opencode-swarm 7.126.0 → 7.126.1
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/.opencode/skills/swarm-pr-feedback/SKILL.md +19 -14
- package/.opencode/skills/swarm-pr-review/SKILL.md +17 -13
- package/dist/cli/{config-doctor-akxywx0c.js → config-doctor-23jxdqwv.js} +2 -2
- package/dist/cli/{core-v1kp7anb.js → core-wg3re04e.js} +1 -1
- package/dist/cli/{curation-policy-dptr1rfe.js → curation-policy-0t6hny6g.js} +2 -2
- package/dist/cli/{curator-23hynz78.js → curator-g8rggzbk.js} +14 -14
- package/dist/cli/{curator-llm-factory-r648jn8e.js → curator-llm-factory-36psae60.js} +14 -14
- package/dist/cli/{guardrail-explain-6atsd4vr.js → guardrail-explain-6ffgrjx9.js} +15 -15
- package/dist/cli/{guardrail-log-222xyxfp.js → guardrail-log-57sczn5h.js} +3 -3
- package/dist/cli/{hive-promoter-bnkhzd46.js → hive-promoter-c458rgp5.js} +14 -14
- package/dist/cli/{index-qzkcy22e.js → index-1p9z8cc4.js} +1 -1
- package/dist/cli/{index-cdx337js.js → index-3hkbegq2.js} +1 -1
- package/dist/cli/{index-gnvg72y1.js → index-4ff0x4cg.js} +79 -1
- package/dist/cli/{index-kwnsatzq.js → index-6j9p0c40.js} +2 -2
- package/dist/cli/{index-a1c9az5e.js → index-abw10n3f.js} +109 -151
- package/dist/cli/{index-r1gdkn2d.js → index-c8sqc3nh.js} +113 -21
- package/dist/cli/{index-2bnfwmk3.js → index-cnhp6c0k.js} +1 -1
- package/dist/cli/{index-dezgmvtw.js → index-echdpdhy.js} +1 -1
- package/dist/cli/{index-yfzn5r9s.js → index-k5xh81c9.js} +3 -3
- package/dist/cli/{index-mgrsx5hn.js → index-kx3533dm.js} +1 -1
- package/dist/cli/{index-bcgfhxzv.js → index-nkhp7j16.js} +5 -5
- package/dist/cli/{index-2yd75hms.js → index-nmyg9b7v.js} +4 -4
- package/dist/cli/{index-16z6txq3.js → index-vvwf9ark.js} +2 -2
- package/dist/cli/{index-jt7hnr7q.js → index-w0yztxgq.js} +1 -1
- package/dist/cli/{index-g4ef4v3m.js → index-w9cb5zwh.js} +1 -1
- package/dist/cli/{index-y4ry07h8.js → index-x1w4cx3n.js} +2 -2
- package/dist/cli/{index-0ff5cm9j.js → index-y9t766sw.js} +2217 -2195
- package/dist/cli/{index-68fpa7ff.js → index-yf4kvhrn.js} +16 -16
- package/dist/cli/index.js +14 -14
- package/dist/cli/{knowledge-escalator-4hc8w7sd.js → knowledge-escalator-kd80m9vp.js} +3 -3
- package/dist/cli/{knowledge-events-kyqjv1f8.js → knowledge-events-j7jfwm1d.js} +1 -1
- package/dist/cli/{knowledge-store-06k0p1gs.js → knowledge-store-1d4byc7y.js} +1 -1
- package/dist/cli/{knowledge-validator-42xjmcmh.js → knowledge-validator-63mkgt9x.js} +4 -4
- package/dist/cli/{scan-cursor-gjcvpyta.js → scan-cursor-qzn5jmbe.js} +2 -2
- package/dist/cli/{schema-69z8w1ka.js → schema-2j92wnns.js} +1 -1
- package/dist/cli/{scope-persistence-habn4q8a.js → scope-persistence-dm5bab50.js} +3 -1
- package/dist/cli/{skill-generator-t6j93mwt.js → skill-generator-sv6zvdvz.js} +5 -5
- package/dist/config/index.d.ts +1 -0
- package/dist/config/loader.d.ts +51 -36
- package/dist/hooks/pr-workflow-gate.d.ts +39 -0
- package/dist/hooks/scope-guard.d.ts +6 -1
- package/dist/index.js +29 -26
- package/dist/scope/scope-binding.d.ts +21 -2
- package/dist/scope/scope-persistence.d.ts +6 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/manifest.d.ts +2 -0
- package/dist/tools/prepare-pr-feedback-scope.d.ts +5 -0
- package/dist/tools/tool-metadata.d.ts +98 -0
- package/dist/tools/write-pr-review-artifact.d.ts +5 -0
- package/package.json +3 -3
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
init_constants,
|
|
9
9
|
init_schema,
|
|
10
10
|
resolveExternalSkillsConfig
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-c8sqc3nh.js";
|
|
12
12
|
import {
|
|
13
13
|
advisoryWarn,
|
|
14
14
|
init_warning_buffer
|
|
@@ -100,30 +100,35 @@ function migratePresetsConfig(raw) {
|
|
|
100
100
|
}
|
|
101
101
|
function sanitizeExternalSkillsConfig(raw) {
|
|
102
102
|
if (!("external_skills" in raw) || raw.external_skills === undefined) {
|
|
103
|
-
return raw;
|
|
103
|
+
return { result: raw, strippedKeys: [] };
|
|
104
104
|
}
|
|
105
105
|
const esResult = ExternalSkillsConfigSchema.safeParse(raw.external_skills);
|
|
106
106
|
if (esResult.success) {
|
|
107
107
|
return {
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
result: {
|
|
109
|
+
...raw,
|
|
110
|
+
external_skills: resolveExternalSkillsConfig(esResult.data)
|
|
111
|
+
},
|
|
112
|
+
strippedKeys: []
|
|
110
113
|
};
|
|
111
114
|
}
|
|
112
115
|
advisoryWarn("[opencode-swarm] external_skills config validation failed:", formatZodIssues(esResult.error));
|
|
113
116
|
advisoryWarn("[opencode-swarm] External skills curation disabled due to invalid config. Fix the external_skills section to enable it.");
|
|
114
117
|
const cleaned = { ...raw };
|
|
115
118
|
delete cleaned.external_skills;
|
|
116
|
-
return cleaned;
|
|
119
|
+
return { result: cleaned, strippedKeys: ["external_skills"] };
|
|
117
120
|
}
|
|
118
121
|
function sanitizeGatesConfig(raw) {
|
|
122
|
+
const strippedKeys = [];
|
|
119
123
|
if (!("gates" in raw) || raw.gates === undefined) {
|
|
120
|
-
return raw;
|
|
124
|
+
return { result: raw, strippedKeys };
|
|
121
125
|
}
|
|
122
126
|
if (typeof raw.gates !== "object" || raw.gates === null || Array.isArray(raw.gates)) {
|
|
123
127
|
advisoryWarn("[opencode-swarm] gates config validation failed: expected an object. Quality gates will use defaults; other config sections remain active.");
|
|
124
128
|
const cleaned2 = { ...raw };
|
|
125
129
|
delete cleaned2.gates;
|
|
126
|
-
|
|
130
|
+
strippedKeys.push("gates");
|
|
131
|
+
return { result: cleaned2, strippedKeys };
|
|
127
132
|
}
|
|
128
133
|
const gateSchemas = GateConfigSchema.shape;
|
|
129
134
|
const cleanedGates = { ...raw.gates };
|
|
@@ -132,6 +137,7 @@ function sanitizeGatesConfig(raw) {
|
|
|
132
137
|
if (!schema) {
|
|
133
138
|
advisoryWarn(`[opencode-swarm] Unknown gates config section "gates.${key}" ignored. Other config sections remain active.`);
|
|
134
139
|
delete cleanedGates[key];
|
|
140
|
+
strippedKeys.push(`gates.${key}`);
|
|
135
141
|
continue;
|
|
136
142
|
}
|
|
137
143
|
const knownFields = GATE_CONFIG_KNOWN_SECTION_KEYS[key];
|
|
@@ -143,6 +149,7 @@ function sanitizeGatesConfig(raw) {
|
|
|
143
149
|
if (!knownFieldSet.has(fieldName)) {
|
|
144
150
|
advisoryWarn(`[opencode-swarm] Unknown gates config key "gates.${key}.${fieldName}" ignored. Other config sections remain active.`);
|
|
145
151
|
delete cleanedSection[fieldName];
|
|
152
|
+
strippedKeys.push(`gates.${key}.${fieldName}`);
|
|
146
153
|
}
|
|
147
154
|
}
|
|
148
155
|
sectionValue = cleanedSection;
|
|
@@ -152,22 +159,30 @@ function sanitizeGatesConfig(raw) {
|
|
|
152
159
|
if (!sectionResult.success) {
|
|
153
160
|
advisoryWarn(`[opencode-swarm] gates.${key} config validation failed; that gate section will use defaults and other config sections remain active:`, formatZodIssues(sectionResult.error));
|
|
154
161
|
delete cleanedGates[key];
|
|
162
|
+
if (!strippedKeys.includes(`gates.${key}`)) {
|
|
163
|
+
strippedKeys.push(`gates.${key}`);
|
|
164
|
+
}
|
|
155
165
|
}
|
|
156
166
|
}
|
|
157
167
|
const gatesResult = GateConfigSchema.safeParse(cleanedGates);
|
|
158
168
|
if (gatesResult.success) {
|
|
159
169
|
return {
|
|
160
|
-
...raw,
|
|
161
|
-
|
|
170
|
+
result: { ...raw, gates: gatesResult.data },
|
|
171
|
+
strippedKeys
|
|
162
172
|
};
|
|
163
173
|
}
|
|
164
174
|
advisoryWarn("[opencode-swarm] gates config validation failed after section cleanup; quality gates will use defaults and other config sections remain active:", formatZodIssues(gatesResult.error));
|
|
165
175
|
const cleaned = { ...raw };
|
|
166
176
|
delete cleaned.gates;
|
|
167
|
-
|
|
177
|
+
if (!strippedKeys.includes("gates")) {
|
|
178
|
+
strippedKeys.push("gates");
|
|
179
|
+
}
|
|
180
|
+
return { result: cleaned, strippedKeys };
|
|
168
181
|
}
|
|
169
182
|
function sanitizeSectionConfigs(raw) {
|
|
170
|
-
|
|
183
|
+
const { result: afterExternal, strippedKeys: externalStripped } = sanitizeExternalSkillsConfig(raw);
|
|
184
|
+
const { result, strippedKeys: gatesStripped } = sanitizeGatesConfig(afterExternal);
|
|
185
|
+
return { result, strippedKeys: [...externalStripped, ...gatesStripped] };
|
|
171
186
|
}
|
|
172
187
|
function formatZodIssues(error) {
|
|
173
188
|
if (error.issues.length === 0)
|
|
@@ -205,168 +220,142 @@ function stripUnrecognizedKeys(raw, error) {
|
|
|
205
220
|
}
|
|
206
221
|
return { cleaned, removed };
|
|
207
222
|
}
|
|
208
|
-
function
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
223
|
+
function warningForRemovedKeys(removedKeys) {
|
|
224
|
+
return `Ignored ${removedKeys.length} invalid or unrecognized config key(s): ${removedKeys.join(", ")}. The rest of your configuration was preserved. Fix or remove these keys.`;
|
|
225
|
+
}
|
|
226
|
+
function rawFullAutoLocked(raw) {
|
|
227
|
+
if (!raw || typeof raw !== "object")
|
|
228
|
+
return false;
|
|
229
|
+
const fullAuto = raw.full_auto;
|
|
230
|
+
if (!fullAuto || typeof fullAuto !== "object" || Array.isArray(fullAuto)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
return fullAuto.locked === true;
|
|
234
|
+
}
|
|
235
|
+
function buildConfigWithMeta(rawUserConfig, rawProjectConfig, loadedFromFile, configHadErrors) {
|
|
236
|
+
let mergedRaw = rawUserConfig ?? {};
|
|
237
|
+
if (rawProjectConfig) {
|
|
238
|
+
mergedRaw = deepMerge(mergedRaw, rawProjectConfig);
|
|
239
|
+
}
|
|
240
|
+
if (rawFullAutoLocked(rawUserConfig) || rawFullAutoLocked(rawProjectConfig)) {
|
|
241
|
+
const fa = mergedRaw.full_auto && typeof mergedRaw.full_auto === "object" && !Array.isArray(mergedRaw.full_auto) ? mergedRaw.full_auto : {};
|
|
242
|
+
mergedRaw = { ...mergedRaw, full_auto: { ...fa, locked: true } };
|
|
243
|
+
}
|
|
244
|
+
mergedRaw = migratePresetsConfig(mergedRaw);
|
|
245
|
+
const { result: sanitized, strippedKeys: gatesStripped } = sanitizeSectionConfigs(mergedRaw);
|
|
246
|
+
mergedRaw = sanitized;
|
|
247
|
+
const sanitizedWarning = gatesStripped.length > 0 ? warningForRemovedKeys(gatesStripped) : undefined;
|
|
248
|
+
const secure = (cfg) => loadedFromFile && configHadErrors ? PluginConfigSchema.parse({
|
|
249
|
+
...cfg,
|
|
212
250
|
guardrails: { enabled: true }
|
|
213
|
-
}) :
|
|
214
|
-
const
|
|
251
|
+
}) : cfg;
|
|
252
|
+
const firstResult = PluginConfigSchema.safeParse(mergedRaw);
|
|
253
|
+
if (firstResult.success) {
|
|
254
|
+
const config = secure(firstResult.data);
|
|
255
|
+
if (loadedFromFile && configHadErrors) {
|
|
256
|
+
const securityWarning = "\u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.";
|
|
257
|
+
advisoryWarn(`[opencode-swarm] ${securityWarning}`);
|
|
258
|
+
return {
|
|
259
|
+
config,
|
|
260
|
+
recovery: "guardrails_defaults",
|
|
261
|
+
removedKeys: [...gatesStripped],
|
|
262
|
+
warnings: [
|
|
263
|
+
...sanitizedWarning ? [sanitizedWarning] : [],
|
|
264
|
+
securityWarning
|
|
265
|
+
]
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (sanitizedWarning)
|
|
269
|
+
advisoryWarn(`[opencode-swarm] ${sanitizedWarning}`);
|
|
270
|
+
return {
|
|
271
|
+
config,
|
|
272
|
+
recovery: gatesStripped.length > 0 ? "stripped_keys" : "none",
|
|
273
|
+
removedKeys: [...gatesStripped],
|
|
274
|
+
warnings: sanitizedWarning ? [sanitizedWarning] : []
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
const { cleaned, removed } = stripUnrecognizedKeys(mergedRaw, firstResult.error);
|
|
215
278
|
if (removed.length > 0) {
|
|
216
279
|
const recovered = PluginConfigSchema.safeParse(cleaned);
|
|
217
280
|
if (recovered.success) {
|
|
218
|
-
const
|
|
281
|
+
const removedKeys = [...gatesStripped, ...removed];
|
|
282
|
+
const warning = warningForRemovedKeys(removedKeys);
|
|
219
283
|
advisoryWarn(`[opencode-swarm] ${warning}`);
|
|
220
284
|
return {
|
|
221
285
|
config: secure(recovered.data),
|
|
222
286
|
recovery: "stripped_keys",
|
|
223
|
-
removedKeys
|
|
287
|
+
removedKeys,
|
|
224
288
|
warnings: [warning]
|
|
225
289
|
};
|
|
226
290
|
}
|
|
227
291
|
}
|
|
228
292
|
if (rawUserConfig) {
|
|
229
|
-
const userSanitized = sanitizeSectionConfigs(rawUserConfig
|
|
293
|
+
const { result: userSanitized, strippedKeys: userGatesStripped } = sanitizeSectionConfigs(rawUserConfig);
|
|
230
294
|
const userParseResult = PluginConfigSchema.safeParse(userSanitized);
|
|
231
295
|
if (userParseResult.success) {
|
|
232
|
-
|
|
233
|
-
advisoryWarn(`[opencode-swarm] ${warning}`);
|
|
296
|
+
advisoryWarn("[opencode-swarm] Project config ignored due to validation errors. Using user config.");
|
|
234
297
|
return {
|
|
235
298
|
config: secure(userParseResult.data),
|
|
236
299
|
recovery: "user_only",
|
|
237
|
-
removedKeys: [],
|
|
238
|
-
warnings: [
|
|
300
|
+
removedKeys: [...gatesStripped, ...userGatesStripped],
|
|
301
|
+
warnings: [
|
|
302
|
+
"Project config ignored due to validation errors; using user config."
|
|
303
|
+
]
|
|
239
304
|
};
|
|
240
305
|
}
|
|
241
306
|
const userStripped = stripUnrecognizedKeys(userSanitized, userParseResult.error);
|
|
242
307
|
if (userStripped.removed.length > 0) {
|
|
243
308
|
const userRecovered = PluginConfigSchema.safeParse(userStripped.cleaned);
|
|
244
309
|
if (userRecovered.success) {
|
|
245
|
-
|
|
246
|
-
advisoryWarn(`[opencode-swarm] ${warning}`);
|
|
310
|
+
advisoryWarn(`[opencode-swarm] Project config ignored; also ignored ${userStripped.removed.length} unrecognized user-config key(s): ${userStripped.removed.join(", ")}.`);
|
|
247
311
|
return {
|
|
248
312
|
config: secure(userRecovered.data),
|
|
249
313
|
recovery: "user_only",
|
|
250
|
-
removedKeys:
|
|
251
|
-
|
|
314
|
+
removedKeys: [
|
|
315
|
+
...gatesStripped,
|
|
316
|
+
...userGatesStripped,
|
|
317
|
+
...userStripped.removed
|
|
318
|
+
],
|
|
319
|
+
warnings: [
|
|
320
|
+
"Project config ignored due to validation errors; using user config."
|
|
321
|
+
]
|
|
252
322
|
};
|
|
253
323
|
}
|
|
254
324
|
}
|
|
255
325
|
}
|
|
256
|
-
const offending = stripUnrecognizedKeys(mergedRaw,
|
|
257
|
-
const warnings = [];
|
|
326
|
+
const offending = stripUnrecognizedKeys(mergedRaw, firstResult.error).removed;
|
|
258
327
|
if (offending.length > 0) {
|
|
259
|
-
|
|
260
|
-
advisoryWarn(`[opencode-swarm] ${warning}`);
|
|
261
|
-
warnings.push(warning);
|
|
328
|
+
advisoryWarn(`[opencode-swarm] Merged config validation failed. Unrecognized key(s): ${offending.join(", ")}.`);
|
|
262
329
|
} else {
|
|
263
|
-
advisoryWarn("[opencode-swarm] Merged config validation failed:", formatZodIssues(
|
|
264
|
-
warnings.push("Merged config validation failed.");
|
|
330
|
+
advisoryWarn("[opencode-swarm] Merged config validation failed:", formatZodIssues(firstResult.error));
|
|
265
331
|
}
|
|
266
|
-
|
|
267
|
-
advisoryWarn(`[opencode-swarm] ${securityWarning}`);
|
|
268
|
-
warnings.push(securityWarning);
|
|
332
|
+
advisoryWarn("[opencode-swarm] \u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.");
|
|
269
333
|
return {
|
|
270
334
|
config: PluginConfigSchema.parse({ guardrails: { enabled: true } }),
|
|
271
335
|
recovery: "guardrails_defaults",
|
|
272
|
-
removedKeys:
|
|
273
|
-
warnings
|
|
336
|
+
removedKeys: [...gatesStripped],
|
|
337
|
+
warnings: [
|
|
338
|
+
"Config failed validation; using safe defaults with guardrails enabled."
|
|
339
|
+
]
|
|
274
340
|
};
|
|
275
341
|
}
|
|
276
|
-
function rawFullAutoLocked(raw) {
|
|
277
|
-
if (!raw || typeof raw !== "object")
|
|
278
|
-
return false;
|
|
279
|
-
const fullAuto = raw.full_auto;
|
|
280
|
-
if (!fullAuto || typeof fullAuto !== "object" || Array.isArray(fullAuto)) {
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
return fullAuto.locked === true;
|
|
284
|
-
}
|
|
285
342
|
function loadPluginConfig(directory) {
|
|
286
343
|
const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
|
|
287
344
|
const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
|
|
288
345
|
const userResult = loadRawConfigFromPath(userConfigPath);
|
|
289
346
|
const projectResult = loadRawConfigFromPath(projectConfigPath);
|
|
290
|
-
const rawUserConfig = userResult.config;
|
|
291
|
-
const rawProjectConfig = projectResult.config;
|
|
292
347
|
const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
|
|
293
348
|
const configHadErrors = userResult.hadError || projectResult.hadError;
|
|
294
|
-
|
|
295
|
-
if (rawProjectConfig) {
|
|
296
|
-
mergedRaw = deepMerge(mergedRaw, rawProjectConfig);
|
|
297
|
-
}
|
|
298
|
-
if (rawFullAutoLocked(rawUserConfig) || rawFullAutoLocked(rawProjectConfig)) {
|
|
299
|
-
const fullAutoRaw = mergedRaw.full_auto && typeof mergedRaw.full_auto === "object" && !Array.isArray(mergedRaw.full_auto) ? mergedRaw.full_auto : {};
|
|
300
|
-
mergedRaw = {
|
|
301
|
-
...mergedRaw,
|
|
302
|
-
full_auto: { ...fullAutoRaw, locked: true }
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
mergedRaw = migratePresetsConfig(mergedRaw);
|
|
306
|
-
mergedRaw = sanitizeSectionConfigs(mergedRaw);
|
|
307
|
-
const result = PluginConfigSchema.safeParse(mergedRaw);
|
|
308
|
-
if (result.success) {
|
|
309
|
-
if (loadedFromFile && configHadErrors) {
|
|
310
|
-
return PluginConfigSchema.parse({
|
|
311
|
-
...mergedRaw,
|
|
312
|
-
guardrails: { enabled: true }
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
return result.data;
|
|
316
|
-
}
|
|
317
|
-
const { config } = parseConfigWithFallback(mergedRaw, rawUserConfig, result, loadedFromFile, configHadErrors);
|
|
318
|
-
return config;
|
|
349
|
+
return buildConfigWithMeta(userResult.config, projectResult.config, loadedFromFile, configHadErrors).config;
|
|
319
350
|
}
|
|
320
351
|
function loadPluginConfigWithMeta(directory) {
|
|
321
352
|
const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
|
|
322
353
|
const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
|
|
323
354
|
const userResult = loadRawConfigFromPath(userConfigPath);
|
|
324
355
|
const projectResult = loadRawConfigFromPath(projectConfigPath);
|
|
325
|
-
const rawUserConfig = userResult.config;
|
|
326
|
-
const rawProjectConfig = projectResult.config;
|
|
327
356
|
const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
|
|
328
357
|
const configHadErrors = userResult.hadError || projectResult.hadError;
|
|
329
|
-
|
|
330
|
-
if (rawProjectConfig) {
|
|
331
|
-
mergedRaw = deepMerge(mergedRaw, rawProjectConfig);
|
|
332
|
-
}
|
|
333
|
-
if (rawFullAutoLocked(rawUserConfig) || rawFullAutoLocked(rawProjectConfig)) {
|
|
334
|
-
const fullAutoRaw = mergedRaw.full_auto && typeof mergedRaw.full_auto === "object" && !Array.isArray(mergedRaw.full_auto) ? mergedRaw.full_auto : {};
|
|
335
|
-
mergedRaw = {
|
|
336
|
-
...mergedRaw,
|
|
337
|
-
full_auto: { ...fullAutoRaw, locked: true }
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
mergedRaw = migratePresetsConfig(mergedRaw);
|
|
341
|
-
mergedRaw = sanitizeSectionConfigs(mergedRaw);
|
|
342
|
-
const result = PluginConfigSchema.safeParse(mergedRaw);
|
|
343
|
-
if (result.success) {
|
|
344
|
-
if (loadedFromFile && configHadErrors) {
|
|
345
|
-
const config2 = PluginConfigSchema.parse({
|
|
346
|
-
...mergedRaw,
|
|
347
|
-
guardrails: { enabled: true }
|
|
348
|
-
});
|
|
349
|
-
return {
|
|
350
|
-
config: config2,
|
|
351
|
-
loadedFromFile,
|
|
352
|
-
configHadErrors,
|
|
353
|
-
recovery: "guardrails_defaults",
|
|
354
|
-
removedKeys: [],
|
|
355
|
-
warnings: [
|
|
356
|
-
"\u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration."
|
|
357
|
-
]
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
return {
|
|
361
|
-
config: result.data,
|
|
362
|
-
loadedFromFile,
|
|
363
|
-
configHadErrors,
|
|
364
|
-
recovery: "none",
|
|
365
|
-
removedKeys: [],
|
|
366
|
-
warnings: []
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
const { config, recovery, removedKeys, warnings } = parseConfigWithFallback(mergedRaw, rawUserConfig, result, loadedFromFile, configHadErrors);
|
|
358
|
+
const { config, recovery, removedKeys, warnings } = buildConfigWithMeta(userResult.config, projectResult.config, loadedFromFile, configHadErrors);
|
|
370
359
|
return {
|
|
371
360
|
config,
|
|
372
361
|
loadedFromFile,
|
|
@@ -414,37 +403,6 @@ async function loadRawConfigFromPathAsync(configPath) {
|
|
|
414
403
|
return { config: null, fileExisted: true, hadError: true };
|
|
415
404
|
}
|
|
416
405
|
}
|
|
417
|
-
function reduceParsedConfig(rawUserConfig, rawProjectConfig, loadedFromFile, configHadErrors) {
|
|
418
|
-
let mergedRaw = rawUserConfig ?? {};
|
|
419
|
-
if (rawProjectConfig) {
|
|
420
|
-
mergedRaw = deepMerge(mergedRaw, rawProjectConfig);
|
|
421
|
-
}
|
|
422
|
-
mergedRaw = migratePresetsConfig(mergedRaw);
|
|
423
|
-
mergedRaw = sanitizeSectionConfigs(mergedRaw);
|
|
424
|
-
const result = PluginConfigSchema.safeParse(mergedRaw);
|
|
425
|
-
if (result.success) {
|
|
426
|
-
if (loadedFromFile && configHadErrors) {
|
|
427
|
-
return {
|
|
428
|
-
config: PluginConfigSchema.parse({
|
|
429
|
-
...mergedRaw,
|
|
430
|
-
guardrails: { enabled: true }
|
|
431
|
-
}),
|
|
432
|
-
recovery: "guardrails_defaults",
|
|
433
|
-
removedKeys: [],
|
|
434
|
-
warnings: [
|
|
435
|
-
"\u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration."
|
|
436
|
-
]
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
|
-
return {
|
|
440
|
-
config: result.data,
|
|
441
|
-
recovery: "none",
|
|
442
|
-
removedKeys: [],
|
|
443
|
-
warnings: []
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
return parseConfigWithFallback(mergedRaw, rawUserConfig, result, loadedFromFile, configHadErrors);
|
|
447
|
-
}
|
|
448
406
|
async function loadPluginConfigWithMetaAsync(directory) {
|
|
449
407
|
const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
|
|
450
408
|
const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
|
|
@@ -454,7 +412,7 @@ async function loadPluginConfigWithMetaAsync(directory) {
|
|
|
454
412
|
]);
|
|
455
413
|
const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
|
|
456
414
|
const configHadErrors = userResult.hadError || projectResult.hadError;
|
|
457
|
-
const { config, recovery, removedKeys, warnings } =
|
|
415
|
+
const { config, recovery, removedKeys, warnings } = buildConfigWithMeta(userResult.config, projectResult.config, loadedFromFile, configHadErrors);
|
|
458
416
|
return {
|
|
459
417
|
config,
|
|
460
418
|
loadedFromFile,
|
|
@@ -60,19 +60,35 @@ var init_tool_metadata = __esm(() => {
|
|
|
60
60
|
"critic_oversight",
|
|
61
61
|
"coder",
|
|
62
62
|
"test_engineer"
|
|
63
|
-
]
|
|
63
|
+
],
|
|
64
|
+
prWorkflow: {
|
|
65
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
66
|
+
capability: "observe"
|
|
67
|
+
}
|
|
64
68
|
},
|
|
65
69
|
diff_summary: {
|
|
66
70
|
description: "filter classified AST changes by category, risk level, or file for reviewer drill-down",
|
|
67
|
-
agents: ["architect", "reviewer", "critic_oversight"]
|
|
71
|
+
agents: ["architect", "reviewer", "critic_oversight"],
|
|
72
|
+
prWorkflow: {
|
|
73
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
74
|
+
capability: "observe"
|
|
75
|
+
}
|
|
68
76
|
},
|
|
69
77
|
syntax_check: {
|
|
70
78
|
description: "check syntax of source files using tree-sitter parsers across multiple languages, returning per-file errors",
|
|
71
|
-
agents: ["architect", "coder", "test_engineer"]
|
|
79
|
+
agents: ["architect", "coder", "test_engineer"],
|
|
80
|
+
prWorkflow: {
|
|
81
|
+
modes: ["PR_REVIEW"],
|
|
82
|
+
capability: "validate"
|
|
83
|
+
}
|
|
72
84
|
},
|
|
73
85
|
placeholder_scan: {
|
|
74
86
|
description: "todo and FIXME comment detection",
|
|
75
|
-
agents: ["architect", "reviewer"]
|
|
87
|
+
agents: ["architect", "reviewer"],
|
|
88
|
+
prWorkflow: {
|
|
89
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
90
|
+
capability: "observe"
|
|
91
|
+
}
|
|
76
92
|
},
|
|
77
93
|
imports: {
|
|
78
94
|
description: "find all consumers that import from a given file \u2014 use before refactoring shared modules to avoid breaking unseen dependents",
|
|
@@ -89,19 +105,35 @@ var init_tool_metadata = __esm(() => {
|
|
|
89
105
|
"critic",
|
|
90
106
|
"coder",
|
|
91
107
|
"test_engineer"
|
|
92
|
-
]
|
|
108
|
+
],
|
|
109
|
+
prWorkflow: {
|
|
110
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
111
|
+
capability: "observe"
|
|
112
|
+
}
|
|
93
113
|
},
|
|
94
114
|
lint: {
|
|
95
115
|
description: "run project linter in check or fix mode; supports biome, eslint, ruff, clippy, and more, returns structured results",
|
|
96
|
-
agents: ["architect", "reviewer", "coder"]
|
|
116
|
+
agents: ["architect", "reviewer", "coder"],
|
|
117
|
+
prWorkflow: {
|
|
118
|
+
modes: ["PR_REVIEW"],
|
|
119
|
+
capability: "validate"
|
|
120
|
+
}
|
|
97
121
|
},
|
|
98
122
|
secretscan: {
|
|
99
123
|
description: "scan for secrets (API keys, tokens, passwords) via regex and entropy; returns redacted previews, excludes common dirs",
|
|
100
|
-
agents: ["architect", "reviewer", "critic_oversight"]
|
|
124
|
+
agents: ["architect", "reviewer", "critic_oversight"],
|
|
125
|
+
prWorkflow: {
|
|
126
|
+
modes: ["PR_REVIEW"],
|
|
127
|
+
capability: "validate"
|
|
128
|
+
}
|
|
101
129
|
},
|
|
102
130
|
sast_scan: {
|
|
103
131
|
description: "static analysis security scan",
|
|
104
|
-
agents: ["architect", "reviewer", "critic_oversight"]
|
|
132
|
+
agents: ["architect", "reviewer", "critic_oversight"],
|
|
133
|
+
prWorkflow: {
|
|
134
|
+
modes: ["PR_REVIEW"],
|
|
135
|
+
capability: "validate"
|
|
136
|
+
}
|
|
105
137
|
},
|
|
106
138
|
build_check: {
|
|
107
139
|
description: "discover and run build, typecheck, and test commands for various project ecosystems in the working directory",
|
|
@@ -113,7 +145,11 @@ var init_tool_metadata = __esm(() => {
|
|
|
113
145
|
},
|
|
114
146
|
quality_budget: {
|
|
115
147
|
description: "code quality budget check",
|
|
116
|
-
agents: ["architect"]
|
|
148
|
+
agents: ["architect"],
|
|
149
|
+
prWorkflow: {
|
|
150
|
+
modes: ["PR_REVIEW"],
|
|
151
|
+
capability: "validate"
|
|
152
|
+
}
|
|
117
153
|
},
|
|
118
154
|
symbols: {
|
|
119
155
|
description: "extract exported symbols (functions, classes, interfaces, types) from source files; supports TypeScript, JavaScript, and Python",
|
|
@@ -152,11 +188,19 @@ var init_tool_metadata = __esm(() => {
|
|
|
152
188
|
},
|
|
153
189
|
schema_drift: {
|
|
154
190
|
description: "OpenAPI spec vs route drift",
|
|
155
|
-
agents: ["architect", "sme", "researcher", "docs", "explorer"]
|
|
191
|
+
agents: ["architect", "sme", "researcher", "docs", "explorer"],
|
|
192
|
+
prWorkflow: {
|
|
193
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
194
|
+
capability: "observe"
|
|
195
|
+
}
|
|
156
196
|
},
|
|
157
197
|
todo_extract: {
|
|
158
198
|
description: "structured TODO/FIXME extraction",
|
|
159
|
-
agents: ["architect", "researcher", "docs", "explorer"]
|
|
199
|
+
agents: ["architect", "researcher", "docs", "explorer"],
|
|
200
|
+
prWorkflow: {
|
|
201
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
202
|
+
capability: "observe"
|
|
203
|
+
}
|
|
160
204
|
},
|
|
161
205
|
evidence_check: {
|
|
162
206
|
description: "verify task evidence completeness",
|
|
@@ -210,7 +254,11 @@ var init_tool_metadata = __esm(() => {
|
|
|
210
254
|
"reviewer",
|
|
211
255
|
"critic_oversight",
|
|
212
256
|
"test_engineer"
|
|
213
|
-
]
|
|
257
|
+
],
|
|
258
|
+
prWorkflow: {
|
|
259
|
+
modes: ["PR_REVIEW"],
|
|
260
|
+
capability: "validate"
|
|
261
|
+
}
|
|
214
262
|
},
|
|
215
263
|
parse_lane_candidates: {
|
|
216
264
|
description: "Parse [CANDIDATE] rows from a dispatch_lanes or collect_lane_results artifact (by output_ref), produce structured records with provenance, optionally persist to a per-batch sidecar JSONL. Pure-parser variant exists as internal module.",
|
|
@@ -220,13 +268,29 @@ var init_tool_metadata = __esm(() => {
|
|
|
220
268
|
description: "persist the complete PR-review trigger evaluation with exact-set validation, dispatch provenance, and live merge-base verification",
|
|
221
269
|
agents: ["architect"]
|
|
222
270
|
},
|
|
271
|
+
write_pr_review_artifact: {
|
|
272
|
+
description: "persist schema-validated PR-review findings checkpoints and exact actionable feedback handoffs under the active run",
|
|
273
|
+
agents: ["architect"]
|
|
274
|
+
},
|
|
275
|
+
prepare_pr_feedback_scope: {
|
|
276
|
+
description: "prepare an exact file scope for one PR-feedback coder Task after immutable feedback verification settles",
|
|
277
|
+
agents: ["architect"]
|
|
278
|
+
},
|
|
223
279
|
test_runner: {
|
|
224
280
|
description: "auto-detect and run tests",
|
|
225
|
-
agents: ["architect", "reviewer", "test_engineer"]
|
|
281
|
+
agents: ["architect", "reviewer", "test_engineer"],
|
|
282
|
+
prWorkflow: {
|
|
283
|
+
modes: ["PR_REVIEW"],
|
|
284
|
+
capability: "validate"
|
|
285
|
+
}
|
|
226
286
|
},
|
|
227
287
|
test_impact: {
|
|
228
288
|
description: "identify test files impacted by changed source files via import analysis",
|
|
229
|
-
agents: ["architect", "reviewer", "critic_oversight", "test_engineer"]
|
|
289
|
+
agents: ["architect", "reviewer", "critic_oversight", "test_engineer"],
|
|
290
|
+
prWorkflow: {
|
|
291
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
292
|
+
capability: "observe"
|
|
293
|
+
}
|
|
230
294
|
},
|
|
231
295
|
mutation_test: {
|
|
232
296
|
description: "executes pre-generated mutation patches against tests, evaluates kill rate against quality gate thresholds",
|
|
@@ -253,11 +317,19 @@ var init_tool_metadata = __esm(() => {
|
|
|
253
317
|
},
|
|
254
318
|
git_blame: {
|
|
255
319
|
description: "per-line git blame metadata: sha, author, date, summary for each line in a file",
|
|
256
|
-
agents: ["reviewer", "explorer", "architect"]
|
|
320
|
+
agents: ["reviewer", "explorer", "architect"],
|
|
321
|
+
prWorkflow: {
|
|
322
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
323
|
+
capability: "observe"
|
|
324
|
+
}
|
|
257
325
|
},
|
|
258
326
|
gitingest: {
|
|
259
327
|
description: "fetch a GitHub repository full content via gitingest.com",
|
|
260
|
-
agents: ["architect", "docs", "explorer"]
|
|
328
|
+
agents: ["architect", "docs", "explorer"],
|
|
329
|
+
prWorkflow: {
|
|
330
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
331
|
+
capability: "observe"
|
|
332
|
+
}
|
|
261
333
|
},
|
|
262
334
|
retrieve_summary: {
|
|
263
335
|
description: "retrieve the full content of a stored tool output summary",
|
|
@@ -280,7 +352,11 @@ var init_tool_metadata = __esm(() => {
|
|
|
280
352
|
},
|
|
281
353
|
retrieve_lane_output: {
|
|
282
354
|
description: "retrieve paged full dispatch lane output by output_ref; use before consuming truncated lane previews or routing candidates from lane results",
|
|
283
|
-
agents: ["architect"]
|
|
355
|
+
agents: ["architect"],
|
|
356
|
+
prWorkflow: {
|
|
357
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
358
|
+
capability: "observe"
|
|
359
|
+
}
|
|
284
360
|
},
|
|
285
361
|
extract_code_blocks: {
|
|
286
362
|
description: "extract code blocks from text content and save them to files",
|
|
@@ -427,15 +503,27 @@ var init_tool_metadata = __esm(() => {
|
|
|
427
503
|
},
|
|
428
504
|
actionlint_scan: {
|
|
429
505
|
description: "Run actionlint against GitHub Actions workflow YAML files with structured findings. Resolves actionlint lazily and does not modify files.",
|
|
430
|
-
agents: ["architect", "test_engineer"]
|
|
506
|
+
agents: ["architect", "test_engineer"],
|
|
507
|
+
prWorkflow: {
|
|
508
|
+
modes: ["PR_REVIEW"],
|
|
509
|
+
capability: "validate"
|
|
510
|
+
}
|
|
431
511
|
},
|
|
432
512
|
osv_scan: {
|
|
433
513
|
description: "Run OSV-Scanner against a workspace path and return structured dependency vulnerability findings. Resolves osv-scanner lazily and does not modify files.",
|
|
434
|
-
agents: ["architect", "test_engineer"]
|
|
514
|
+
agents: ["architect", "test_engineer"],
|
|
515
|
+
prWorkflow: {
|
|
516
|
+
modes: ["PR_REVIEW"],
|
|
517
|
+
capability: "validate"
|
|
518
|
+
}
|
|
435
519
|
},
|
|
436
520
|
gh_evidence: {
|
|
437
521
|
description: "Fetch bounded GitHub pull request or issue metadata through gh for review and CI evidence. Resolves gh lazily and is read-only.",
|
|
438
|
-
agents: ["architect", "researcher"]
|
|
522
|
+
agents: ["architect", "researcher"],
|
|
523
|
+
prWorkflow: {
|
|
524
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
525
|
+
capability: "observe"
|
|
526
|
+
}
|
|
439
527
|
},
|
|
440
528
|
batch_symbols: {
|
|
441
529
|
description: "Batched symbol extraction across multiple files. Returns per-file symbol summaries with isolated error handling.",
|
|
@@ -479,7 +567,11 @@ var init_tool_metadata = __esm(() => {
|
|
|
479
567
|
"critic_oversight",
|
|
480
568
|
"explorer",
|
|
481
569
|
"coder"
|
|
482
|
-
]
|
|
570
|
+
],
|
|
571
|
+
prWorkflow: {
|
|
572
|
+
modes: ["PR_REVIEW", "PR_FEEDBACK"],
|
|
573
|
+
capability: "observe"
|
|
574
|
+
}
|
|
483
575
|
},
|
|
484
576
|
get_qa_gate_profile: {
|
|
485
577
|
description: "retrieve the QA gate profile for the current plan: gates (reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council), lock state, and profile hash. Read-only.",
|
|
@@ -608,7 +608,7 @@ async function applyKnowledgeVerdictFeedback(directory, options) {
|
|
|
608
608
|
deltas.push({ id, delta });
|
|
609
609
|
}
|
|
610
610
|
if (deltas.length > 0) {
|
|
611
|
-
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-
|
|
611
|
+
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-1d4byc7y.js");
|
|
612
612
|
await bumpKnowledgeConfidenceBatch(directory, deltas, options?.floorOptions);
|
|
613
613
|
}
|
|
614
614
|
return {
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ALLOWED_SKILL_PATH_PREFIXES,
|
|
4
4
|
validateSkillPath
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-6j9p0c40.js";
|
|
6
6
|
import {
|
|
7
7
|
computeOutcomeSignal,
|
|
8
8
|
readKnowledge,
|
|
9
9
|
resolveHiveKnowledgePath,
|
|
10
10
|
resolveSwarmKnowledgePath,
|
|
11
11
|
transactKnowledge
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-nmyg9b7v.js";
|
|
13
13
|
import {
|
|
14
14
|
effectiveRetrievalOutcomes,
|
|
15
15
|
readKnowledgeCounterRollups
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-cnhp6c0k.js";
|
|
17
17
|
import {
|
|
18
18
|
init_knowledge_types,
|
|
19
19
|
isActiveStatus
|