@p4r4d0xb0x/opencode-dcp 3.0.5 → 3.1.12

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.
Files changed (217) hide show
  1. package/README.md +31 -26
  2. package/dist/index.d.ts +2 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +7909 -76
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/commands/compression-targets.d.ts +14 -0
  7. package/dist/lib/commands/compression-targets.d.ts.map +1 -0
  8. package/dist/lib/commands/context.d.ts.map +1 -1
  9. package/dist/lib/commands/decompress.d.ts.map +1 -1
  10. package/dist/lib/commands/index.d.ts +8 -0
  11. package/dist/lib/commands/index.d.ts.map +1 -0
  12. package/dist/lib/commands/manual.d.ts +1 -0
  13. package/dist/lib/commands/manual.d.ts.map +1 -1
  14. package/dist/lib/commands/recompress.d.ts.map +1 -1
  15. package/dist/lib/commands/stats.d.ts.map +1 -1
  16. package/dist/lib/commands/sweep.d.ts.map +1 -1
  17. package/dist/lib/compress/index.d.ts +4 -0
  18. package/dist/lib/compress/index.d.ts.map +1 -0
  19. package/dist/lib/compress/message-utils.d.ts +8 -0
  20. package/dist/lib/compress/message-utils.d.ts.map +1 -0
  21. package/dist/lib/compress/message.d.ts +4 -0
  22. package/dist/lib/compress/message.d.ts.map +1 -0
  23. package/dist/lib/compress/pipeline.d.ts +29 -0
  24. package/dist/lib/compress/pipeline.d.ts.map +1 -0
  25. package/dist/lib/compress/protected-content.d.ts +7 -0
  26. package/dist/lib/compress/protected-content.d.ts.map +1 -0
  27. package/dist/lib/compress/range-utils.d.ts +10 -0
  28. package/dist/lib/compress/range-utils.d.ts.map +1 -0
  29. package/dist/lib/compress/range.d.ts +4 -0
  30. package/dist/lib/compress/range.d.ts.map +1 -0
  31. package/dist/lib/compress/search.d.ts +11 -0
  32. package/dist/lib/compress/search.d.ts.map +1 -0
  33. package/dist/lib/compress/state.d.ts +9 -0
  34. package/dist/lib/compress/state.d.ts.map +1 -0
  35. package/dist/lib/compress/timing.d.ts +18 -0
  36. package/dist/lib/compress/timing.d.ts.map +1 -0
  37. package/dist/lib/compress/types.d.ts +94 -0
  38. package/dist/lib/compress/types.d.ts.map +1 -0
  39. package/dist/lib/{shared-utils.d.ts → compress-permission.d.ts} +2 -4
  40. package/dist/lib/compress-permission.d.ts.map +1 -0
  41. package/dist/lib/config.d.ts +7 -7
  42. package/dist/lib/config.d.ts.map +1 -1
  43. package/dist/lib/hooks.d.ts +4 -1
  44. package/dist/lib/hooks.d.ts.map +1 -1
  45. package/dist/lib/message-ids.d.ts +1 -1
  46. package/dist/lib/message-ids.d.ts.map +1 -1
  47. package/dist/lib/messages/index.d.ts +2 -0
  48. package/dist/lib/messages/index.d.ts.map +1 -1
  49. package/dist/lib/messages/inject/inject.d.ts +3 -2
  50. package/dist/lib/messages/inject/inject.d.ts.map +1 -1
  51. package/dist/lib/messages/inject/utils.d.ts +2 -3
  52. package/dist/lib/messages/inject/utils.d.ts.map +1 -1
  53. package/dist/lib/messages/priority.d.ts +13 -0
  54. package/dist/lib/messages/priority.d.ts.map +1 -0
  55. package/dist/lib/messages/prune.d.ts.map +1 -1
  56. package/dist/lib/messages/query.d.ts +7 -0
  57. package/dist/lib/messages/query.d.ts.map +1 -0
  58. package/dist/lib/messages/shape.d.ts +5 -0
  59. package/dist/lib/messages/shape.d.ts.map +1 -0
  60. package/dist/lib/messages/utils.d.ts +10 -4
  61. package/dist/lib/messages/utils.d.ts.map +1 -1
  62. package/dist/lib/prompts/compress-message.d.ts +2 -0
  63. package/dist/lib/prompts/compress-message.d.ts.map +1 -0
  64. package/dist/lib/prompts/compress-range.d.ts +2 -0
  65. package/dist/lib/prompts/compress-range.d.ts.map +1 -0
  66. package/dist/lib/prompts/context-limit-nudge.d.ts +1 -1
  67. package/dist/lib/prompts/context-limit-nudge.d.ts.map +1 -1
  68. package/dist/lib/prompts/extensions/nudge.d.ts +5 -0
  69. package/dist/lib/prompts/extensions/nudge.d.ts.map +1 -0
  70. package/dist/lib/prompts/extensions/system.d.ts +4 -0
  71. package/dist/lib/prompts/extensions/system.d.ts.map +1 -0
  72. package/dist/lib/prompts/extensions/tool.d.ts +3 -0
  73. package/dist/lib/prompts/extensions/tool.d.ts.map +1 -0
  74. package/dist/lib/prompts/index.d.ts +2 -1
  75. package/dist/lib/prompts/index.d.ts.map +1 -1
  76. package/dist/lib/prompts/iteration-nudge.d.ts +1 -1
  77. package/dist/lib/prompts/iteration-nudge.d.ts.map +1 -1
  78. package/dist/lib/prompts/store.d.ts +5 -4
  79. package/dist/lib/prompts/store.d.ts.map +1 -1
  80. package/dist/lib/prompts/system.d.ts +1 -1
  81. package/dist/lib/prompts/system.d.ts.map +1 -1
  82. package/dist/lib/prompts/turn-nudge.d.ts +1 -1
  83. package/dist/lib/prompts/turn-nudge.d.ts.map +1 -1
  84. package/dist/lib/state/index.d.ts +1 -0
  85. package/dist/lib/state/index.d.ts.map +1 -1
  86. package/dist/lib/state/persistence.d.ts +1 -0
  87. package/dist/lib/state/persistence.d.ts.map +1 -1
  88. package/dist/lib/state/state.d.ts.map +1 -1
  89. package/dist/lib/state/types.d.ts +10 -1
  90. package/dist/lib/state/types.d.ts.map +1 -1
  91. package/dist/lib/state/utils.d.ts +9 -5
  92. package/dist/lib/state/utils.d.ts.map +1 -1
  93. package/dist/lib/strategies/index.d.ts +0 -1
  94. package/dist/lib/strategies/index.d.ts.map +1 -1
  95. package/dist/lib/{strategies/utils.d.ts → token-utils.d.ts} +6 -8
  96. package/dist/lib/token-utils.d.ts.map +1 -0
  97. package/dist/lib/ui/notification.d.ts +8 -1
  98. package/dist/lib/ui/notification.d.ts.map +1 -1
  99. package/dist/lib/ui/utils.d.ts +1 -1
  100. package/dist/lib/ui/utils.d.ts.map +1 -1
  101. package/dist/lib/update.d.ts +22 -0
  102. package/dist/lib/update.d.ts.map +1 -0
  103. package/package.json +26 -15
  104. package/dist/lib/auth.js +0 -32
  105. package/dist/lib/auth.js.map +0 -1
  106. package/dist/lib/commands/context.js +0 -241
  107. package/dist/lib/commands/context.js.map +0 -1
  108. package/dist/lib/commands/decompress.js +0 -159
  109. package/dist/lib/commands/decompress.js.map +0 -1
  110. package/dist/lib/commands/help.js +0 -52
  111. package/dist/lib/commands/help.js.map +0 -1
  112. package/dist/lib/commands/manual.js +0 -48
  113. package/dist/lib/commands/manual.js.map +0 -1
  114. package/dist/lib/commands/recompress.js +0 -137
  115. package/dist/lib/commands/recompress.js.map +0 -1
  116. package/dist/lib/commands/stats.js +0 -62
  117. package/dist/lib/commands/stats.js.map +0 -1
  118. package/dist/lib/commands/sweep.js +0 -194
  119. package/dist/lib/commands/sweep.js.map +0 -1
  120. package/dist/lib/config.js +0 -766
  121. package/dist/lib/config.js.map +0 -1
  122. package/dist/lib/hooks.js +0 -195
  123. package/dist/lib/hooks.js.map +0 -1
  124. package/dist/lib/host-permissions.js +0 -58
  125. package/dist/lib/host-permissions.js.map +0 -1
  126. package/dist/lib/logger.js +0 -204
  127. package/dist/lib/logger.js.map +0 -1
  128. package/dist/lib/message-ids.js +0 -112
  129. package/dist/lib/message-ids.js.map +0 -1
  130. package/dist/lib/messages/index.js +0 -7
  131. package/dist/lib/messages/index.js.map +0 -1
  132. package/dist/lib/messages/inject/inject.js +0 -131
  133. package/dist/lib/messages/inject/inject.js.map +0 -1
  134. package/dist/lib/messages/inject/subagent-results.js +0 -58
  135. package/dist/lib/messages/inject/subagent-results.js.map +0 -1
  136. package/dist/lib/messages/inject/utils.js +0 -198
  137. package/dist/lib/messages/inject/utils.js.map +0 -1
  138. package/dist/lib/messages/prune.js +0 -177
  139. package/dist/lib/messages/prune.js.map +0 -1
  140. package/dist/lib/messages/reasoning-strip.js +0 -33
  141. package/dist/lib/messages/reasoning-strip.js.map +0 -1
  142. package/dist/lib/messages/sync.js +0 -93
  143. package/dist/lib/messages/sync.js.map +0 -1
  144. package/dist/lib/messages/utils.js +0 -118
  145. package/dist/lib/messages/utils.js.map +0 -1
  146. package/dist/lib/prompts/compress.d.ts +0 -2
  147. package/dist/lib/prompts/compress.d.ts.map +0 -1
  148. package/dist/lib/prompts/compress.js +0 -85
  149. package/dist/lib/prompts/compress.js.map +0 -1
  150. package/dist/lib/prompts/context-limit-nudge.js +0 -25
  151. package/dist/lib/prompts/context-limit-nudge.js.map +0 -1
  152. package/dist/lib/prompts/index.js +0 -19
  153. package/dist/lib/prompts/index.js.map +0 -1
  154. package/dist/lib/prompts/internal-overlays.d.ts +0 -5
  155. package/dist/lib/prompts/internal-overlays.d.ts.map +0 -1
  156. package/dist/lib/prompts/internal-overlays.js +0 -43
  157. package/dist/lib/prompts/internal-overlays.js.map +0 -1
  158. package/dist/lib/prompts/iteration-nudge.js +0 -9
  159. package/dist/lib/prompts/iteration-nudge.js.map +0 -1
  160. package/dist/lib/prompts/store.js +0 -346
  161. package/dist/lib/prompts/store.js.map +0 -1
  162. package/dist/lib/prompts/system.js +0 -30
  163. package/dist/lib/prompts/system.js.map +0 -1
  164. package/dist/lib/prompts/turn-nudge.js +0 -12
  165. package/dist/lib/prompts/turn-nudge.js.map +0 -1
  166. package/dist/lib/protected-patterns.js +0 -107
  167. package/dist/lib/protected-patterns.js.map +0 -1
  168. package/dist/lib/shared-utils.d.ts.map +0 -1
  169. package/dist/lib/shared-utils.js +0 -30
  170. package/dist/lib/shared-utils.js.map +0 -1
  171. package/dist/lib/state/index.js +0 -4
  172. package/dist/lib/state/index.js.map +0 -1
  173. package/dist/lib/state/persistence.js +0 -174
  174. package/dist/lib/state/persistence.js.map +0 -1
  175. package/dist/lib/state/state.js +0 -134
  176. package/dist/lib/state/state.js.map +0 -1
  177. package/dist/lib/state/tool-cache.js +0 -69
  178. package/dist/lib/state/tool-cache.js.map +0 -1
  179. package/dist/lib/state/types.js +0 -2
  180. package/dist/lib/state/types.js.map +0 -1
  181. package/dist/lib/state/utils.js +0 -196
  182. package/dist/lib/state/utils.js.map +0 -1
  183. package/dist/lib/strategies/deduplication.js +0 -100
  184. package/dist/lib/strategies/deduplication.js.map +0 -1
  185. package/dist/lib/strategies/index.js +0 -4
  186. package/dist/lib/strategies/index.js.map +0 -1
  187. package/dist/lib/strategies/purge-errors.js +0 -62
  188. package/dist/lib/strategies/purge-errors.js.map +0 -1
  189. package/dist/lib/strategies/supersede-writes.d.ts +0 -13
  190. package/dist/lib/strategies/supersede-writes.d.ts.map +0 -1
  191. package/dist/lib/strategies/supersede-writes.js +0 -94
  192. package/dist/lib/strategies/supersede-writes.js.map +0 -1
  193. package/dist/lib/strategies/utils.d.ts.map +0 -1
  194. package/dist/lib/strategies/utils.js +0 -128
  195. package/dist/lib/strategies/utils.js.map +0 -1
  196. package/dist/lib/subagents/subagent-results.js +0 -52
  197. package/dist/lib/subagents/subagent-results.js.map +0 -1
  198. package/dist/lib/tools/compress.d.ts +0 -4
  199. package/dist/lib/tools/compress.d.ts.map +0 -1
  200. package/dist/lib/tools/compress.js +0 -110
  201. package/dist/lib/tools/compress.js.map +0 -1
  202. package/dist/lib/tools/index.d.ts +0 -3
  203. package/dist/lib/tools/index.d.ts.map +0 -1
  204. package/dist/lib/tools/index.js +0 -2
  205. package/dist/lib/tools/index.js.map +0 -1
  206. package/dist/lib/tools/types.d.ts +0 -13
  207. package/dist/lib/tools/types.d.ts.map +0 -1
  208. package/dist/lib/tools/types.js +0 -2
  209. package/dist/lib/tools/types.js.map +0 -1
  210. package/dist/lib/tools/utils.d.ts +0 -80
  211. package/dist/lib/tools/utils.d.ts.map +0 -1
  212. package/dist/lib/tools/utils.js +0 -675
  213. package/dist/lib/tools/utils.js.map +0 -1
  214. package/dist/lib/ui/notification.js +0 -182
  215. package/dist/lib/ui/notification.js.map +0 -1
  216. package/dist/lib/ui/utils.js +0 -255
  217. package/dist/lib/ui/utils.js.map +0 -1
@@ -1,766 +0,0 @@
1
- import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from "fs";
2
- import { join, dirname } from "path";
3
- import { homedir } from "os";
4
- import { parse } from "jsonc-parser";
5
- const DEFAULT_PROTECTED_TOOLS = [
6
- "task",
7
- "skill",
8
- "todowrite",
9
- "todoread",
10
- "compress",
11
- "batch",
12
- "plan_enter",
13
- "plan_exit",
14
- "write",
15
- "edit",
16
- ];
17
- const COMPRESS_DEFAULT_PROTECTED_TOOLS = ["task", "skill", "todowrite", "todoread"];
18
- export const VALID_CONFIG_KEYS = new Set([
19
- "$schema",
20
- "enabled",
21
- "debug",
22
- "showUpdateToasts",
23
- "pruneNotification",
24
- "pruneNotificationType",
25
- "turnProtection",
26
- "turnProtection.enabled",
27
- "turnProtection.turns",
28
- "experimental",
29
- "experimental.allowSubAgents",
30
- "experimental.customPrompts",
31
- "protectedFilePatterns",
32
- "commands",
33
- "commands.enabled",
34
- "commands.protectedTools",
35
- "manualMode",
36
- "manualMode.enabled",
37
- "manualMode.automaticStrategies",
38
- "compress",
39
- "compress.permission",
40
- "compress.showCompression",
41
- "compress.maxContextLimit",
42
- "compress.minContextLimit",
43
- "compress.modelMaxLimits",
44
- "compress.modelMinLimits",
45
- "compress.nudgeFrequency",
46
- "compress.iterationNudgeThreshold",
47
- "compress.nudgeForce",
48
- "compress.flatSchema",
49
- "compress.protectedTools",
50
- "compress.protectUserMessages",
51
- "strategies",
52
- "strategies.deduplication",
53
- "strategies.deduplication.enabled",
54
- "strategies.deduplication.protectedTools",
55
- "strategies.supersedeWrites",
56
- "strategies.supersedeWrites.enabled",
57
- "strategies.purgeErrors",
58
- "strategies.purgeErrors.enabled",
59
- "strategies.purgeErrors.turns",
60
- "strategies.purgeErrors.protectedTools",
61
- ]);
62
- function getConfigKeyPaths(obj, prefix = "") {
63
- const keys = [];
64
- for (const key of Object.keys(obj)) {
65
- const fullKey = prefix ? `${prefix}.${key}` : key;
66
- keys.push(fullKey);
67
- // model*Limits are dynamic maps keyed by providerID/modelID; do not recurse into arbitrary IDs.
68
- if (fullKey === "compress.modelMaxLimits" || fullKey === "compress.modelMinLimits") {
69
- continue;
70
- }
71
- if (obj[key] && typeof obj[key] === "object" && !Array.isArray(obj[key])) {
72
- keys.push(...getConfigKeyPaths(obj[key], fullKey));
73
- }
74
- }
75
- return keys;
76
- }
77
- export function getInvalidConfigKeys(userConfig) {
78
- const userKeys = getConfigKeyPaths(userConfig);
79
- return userKeys.filter((key) => !VALID_CONFIG_KEYS.has(key));
80
- }
81
- export function validateConfigTypes(config) {
82
- const errors = [];
83
- if (config.enabled !== undefined && typeof config.enabled !== "boolean") {
84
- errors.push({ key: "enabled", expected: "boolean", actual: typeof config.enabled });
85
- }
86
- if (config.debug !== undefined && typeof config.debug !== "boolean") {
87
- errors.push({ key: "debug", expected: "boolean", actual: typeof config.debug });
88
- }
89
- if (config.pruneNotification !== undefined) {
90
- const validValues = ["off", "minimal", "detailed"];
91
- if (!validValues.includes(config.pruneNotification)) {
92
- errors.push({
93
- key: "pruneNotification",
94
- expected: '"off" | "minimal" | "detailed"',
95
- actual: JSON.stringify(config.pruneNotification),
96
- });
97
- }
98
- }
99
- if (config.pruneNotificationType !== undefined) {
100
- const validValues = ["chat", "toast"];
101
- if (!validValues.includes(config.pruneNotificationType)) {
102
- errors.push({
103
- key: "pruneNotificationType",
104
- expected: '"chat" | "toast"',
105
- actual: JSON.stringify(config.pruneNotificationType),
106
- });
107
- }
108
- }
109
- if (config.protectedFilePatterns !== undefined) {
110
- if (!Array.isArray(config.protectedFilePatterns)) {
111
- errors.push({
112
- key: "protectedFilePatterns",
113
- expected: "string[]",
114
- actual: typeof config.protectedFilePatterns,
115
- });
116
- }
117
- else if (!config.protectedFilePatterns.every((v) => typeof v === "string")) {
118
- errors.push({
119
- key: "protectedFilePatterns",
120
- expected: "string[]",
121
- actual: "non-string entries",
122
- });
123
- }
124
- }
125
- if (config.turnProtection) {
126
- if (config.turnProtection.enabled !== undefined &&
127
- typeof config.turnProtection.enabled !== "boolean") {
128
- errors.push({
129
- key: "turnProtection.enabled",
130
- expected: "boolean",
131
- actual: typeof config.turnProtection.enabled,
132
- });
133
- }
134
- if (config.turnProtection.turns !== undefined &&
135
- typeof config.turnProtection.turns !== "number") {
136
- errors.push({
137
- key: "turnProtection.turns",
138
- expected: "number",
139
- actual: typeof config.turnProtection.turns,
140
- });
141
- }
142
- if (typeof config.turnProtection.turns === "number" && config.turnProtection.turns < 1) {
143
- errors.push({
144
- key: "turnProtection.turns",
145
- expected: "positive number (>= 1)",
146
- actual: `${config.turnProtection.turns}`,
147
- });
148
- }
149
- }
150
- const experimental = config.experimental;
151
- if (experimental !== undefined) {
152
- if (typeof experimental !== "object" ||
153
- experimental === null ||
154
- Array.isArray(experimental)) {
155
- errors.push({
156
- key: "experimental",
157
- expected: "object",
158
- actual: typeof experimental,
159
- });
160
- }
161
- else {
162
- if (experimental.allowSubAgents !== undefined &&
163
- typeof experimental.allowSubAgents !== "boolean") {
164
- errors.push({
165
- key: "experimental.allowSubAgents",
166
- expected: "boolean",
167
- actual: typeof experimental.allowSubAgents,
168
- });
169
- }
170
- if (experimental.customPrompts !== undefined &&
171
- typeof experimental.customPrompts !== "boolean") {
172
- errors.push({
173
- key: "experimental.customPrompts",
174
- expected: "boolean",
175
- actual: typeof experimental.customPrompts,
176
- });
177
- }
178
- }
179
- }
180
- const commands = config.commands;
181
- if (commands !== undefined) {
182
- if (typeof commands !== "object" || commands === null || Array.isArray(commands)) {
183
- errors.push({
184
- key: "commands",
185
- expected: "object",
186
- actual: typeof commands,
187
- });
188
- }
189
- else {
190
- if (commands.enabled !== undefined && typeof commands.enabled !== "boolean") {
191
- errors.push({
192
- key: "commands.enabled",
193
- expected: "boolean",
194
- actual: typeof commands.enabled,
195
- });
196
- }
197
- if (commands.protectedTools !== undefined && !Array.isArray(commands.protectedTools)) {
198
- errors.push({
199
- key: "commands.protectedTools",
200
- expected: "string[]",
201
- actual: typeof commands.protectedTools,
202
- });
203
- }
204
- }
205
- }
206
- const manualMode = config.manualMode;
207
- if (manualMode !== undefined) {
208
- if (typeof manualMode !== "object" || manualMode === null || Array.isArray(manualMode)) {
209
- errors.push({
210
- key: "manualMode",
211
- expected: "object",
212
- actual: typeof manualMode,
213
- });
214
- }
215
- else {
216
- if (manualMode.enabled !== undefined && typeof manualMode.enabled !== "boolean") {
217
- errors.push({
218
- key: "manualMode.enabled",
219
- expected: "boolean",
220
- actual: typeof manualMode.enabled,
221
- });
222
- }
223
- if (manualMode.automaticStrategies !== undefined &&
224
- typeof manualMode.automaticStrategies !== "boolean") {
225
- errors.push({
226
- key: "manualMode.automaticStrategies",
227
- expected: "boolean",
228
- actual: typeof manualMode.automaticStrategies,
229
- });
230
- }
231
- }
232
- }
233
- const compress = config.compress;
234
- if (compress !== undefined) {
235
- if (typeof compress !== "object" || compress === null || Array.isArray(compress)) {
236
- errors.push({
237
- key: "compress",
238
- expected: "object",
239
- actual: typeof compress,
240
- });
241
- }
242
- else {
243
- if (compress.nudgeFrequency !== undefined &&
244
- typeof compress.nudgeFrequency !== "number") {
245
- errors.push({
246
- key: "compress.nudgeFrequency",
247
- expected: "number",
248
- actual: typeof compress.nudgeFrequency,
249
- });
250
- }
251
- if (typeof compress.nudgeFrequency === "number" && compress.nudgeFrequency < 1) {
252
- errors.push({
253
- key: "compress.nudgeFrequency",
254
- expected: "positive number (>= 1)",
255
- actual: `${compress.nudgeFrequency} (will be clamped to 1)`,
256
- });
257
- }
258
- if (compress.iterationNudgeThreshold !== undefined &&
259
- typeof compress.iterationNudgeThreshold !== "number") {
260
- errors.push({
261
- key: "compress.iterationNudgeThreshold",
262
- expected: "number",
263
- actual: typeof compress.iterationNudgeThreshold,
264
- });
265
- }
266
- if (compress.nudgeForce !== undefined &&
267
- compress.nudgeForce !== "strong" &&
268
- compress.nudgeForce !== "soft") {
269
- errors.push({
270
- key: "compress.nudgeForce",
271
- expected: '"strong" | "soft"',
272
- actual: JSON.stringify(compress.nudgeForce),
273
- });
274
- }
275
- if (compress.flatSchema !== undefined && typeof compress.flatSchema !== "boolean") {
276
- errors.push({
277
- key: "compress.flatSchema",
278
- expected: "boolean",
279
- actual: typeof compress.flatSchema,
280
- });
281
- }
282
- if (compress.protectedTools !== undefined && !Array.isArray(compress.protectedTools)) {
283
- errors.push({
284
- key: "compress.protectedTools",
285
- expected: "string[]",
286
- actual: typeof compress.protectedTools,
287
- });
288
- }
289
- if (compress.protectUserMessages !== undefined &&
290
- typeof compress.protectUserMessages !== "boolean") {
291
- errors.push({
292
- key: "compress.protectUserMessages",
293
- expected: "boolean",
294
- actual: typeof compress.protectUserMessages,
295
- });
296
- }
297
- if (typeof compress.iterationNudgeThreshold === "number" &&
298
- compress.iterationNudgeThreshold < 1) {
299
- errors.push({
300
- key: "compress.iterationNudgeThreshold",
301
- expected: "positive number (>= 1)",
302
- actual: `${compress.iterationNudgeThreshold} (will be clamped to 1)`,
303
- });
304
- }
305
- const validateLimitValue = (key, value, actualValue = value) => {
306
- const isValidNumber = typeof value === "number";
307
- const isPercentString = typeof value === "string" && value.endsWith("%");
308
- if (!isValidNumber && !isPercentString) {
309
- errors.push({
310
- key,
311
- expected: 'number | "${number}%"',
312
- actual: JSON.stringify(actualValue),
313
- });
314
- }
315
- };
316
- const validateModelLimits = (key, limits) => {
317
- if (limits === undefined) {
318
- return;
319
- }
320
- if (typeof limits !== "object" || limits === null || Array.isArray(limits)) {
321
- errors.push({
322
- key,
323
- expected: "Record<string, number | ${number}%>",
324
- actual: typeof limits,
325
- });
326
- return;
327
- }
328
- for (const [providerModelKey, limit] of Object.entries(limits)) {
329
- const isValidNumber = typeof limit === "number";
330
- const isPercentString = typeof limit === "string" && /^\d+(?:\.\d+)?%$/.test(limit);
331
- if (!isValidNumber && !isPercentString) {
332
- errors.push({
333
- key: `${key}.${providerModelKey}`,
334
- expected: 'number | "${number}%"',
335
- actual: JSON.stringify(limit),
336
- });
337
- }
338
- }
339
- };
340
- if (compress.maxContextLimit !== undefined) {
341
- validateLimitValue("compress.maxContextLimit", compress.maxContextLimit);
342
- }
343
- if (compress.minContextLimit !== undefined) {
344
- validateLimitValue("compress.minContextLimit", compress.minContextLimit);
345
- }
346
- validateModelLimits("compress.modelMaxLimits", compress.modelMaxLimits);
347
- validateModelLimits("compress.modelMinLimits", compress.modelMinLimits);
348
- const validValues = ["ask", "allow", "deny"];
349
- if (compress.permission !== undefined && !validValues.includes(compress.permission)) {
350
- errors.push({
351
- key: "compress.permission",
352
- expected: '"ask" | "allow" | "deny"',
353
- actual: JSON.stringify(compress.permission),
354
- });
355
- }
356
- if (compress.showCompression !== undefined &&
357
- typeof compress.showCompression !== "boolean") {
358
- errors.push({
359
- key: "compress.showCompression",
360
- expected: "boolean",
361
- actual: typeof compress.showCompression,
362
- });
363
- }
364
- }
365
- }
366
- const strategies = config.strategies;
367
- if (strategies) {
368
- if (strategies.deduplication?.enabled !== undefined &&
369
- typeof strategies.deduplication.enabled !== "boolean") {
370
- errors.push({
371
- key: "strategies.deduplication.enabled",
372
- expected: "boolean",
373
- actual: typeof strategies.deduplication.enabled,
374
- });
375
- }
376
- if (strategies.deduplication?.protectedTools !== undefined &&
377
- !Array.isArray(strategies.deduplication.protectedTools)) {
378
- errors.push({
379
- key: "strategies.deduplication.protectedTools",
380
- expected: "string[]",
381
- actual: typeof strategies.deduplication.protectedTools,
382
- });
383
- }
384
- if (strategies.supersedeWrites) {
385
- if (strategies.supersedeWrites.enabled !== undefined &&
386
- typeof strategies.supersedeWrites.enabled !== "boolean") {
387
- errors.push({
388
- key: "strategies.supersedeWrites.enabled",
389
- expected: "boolean",
390
- actual: typeof strategies.supersedeWrites.enabled,
391
- });
392
- }
393
- }
394
- if (strategies.purgeErrors) {
395
- if (strategies.purgeErrors.enabled !== undefined &&
396
- typeof strategies.purgeErrors.enabled !== "boolean") {
397
- errors.push({
398
- key: "strategies.purgeErrors.enabled",
399
- expected: "boolean",
400
- actual: typeof strategies.purgeErrors.enabled,
401
- });
402
- }
403
- if (strategies.purgeErrors.turns !== undefined &&
404
- typeof strategies.purgeErrors.turns !== "number") {
405
- errors.push({
406
- key: "strategies.purgeErrors.turns",
407
- expected: "number",
408
- actual: typeof strategies.purgeErrors.turns,
409
- });
410
- }
411
- // Warn if turns is 0 or negative - will be clamped to 1
412
- if (typeof strategies.purgeErrors.turns === "number" &&
413
- strategies.purgeErrors.turns < 1) {
414
- errors.push({
415
- key: "strategies.purgeErrors.turns",
416
- expected: "positive number (>= 1)",
417
- actual: `${strategies.purgeErrors.turns} (will be clamped to 1)`,
418
- });
419
- }
420
- if (strategies.purgeErrors.protectedTools !== undefined &&
421
- !Array.isArray(strategies.purgeErrors.protectedTools)) {
422
- errors.push({
423
- key: "strategies.purgeErrors.protectedTools",
424
- expected: "string[]",
425
- actual: typeof strategies.purgeErrors.protectedTools,
426
- });
427
- }
428
- }
429
- }
430
- return errors;
431
- }
432
- function showConfigWarnings(ctx, configPath, configData, isProject) {
433
- const invalidKeys = getInvalidConfigKeys(configData);
434
- const typeErrors = validateConfigTypes(configData);
435
- if (invalidKeys.length === 0 && typeErrors.length === 0) {
436
- return;
437
- }
438
- const configType = isProject ? "project config" : "config";
439
- const messages = [];
440
- if (invalidKeys.length > 0) {
441
- const keyList = invalidKeys.slice(0, 3).join(", ");
442
- const suffix = invalidKeys.length > 3 ? ` (+${invalidKeys.length - 3} more)` : "";
443
- messages.push(`Unknown keys: ${keyList}${suffix}`);
444
- }
445
- if (typeErrors.length > 0) {
446
- for (const err of typeErrors.slice(0, 2)) {
447
- messages.push(`${err.key}: expected ${err.expected}, got ${err.actual}`);
448
- }
449
- if (typeErrors.length > 2) {
450
- messages.push(`(+${typeErrors.length - 2} more type errors)`);
451
- }
452
- }
453
- setTimeout(() => {
454
- try {
455
- ctx.client.tui.showToast({
456
- body: {
457
- title: `DCP: ${configType} warning`,
458
- message: `${configPath}\n${messages.join("\n")}`,
459
- variant: "warning",
460
- duration: 7000,
461
- },
462
- });
463
- }
464
- catch { }
465
- }, 7000);
466
- }
467
- const defaultConfig = {
468
- enabled: true,
469
- debug: false,
470
- pruneNotification: "detailed",
471
- pruneNotificationType: "chat",
472
- commands: {
473
- enabled: true,
474
- protectedTools: [...DEFAULT_PROTECTED_TOOLS],
475
- },
476
- manualMode: {
477
- enabled: false,
478
- automaticStrategies: true,
479
- },
480
- turnProtection: {
481
- enabled: false,
482
- turns: 4,
483
- },
484
- experimental: {
485
- allowSubAgents: false,
486
- customPrompts: false,
487
- },
488
- protectedFilePatterns: [],
489
- compress: {
490
- permission: "allow",
491
- showCompression: false,
492
- maxContextLimit: 150000,
493
- minContextLimit: 50000,
494
- nudgeFrequency: 5,
495
- iterationNudgeThreshold: 15,
496
- nudgeForce: "soft",
497
- flatSchema: false,
498
- protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],
499
- protectUserMessages: false,
500
- },
501
- strategies: {
502
- deduplication: {
503
- enabled: true,
504
- protectedTools: [],
505
- },
506
- supersedeWrites: {
507
- enabled: true,
508
- },
509
- purgeErrors: {
510
- enabled: true,
511
- turns: 4,
512
- protectedTools: [],
513
- },
514
- },
515
- };
516
- const GLOBAL_CONFIG_DIR = process.env.XDG_CONFIG_HOME
517
- ? join(process.env.XDG_CONFIG_HOME, "opencode")
518
- : join(homedir(), ".config", "opencode");
519
- const GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, "dcp.jsonc");
520
- const GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, "dcp.json");
521
- function findOpencodeDir(startDir) {
522
- let current = startDir;
523
- while (current !== "/") {
524
- const candidate = join(current, ".opencode");
525
- if (existsSync(candidate) && statSync(candidate).isDirectory()) {
526
- return candidate;
527
- }
528
- const parent = dirname(current);
529
- if (parent === current) {
530
- break;
531
- }
532
- current = parent;
533
- }
534
- return null;
535
- }
536
- function getConfigPaths(ctx) {
537
- const global = existsSync(GLOBAL_CONFIG_PATH_JSONC)
538
- ? GLOBAL_CONFIG_PATH_JSONC
539
- : existsSync(GLOBAL_CONFIG_PATH_JSON)
540
- ? GLOBAL_CONFIG_PATH_JSON
541
- : null;
542
- let configDir = null;
543
- const opencodeConfigDir = process.env.OPENCODE_CONFIG_DIR;
544
- if (opencodeConfigDir) {
545
- const configJsonc = join(opencodeConfigDir, "dcp.jsonc");
546
- const configJson = join(opencodeConfigDir, "dcp.json");
547
- configDir = existsSync(configJsonc)
548
- ? configJsonc
549
- : existsSync(configJson)
550
- ? configJson
551
- : null;
552
- }
553
- let project = null;
554
- if (ctx?.directory) {
555
- const opencodeDir = findOpencodeDir(ctx.directory);
556
- if (opencodeDir) {
557
- const projectJsonc = join(opencodeDir, "dcp.jsonc");
558
- const projectJson = join(opencodeDir, "dcp.json");
559
- project = existsSync(projectJsonc)
560
- ? projectJsonc
561
- : existsSync(projectJson)
562
- ? projectJson
563
- : null;
564
- }
565
- }
566
- return { global, configDir, project };
567
- }
568
- function createDefaultConfig() {
569
- if (!existsSync(GLOBAL_CONFIG_DIR)) {
570
- mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
571
- }
572
- const configContent = `{
573
- "$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json"
574
- }
575
- `;
576
- writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, "utf-8");
577
- }
578
- function loadConfigFile(configPath) {
579
- let fileContent = "";
580
- try {
581
- fileContent = readFileSync(configPath, "utf-8");
582
- }
583
- catch {
584
- return { data: null };
585
- }
586
- try {
587
- const parsed = parse(fileContent, undefined, { allowTrailingComma: true });
588
- if (parsed === undefined || parsed === null) {
589
- return { data: null, parseError: "Config file is empty or invalid" };
590
- }
591
- return { data: parsed };
592
- }
593
- catch (error) {
594
- return { data: null, parseError: error.message || "Failed to parse config" };
595
- }
596
- }
597
- function mergeStrategies(base, override) {
598
- if (!override) {
599
- return base;
600
- }
601
- return {
602
- deduplication: {
603
- enabled: override.deduplication?.enabled ?? base.deduplication.enabled,
604
- protectedTools: [
605
- ...new Set([
606
- ...base.deduplication.protectedTools,
607
- ...(override.deduplication?.protectedTools ?? []),
608
- ]),
609
- ],
610
- },
611
- supersedeWrites: {
612
- enabled: override.supersedeWrites?.enabled ?? base.supersedeWrites.enabled,
613
- },
614
- purgeErrors: {
615
- enabled: override.purgeErrors?.enabled ?? base.purgeErrors.enabled,
616
- turns: override.purgeErrors?.turns ?? base.purgeErrors.turns,
617
- protectedTools: [
618
- ...new Set([
619
- ...base.purgeErrors.protectedTools,
620
- ...(override.purgeErrors?.protectedTools ?? []),
621
- ]),
622
- ],
623
- },
624
- };
625
- }
626
- function mergeCompress(base, override) {
627
- if (!override) {
628
- return base;
629
- }
630
- return {
631
- permission: override.permission ?? base.permission,
632
- showCompression: override.showCompression ?? base.showCompression,
633
- maxContextLimit: override.maxContextLimit ?? base.maxContextLimit,
634
- minContextLimit: override.minContextLimit ?? base.minContextLimit,
635
- modelMaxLimits: override.modelMaxLimits ?? base.modelMaxLimits,
636
- modelMinLimits: override.modelMinLimits ?? base.modelMinLimits,
637
- nudgeFrequency: override.nudgeFrequency ?? base.nudgeFrequency,
638
- iterationNudgeThreshold: override.iterationNudgeThreshold ?? base.iterationNudgeThreshold,
639
- nudgeForce: override.nudgeForce ?? base.nudgeForce,
640
- flatSchema: override.flatSchema ?? base.flatSchema,
641
- protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],
642
- protectUserMessages: override.protectUserMessages ?? base.protectUserMessages,
643
- };
644
- }
645
- function mergeCommands(base, override) {
646
- if (!override) {
647
- return base;
648
- }
649
- return {
650
- enabled: override.enabled ?? base.enabled,
651
- protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],
652
- };
653
- }
654
- function mergeManualMode(base, override) {
655
- if (override === undefined)
656
- return base;
657
- return {
658
- enabled: override.enabled ?? base.enabled,
659
- automaticStrategies: override.automaticStrategies ?? base.automaticStrategies,
660
- };
661
- }
662
- function mergeExperimental(base, override) {
663
- if (override === undefined)
664
- return base;
665
- return {
666
- allowSubAgents: override.allowSubAgents ?? base.allowSubAgents,
667
- customPrompts: override.customPrompts ?? base.customPrompts,
668
- };
669
- }
670
- function deepCloneConfig(config) {
671
- return {
672
- ...config,
673
- commands: {
674
- enabled: config.commands.enabled,
675
- protectedTools: [...config.commands.protectedTools],
676
- },
677
- manualMode: {
678
- enabled: config.manualMode.enabled,
679
- automaticStrategies: config.manualMode.automaticStrategies,
680
- },
681
- turnProtection: { ...config.turnProtection },
682
- experimental: { ...config.experimental },
683
- protectedFilePatterns: [...config.protectedFilePatterns],
684
- compress: {
685
- ...config.compress,
686
- modelMaxLimits: { ...config.compress.modelMaxLimits },
687
- modelMinLimits: { ...config.compress.modelMinLimits },
688
- protectedTools: [...config.compress.protectedTools],
689
- },
690
- strategies: {
691
- deduplication: {
692
- ...config.strategies.deduplication,
693
- protectedTools: [...config.strategies.deduplication.protectedTools],
694
- },
695
- supersedeWrites: { ...config.strategies.supersedeWrites },
696
- purgeErrors: {
697
- ...config.strategies.purgeErrors,
698
- protectedTools: [...config.strategies.purgeErrors.protectedTools],
699
- },
700
- },
701
- };
702
- }
703
- function mergeLayer(config, data) {
704
- return {
705
- enabled: data.enabled ?? config.enabled,
706
- debug: data.debug ?? config.debug,
707
- pruneNotification: data.pruneNotification ?? config.pruneNotification,
708
- pruneNotificationType: data.pruneNotificationType ?? config.pruneNotificationType,
709
- commands: mergeCommands(config.commands, data.commands),
710
- manualMode: mergeManualMode(config.manualMode, data.manualMode),
711
- turnProtection: {
712
- enabled: data.turnProtection?.enabled ?? config.turnProtection.enabled,
713
- turns: data.turnProtection?.turns ?? config.turnProtection.turns,
714
- },
715
- experimental: mergeExperimental(config.experimental, data.experimental),
716
- protectedFilePatterns: [
717
- ...new Set([...config.protectedFilePatterns, ...(data.protectedFilePatterns ?? [])]),
718
- ],
719
- compress: mergeCompress(config.compress, data.compress),
720
- strategies: mergeStrategies(config.strategies, data.strategies),
721
- };
722
- }
723
- function scheduleParseWarning(ctx, title, message) {
724
- setTimeout(() => {
725
- try {
726
- ctx.client.tui.showToast({
727
- body: {
728
- title,
729
- message,
730
- variant: "warning",
731
- duration: 7000,
732
- },
733
- });
734
- }
735
- catch { }
736
- }, 7000);
737
- }
738
- export function getConfig(ctx) {
739
- let config = deepCloneConfig(defaultConfig);
740
- const configPaths = getConfigPaths(ctx);
741
- if (!configPaths.global) {
742
- createDefaultConfig();
743
- }
744
- const layers = [
745
- { path: configPaths.global, name: "config", isProject: false },
746
- { path: configPaths.configDir, name: "configDir config", isProject: true },
747
- { path: configPaths.project, name: "project config", isProject: true },
748
- ];
749
- for (const layer of layers) {
750
- if (!layer.path) {
751
- continue;
752
- }
753
- const result = loadConfigFile(layer.path);
754
- if (result.parseError) {
755
- scheduleParseWarning(ctx, `DCP: Invalid ${layer.name}`, `${layer.path}\n${result.parseError}\nUsing previous/default values`);
756
- continue;
757
- }
758
- if (!result.data) {
759
- continue;
760
- }
761
- showConfigWarnings(ctx, layer.path, result.data, layer.isProject);
762
- config = mergeLayer(config, result.data);
763
- }
764
- return config;
765
- }
766
- //# sourceMappingURL=config.js.map