opencode-swarm 7.125.6 → 7.126.0

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 (33) hide show
  1. package/.opencode/skills/brainstorm/SKILL.md +18 -14
  2. package/.opencode/skills/plan/SKILL.md +21 -15
  3. package/.opencode/skills/specify/SKILL.md +18 -14
  4. package/dist/agents/architect.d.ts +9 -7
  5. package/dist/cli/{curation-policy-62w2pwfz.js → curation-policy-dptr1rfe.js} +2 -2
  6. package/dist/cli/{curator-gke6nrc4.js → curator-23hynz78.js} +9 -9
  7. package/dist/cli/{curator-llm-factory-40c4852v.js → curator-llm-factory-r648jn8e.js} +9 -9
  8. package/dist/cli/{guardrail-explain-m34vcgjg.js → guardrail-explain-6atsd4vr.js} +10 -10
  9. package/dist/cli/{hive-promoter-6fg3redm.js → hive-promoter-bnkhzd46.js} +9 -9
  10. package/dist/cli/{index-d17kqe54.js → index-0ff5cm9j.js} +75 -37
  11. package/dist/cli/{index-4b1e5m0d.js → index-16z6txq3.js} +1 -1
  12. package/dist/cli/{index-gbnpz7rh.js → index-2bnfwmk3.js} +1 -1
  13. package/dist/cli/{index-1012f47p.js → index-2yd75hms.js} +3 -3
  14. package/dist/cli/{index-zp330ss0.js → index-68fpa7ff.js} +10 -10
  15. package/dist/cli/{index-74xejn4v.js → index-a1c9az5e.js} +117 -19
  16. package/dist/cli/{index-0f45t7xy.js → index-bcgfhxzv.js} +4 -4
  17. package/dist/cli/{index-e315gwc9.js → index-cdx337js.js} +1 -1
  18. package/dist/cli/{index-yq4s3q43.js → index-kwnsatzq.js} +2 -2
  19. package/dist/cli/{index-1htanqp1.js → index-mgrsx5hn.js} +1 -1
  20. package/dist/cli/{index-1cxp3b5y.js → index-y4ry07h8.js} +1 -1
  21. package/dist/cli/{index-gd5w3ef8.js → index-yfzn5r9s.js} +3 -3
  22. package/dist/cli/index.js +9 -9
  23. package/dist/cli/{knowledge-escalator-h3hg7ek7.js → knowledge-escalator-4hc8w7sd.js} +3 -3
  24. package/dist/cli/{knowledge-events-jtr66wxz.js → knowledge-events-kyqjv1f8.js} +1 -1
  25. package/dist/cli/{knowledge-store-69ttjjjs.js → knowledge-store-06k0p1gs.js} +1 -1
  26. package/dist/cli/{knowledge-validator-yn06rh13.js → knowledge-validator-42xjmcmh.js} +4 -4
  27. package/dist/cli/{scan-cursor-r0w2p5gz.js → scan-cursor-gjcvpyta.js} +2 -2
  28. package/dist/cli/{skill-generator-a7xfyddq.js → skill-generator-t6j93mwt.js} +5 -5
  29. package/dist/commands/turbo-constants.d.ts +6 -0
  30. package/dist/config/constants.d.ts +1 -1
  31. package/dist/config/loader.d.ts +26 -0
  32. package/dist/index.js +20 -60
  33. package/package.json +2 -1
@@ -94,15 +94,15 @@ import {
94
94
  retireSkill,
95
95
  selectCandidateEntries,
96
96
  syncBundledProjectSkillsIfMissingAsync
97
- } from "./index-gd5w3ef8.js";
97
+ } from "./index-yfzn5r9s.js";
98
98
  import {
99
99
  readRecentEscalations
100
- } from "./index-0f45t7xy.js";
100
+ } from "./index-bcgfhxzv.js";
101
101
  import {
102
102
  alreadyCuratedThisGeneration,
103
103
  claimNextScanBatch,
104
104
  resolveCohortId
105
- } from "./index-e315gwc9.js";
105
+ } from "./index-cdx337js.js";
106
106
  import {
107
107
  CURATOR_INIT_PROMPT,
108
108
  CURATOR_PHASE_PROMPT,
@@ -135,11 +135,11 @@ import {
135
135
  validateActionability,
136
136
  validateActionableFields,
137
137
  validateLesson
138
- } from "./index-yq4s3q43.js";
138
+ } from "./index-kwnsatzq.js";
139
139
  import {
140
140
  authorizeCuration,
141
141
  buildConfigFingerprintInput
142
- } from "./index-1htanqp1.js";
142
+ } from "./index-mgrsx5hn.js";
143
143
  import {
144
144
  cohortConfigFingerprint
145
145
  } from "./index-rtry5xyf.js";
@@ -169,7 +169,7 @@ import {
169
169
  transactFile,
170
170
  transactKnowledge,
171
171
  wordBigrams
172
- } from "./index-1012f47p.js";
172
+ } from "./index-2yd75hms.js";
173
173
  import {
174
174
  MAX_EVENT_LOG_ENTRIES,
175
175
  _internals,
@@ -179,7 +179,7 @@ import {
179
179
  recordHiveKnowledgeEvent,
180
180
  recordKnowledgeEvent,
181
181
  resolveKnowledgeEventsPath
182
- } from "./index-gbnpz7rh.js";
182
+ } from "./index-2bnfwmk3.js";
183
183
  import {
184
184
  resolveHiveDataDir,
185
185
  resolveHiveEventsPath,
@@ -201,7 +201,7 @@ import {
201
201
  init_loader,
202
202
  loadPluginConfig,
203
203
  loadPluginConfigWithMeta
204
- } from "./index-74xejn4v.js";
204
+ } from "./index-a1c9az5e.js";
205
205
  import {
206
206
  RetrospectiveEvidenceSchema
207
207
  } from "./index-k5jrywpr.js";
@@ -5167,7 +5167,7 @@ async function propagateReward(provider, opts, sources, directlyRewardedIds) {
5167
5167
  if (!Number.isFinite(nowMs))
5168
5168
  return;
5169
5169
  const windowMs = windowDays * MS_PER_DAY2;
5170
- const recencyById = await buildRetrievalRecency(provider);
5170
+ const recencyById = await buildRetrievalRecency(provider, nowMs);
5171
5171
  if (!recencyById)
5172
5172
  return;
5173
5173
  const orderedSources = [...sources].sort((a, b) => a.id.localeCompare(b.id));
@@ -5234,10 +5234,10 @@ async function propagateReward(provider, opts, sources, directlyRewardedIds) {
5234
5234
  });
5235
5235
  }
5236
5236
  }
5237
- async function buildRetrievalRecency(provider) {
5237
+ async function buildRetrievalRecency(provider, nowMs) {
5238
5238
  if (typeof provider.listRecallUsage !== "function")
5239
5239
  return null;
5240
- const since = new Date(Date.now() - RECENCY_WINDOW_MS).toISOString();
5240
+ const since = new Date(nowMs - RECENCY_WINDOW_MS).toISOString();
5241
5241
  const usage = await provider.listRecallUsage({ since, limit: RECENCY_EVENT_LIMIT }) ?? [];
5242
5242
  const recency = new Map;
5243
5243
  for (const event of usage) {
@@ -10925,7 +10925,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
10925
10925
  }
10926
10926
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
10927
10927
  try {
10928
- const skillModule = await import("./skill-generator-a7xfyddq.js");
10928
+ const skillModule = await import("./skill-generator-t6j93mwt.js");
10929
10929
  for (const cand of skillCandidates) {
10930
10930
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
10931
10931
  continue;
@@ -11262,7 +11262,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
11262
11262
  } catch {}
11263
11263
  }
11264
11264
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
11265
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-h3hg7ek7.js");
11265
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-4hc8w7sd.js");
11266
11266
  for (const { id } of contradictedEntries) {
11267
11267
  try {
11268
11268
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -12061,7 +12061,7 @@ async function runCuratorPostMortem(directory, options = {}) {
12061
12061
  warnings.push("Failed to collect knowledge summary.");
12062
12062
  }
12063
12063
  try {
12064
- const { getScanStatus } = await import("./scan-cursor-r0w2p5gz.js");
12064
+ const { getScanStatus } = await import("./scan-cursor-gjcvpyta.js");
12065
12065
  const scanStatus = await getScanStatus(directory);
12066
12066
  if (scanStatus.remaining_estimate > 0) {
12067
12067
  warnings.push(`Fair scan: reviewed ${knowledgeSummary.length} entries this sweep (generation ${scanStatus.generation}); ${scanStatus.remaining_estimate} more eligible entries will be visited in future curation sweeps.`);
@@ -12235,7 +12235,7 @@ var _internals15 = {
12235
12235
  loadDefaultKnowledgeConfig: async (directory) => {
12236
12236
  const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-69z8w1ka.js");
12237
12237
  try {
12238
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4b1e5m0d.js");
12238
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-16z6txq3.js");
12239
12239
  const loaded = loadPluginConfigWithMeta2(directory);
12240
12240
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
12241
12241
  } catch {
@@ -12243,11 +12243,11 @@ var _internals15 = {
12243
12243
  }
12244
12244
  },
12245
12245
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
12246
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-gke6nrc4.js");
12246
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-23hynz78.js");
12247
12247
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
12248
12248
  },
12249
12249
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
12250
- const { checkHivePromotions } = await import("./hive-promoter-6fg3redm.js");
12250
+ const { checkHivePromotions } = await import("./hive-promoter-bnkhzd46.js");
12251
12251
  return checkHivePromotions(entries, knowledgeConfig, directory);
12252
12252
  },
12253
12253
  applyProposalTriage: async (directory, triage) => {
@@ -12256,7 +12256,7 @@ var _internals15 = {
12256
12256
  activateProposal,
12257
12257
  listSkills: listSkills2,
12258
12258
  sanitizeSlug
12259
- } = await import("./skill-generator-a7xfyddq.js");
12259
+ } = await import("./skill-generator-t6j93mwt.js");
12260
12260
  const result = {
12261
12261
  approved: [],
12262
12262
  rejected: [],
@@ -14783,7 +14783,7 @@ function hashContent(content) {
14783
14783
  async function loadConfigForPolicyCurator(directory) {
14784
14784
  const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-69z8w1ka.js");
14785
14785
  try {
14786
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4b1e5m0d.js");
14786
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-16z6txq3.js");
14787
14787
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
14788
14788
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
14789
14789
  } catch {
@@ -20114,8 +20114,8 @@ var _internals28 = {
20114
20114
  loadCuratorDeps: async () => {
20115
20115
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
20116
20116
  import("./schema-69z8w1ka.js"),
20117
- import("./curator-gke6nrc4.js"),
20118
- import("./curator-llm-factory-40c4852v.js")
20117
+ import("./curator-23hynz78.js"),
20118
+ import("./curator-llm-factory-r648jn8e.js")
20119
20119
  ]);
20120
20120
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
20121
20121
  }
@@ -20614,7 +20614,7 @@ import { fileURLToPath } from "url";
20614
20614
  // package.json
20615
20615
  var package_default = {
20616
20616
  name: "opencode-swarm",
20617
- version: "7.125.6",
20617
+ version: "7.126.0",
20618
20618
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
20619
20619
  main: "dist/index.js",
20620
20620
  types: "dist/index.d.ts",
@@ -20709,6 +20709,7 @@ var package_default = {
20709
20709
  "test:unit:ci": "bun scripts/ci/run-unit-tests-local.ts",
20710
20710
  "drift:check": "bun run scripts/drift-check.ts",
20711
20711
  "drift:fix": "bun run scripts/drift-check.ts --fix --confirm",
20712
+ "skills:sync": "bun run scripts/sync-qa-gate-skills.ts",
20712
20713
  format: "biome format . --write",
20713
20714
  check: "biome check --write .",
20714
20715
  dev: "bun run build && opencode",
@@ -21135,7 +21136,7 @@ async function computeCurationDiagnostics(directory, entries) {
21135
21136
  let scanCompleted = false;
21136
21137
  let scanRemaining = 0;
21137
21138
  try {
21138
- const { getScanStatus } = await import("./scan-cursor-r0w2p5gz.js");
21139
+ const { getScanStatus } = await import("./scan-cursor-gjcvpyta.js");
21139
21140
  const status = await getScanStatus(directory);
21140
21141
  scanGeneration = status.generation;
21141
21142
  scanCompleted = status.completed;
@@ -21148,14 +21149,14 @@ async function computeCurationDiagnostics(directory, entries) {
21148
21149
  const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-69z8w1ka.js");
21149
21150
  let config;
21150
21151
  try {
21151
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4b1e5m0d.js");
21152
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-16z6txq3.js");
21152
21153
  const loaded = loadPluginConfigWithMeta2(directory);
21153
21154
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
21154
21155
  } catch {
21155
21156
  config = KnowledgeConfigSchema2.parse({});
21156
21157
  }
21157
21158
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
21158
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-62w2pwfz.js");
21159
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-dptr1rfe.js");
21159
21160
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
21160
21161
  const cohortFp = await readCohortConfigFingerprint(directory);
21161
21162
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -22301,6 +22302,15 @@ function formatToolDoctorMarkdown(result) {
22301
22302
  return lines.join(`
22302
22303
  `);
22303
22304
  }
22305
+ function stripControlChars(s) {
22306
+ return s.replace(/[\x00-\x1f\x7f]+/g, " ");
22307
+ }
22308
+ function sanitizeForMarkdownCodeSpan(s) {
22309
+ return stripControlChars(s).replace(/`/g, "'");
22310
+ }
22311
+ function sanitizeForMarkdownText(s) {
22312
+ return stripControlChars(s).replace(/([\\`*_[\]|])/g, "\\$1");
22313
+ }
22304
22314
  function formatDoctorMarkdown(result) {
22305
22315
  const lines = [
22306
22316
  "## Config Doctor Report",
@@ -22339,7 +22349,8 @@ function formatDoctorMarkdown(result) {
22339
22349
  }
22340
22350
  async function handleDoctorCommand(directory, args) {
22341
22351
  const enableAutoFix = args.includes("--fix") || args.includes("-f");
22342
- const config = loadPluginConfig(directory);
22352
+ const meta = loadPluginConfigWithMeta(directory);
22353
+ const config = meta.config;
22343
22354
  const result = runConfigDoctor(config, directory);
22344
22355
  let output;
22345
22356
  if (enableAutoFix && result.hasAutoFixableIssues) {
@@ -22358,6 +22369,28 @@ async function handleDoctorCommand(directory, args) {
22358
22369
  }
22359
22370
  output = markdown;
22360
22371
  }
22372
+ if (meta.recovery !== "none") {
22373
+ const lines = [`
22374
+ ---
22375
+
22376
+ ## Config Recovery (FR-004)
22377
+
22378
+ `];
22379
+ lines.push(`- **Recovery applied**: \`${meta.recovery}\``);
22380
+ if (meta.removedKeys.length > 0) {
22381
+ lines.push(`- **Removed keys (${meta.removedKeys.length})**:`);
22382
+ for (const k of meta.removedKeys)
22383
+ lines.push(` - \`${sanitizeForMarkdownCodeSpan(k)}\``);
22384
+ }
22385
+ if (meta.warnings.length > 0) {
22386
+ lines.push(`- **Recovery warnings (${meta.warnings.length})**:`);
22387
+ for (const w of meta.warnings)
22388
+ lines.push(` - ${sanitizeForMarkdownText(w)}`);
22389
+ }
22390
+ output += `${lines.join(`
22391
+ `)}
22392
+ `;
22393
+ }
22361
22394
  const strayDirs = detectStraySwarmDirs(directory);
22362
22395
  if (strayDirs.length > 0) {
22363
22396
  if (enableAutoFix) {
@@ -40706,6 +40739,11 @@ No active swarm plan found. Nothing to sync.`;
40706
40739
 
40707
40740
  // src/commands/turbo.ts
40708
40741
  init_logger();
40742
+
40743
+ // src/commands/turbo-constants.ts
40744
+ var TURBO_BYPASS_DISCLOSURE = "Bypassed: Stage B (reviewer + test_engineer) for Tier 0-2 tasks; phase_complete Gates 1-5 " + "(completion-verify, drift-verifier, hallucination-guard, mutation-gate, phase-council). " + "Still enforced: Stage A (lint, imports, pre_check_batch); Tier 3 Stage B; Gate 5b " + "(architecture-supervisor); Gate 6 (final-council); Gate 7 (full-auto).";
40745
+
40746
+ // src/commands/turbo.ts
40709
40747
  var _internals61 = {
40710
40748
  loadPluginConfigWithMeta
40711
40749
  };
@@ -40760,7 +40798,7 @@ async function handleTurboCommand(directory, args, sessionID) {
40760
40798
  session.turboStrategy = "standard";
40761
40799
  session.leanTurboActive = false;
40762
40800
  session.leanTurboCurrentPhase = undefined;
40763
- return "Turbo Mode enabled";
40801
+ return `Turbo Mode enabled. ${TURBO_BYPASS_DISCLOSURE}`;
40764
40802
  }
40765
40803
  }
40766
40804
  if (arg0 === "on") {
@@ -40783,7 +40821,7 @@ async function handleTurboCommand(directory, args, sessionID) {
40783
40821
  session.turboStrategy = "standard";
40784
40822
  session.leanTurboActive = false;
40785
40823
  session.leanTurboCurrentPhase = undefined;
40786
- return "Turbo Mode enabled";
40824
+ return `Turbo Mode enabled. ${TURBO_BYPASS_DISCLOSURE}`;
40787
40825
  }
40788
40826
  if (arg0 === "standard" && arg1 === "on") {
40789
40827
  if (isLeanActive) {
@@ -40793,7 +40831,7 @@ async function handleTurboCommand(directory, args, sessionID) {
40793
40831
  session.turboStrategy = "standard";
40794
40832
  session.leanTurboActive = false;
40795
40833
  session.leanTurboCurrentPhase = undefined;
40796
- return "Turbo Mode enabled (standard)";
40834
+ return `Turbo Mode enabled (standard). ${TURBO_BYPASS_DISCLOSURE}`;
40797
40835
  }
40798
40836
  if (arg0 === "lean" && arg1 === "on") {
40799
40837
  return enableLeanTurbo(session, directory, sessionID);
@@ -40856,7 +40894,7 @@ Epic Mode enabled \u2014 the architect will use the transparent decide-then-disp
40856
40894
  session.turboStrategy = "standard";
40857
40895
  session.leanTurboActive = false;
40858
40896
  session.leanTurboCurrentPhase = undefined;
40859
- return "Turbo Mode enabled";
40897
+ return `Turbo Mode enabled. ${TURBO_BYPASS_DISCLOSURE}`;
40860
40898
  }
40861
40899
  }
40862
40900
  function enableLeanTurbo(session, directory, sessionID) {
@@ -40894,7 +40932,7 @@ function enableLeanTurbo(session, directory, sessionID) {
40894
40932
  session.leanTurboActive = true;
40895
40933
  session.leanTurboCurrentPhase = undefined;
40896
40934
  return [
40897
- "Lean Turbo enabled",
40935
+ `Lean Turbo enabled. ${TURBO_BYPASS_DISCLOSURE} ` + `Per-lane: reviewer gates and file-lock conflict detection.`,
40898
40936
  `(maxParallelCoders=${maxParallelCoders}, conflict_policy=${conflictPolicy},`,
40899
40937
  `Full-Auto: ${fullAutoActive ? "active" : "inactive"})`
40900
40938
  ].join(" ");
@@ -41126,7 +41164,7 @@ function buildDetailedHelp(commandName, entry) {
41126
41164
  async function handleHelpCommand(ctx) {
41127
41165
  const targetCommand = ctx.args.join(" ");
41128
41166
  if (!targetCommand) {
41129
- const { buildHelpText } = await import("./index-zp330ss0.js");
41167
+ const { buildHelpText } = await import("./index-68fpa7ff.js");
41130
41168
  return buildHelpText();
41131
41169
  }
41132
41170
  const tokens = targetCommand.split(/\s+/);
@@ -41135,7 +41173,7 @@ async function handleHelpCommand(ctx) {
41135
41173
  return _internals62.buildDetailedHelp(resolved.key, resolved.entry);
41136
41174
  }
41137
41175
  const similar = _internals62.findSimilarCommands(targetCommand);
41138
- const { buildHelpText: fullHelp } = await import("./index-zp330ss0.js");
41176
+ const { buildHelpText: fullHelp } = await import("./index-68fpa7ff.js");
41139
41177
  if (similar.length > 0) {
41140
41178
  return `Command '/swarm ${targetCommand}' not found.
41141
41179
 
@@ -41274,7 +41312,7 @@ var COMMAND_REGISTRY = {
41274
41312
  },
41275
41313
  "guardrail explain": {
41276
41314
  handler: async (ctx) => {
41277
- const { handleGuardrailExplain } = await import("./guardrail-explain-m34vcgjg.js");
41315
+ const { handleGuardrailExplain } = await import("./guardrail-explain-6atsd4vr.js");
41278
41316
  return handleGuardrailExplain(ctx.directory, ctx.args);
41279
41317
  },
41280
41318
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -41284,7 +41322,7 @@ var COMMAND_REGISTRY = {
41284
41322
  },
41285
41323
  "guardrail-explain": {
41286
41324
  handler: async (ctx) => {
41287
- const { handleGuardrailExplain } = await import("./guardrail-explain-m34vcgjg.js");
41325
+ const { handleGuardrailExplain } = await import("./guardrail-explain-6atsd4vr.js");
41288
41326
  return handleGuardrailExplain(ctx.directory, ctx.args);
41289
41327
  },
41290
41328
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -41884,8 +41922,8 @@ Subcommands:
41884
41922
  args: "on, off, lean, standard, epic, status",
41885
41923
  details: `Toggles Turbo Mode for the current session. Supports three strategies:
41886
41924
 
41887
- ` + `**Standard turbo** \u2014 skips non-critical QA gates for faster iteration.
41888
- ` + `**Lean turbo** \u2014 parallel lane execution with per-lane reviewer gates and file-lock conflict detection.
41925
+ ` + `**Standard turbo** \u2014 ${TURBO_BYPASS_DISCLOSURE}
41926
+ ` + `**Lean turbo** \u2014 parallel lane execution with per-lane reviewer gates and file-lock conflict detection. ${TURBO_BYPASS_DISCLOSURE}
41889
41927
  ` + "**Epic** \u2014 additive overlay above Lean Turbo. Auto-decides per-plan parallel-vs-serial via the coupling coefficient `p` and three gates (p-threshold, hot-module, greenfield). When `/swarm turbo epic on` is selected, Lean Turbo is also enabled \u2014 Epic dispatches Lean Turbo when it promotes.\n" + `
41890
41928
  Subcommands:
41891
41929
  ` + ` turbo on \u2014 enable turbo (uses lean when config turbo.strategy is "lean", otherwise standard)
@@ -6,7 +6,7 @@ import {
6
6
  loadPluginConfigWithMeta,
7
7
  loadPluginConfigWithMetaAsync,
8
8
  resolveWorktreeIsolationConfig
9
- } from "./index-74xejn4v.js";
9
+ } from "./index-a1c9az5e.js";
10
10
  import {
11
11
  ApprovalEvidenceSchema,
12
12
  BaseEvidenceSchema,
@@ -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-69ttjjjs.js");
611
+ const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-06k0p1gs.js");
612
612
  await bumpKnowledgeConfidenceBatch(directory, deltas, options?.floorOptions);
613
613
  }
614
614
  return {
@@ -650,7 +650,7 @@ async function applyConfidenceFloorAction(directory, touched, options) {
650
650
  const recovered = touched.filter((e) => e.confidence > CONFIDENCE_FLOOR + FLOOR_EPSILON && e.confidence_floor_demoted);
651
651
  if (atFloor.length === 0 && recovered.length === 0)
652
652
  return;
653
- const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-jtr66wxz.js");
653
+ const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-kyqjv1f8.js");
654
654
  const rollups = await readKnowledgeCounterRollups(directory);
655
655
  const flagIds = new Set;
656
656
  for (const e of atFloor) {
@@ -717,11 +717,11 @@ async function applyConfidenceFloorAction(directory, touched, options) {
717
717
  });
718
718
  }
719
719
  if (action === "quarantine" && toQuarantine.length > 0) {
720
- const { quarantineEntry } = await import("./knowledge-validator-yn06rh13.js");
720
+ const { quarantineEntry } = await import("./knowledge-validator-42xjmcmh.js");
721
721
  const { KnowledgeConfigSchema } = await import("./schema-69z8w1ka.js");
722
722
  let config;
723
723
  try {
724
- const { loadPluginConfigWithMeta } = await import("./index-4b1e5m0d.js");
724
+ const { loadPluginConfigWithMeta } = await import("./index-16z6txq3.js");
725
725
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
726
726
  config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
727
727
  } catch {
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-1cxp3b5y.js";
4
+ } from "./index-y4ry07h8.js";
5
5
  import {
6
6
  handleGuardrailLog
7
7
  } from "./index-qzkcy22e.js";
@@ -83,28 +83,28 @@ import {
83
83
  handleWriteRetroCommand,
84
84
  normalizeSwarmCommandInput,
85
85
  resolveCommand
86
- } from "./index-d17kqe54.js";
86
+ } from "./index-0ff5cm9j.js";
87
87
  import"./index-dezgmvtw.js";
88
88
  import"./index-jt7hnr7q.js";
89
89
  import"./index-kk1scggc.js";
90
90
  import"./index-4905hd2m.js";
91
91
  import"./index-134d35c1.js";
92
92
  import"./index-6n2jpz7x.js";
93
- import"./index-gd5w3ef8.js";
94
- import"./index-0f45t7xy.js";
95
- import"./index-e315gwc9.js";
93
+ import"./index-yfzn5r9s.js";
94
+ import"./index-bcgfhxzv.js";
95
+ import"./index-cdx337js.js";
96
96
  import"./index-vxv732ex.js";
97
97
  import"./index-c8s9a3zh.js";
98
98
  import"./index-9ss2m4rs.js";
99
99
  import"./index-23zsx7dm.js";
100
- import"./index-yq4s3q43.js";
101
- import"./index-1htanqp1.js";
100
+ import"./index-kwnsatzq.js";
101
+ import"./index-mgrsx5hn.js";
102
102
  import"./index-rtry5xyf.js";
103
- import"./index-1012f47p.js";
104
- import"./index-gbnpz7rh.js";
103
+ import"./index-2yd75hms.js";
104
+ import"./index-2bnfwmk3.js";
105
105
  import"./index-ae75rja9.js";
106
106
  import"./index-q27bajqb.js";
107
- import"./index-74xejn4v.js";
107
+ import"./index-a1c9az5e.js";
108
108
  import"./index-k5jrywpr.js";
109
109
  import"./index-n832052r.js";
110
110
  import {
@@ -215,34 +215,63 @@ function parseConfigWithFallback(mergedRaw, rawUserConfig, failedResult, loadedF
215
215
  if (removed.length > 0) {
216
216
  const recovered = PluginConfigSchema.safeParse(cleaned);
217
217
  if (recovered.success) {
218
- advisoryWarn(`[opencode-swarm] Ignored ${removed.length} unrecognized config key(s): ${removed.join(", ")}. The rest of your configuration was preserved. Fix or remove these keys.`);
219
- return secure(recovered.data);
218
+ const warning = `Ignored ${removed.length} unrecognized config key(s): ${removed.join(", ")}. The rest of your configuration was preserved. Fix or remove these keys.`;
219
+ advisoryWarn(`[opencode-swarm] ${warning}`);
220
+ return {
221
+ config: secure(recovered.data),
222
+ recovery: "stripped_keys",
223
+ removedKeys: removed,
224
+ warnings: [warning]
225
+ };
220
226
  }
221
227
  }
222
228
  if (rawUserConfig) {
223
229
  const userSanitized = sanitizeSectionConfigs(rawUserConfig ?? {});
224
230
  const userParseResult = PluginConfigSchema.safeParse(userSanitized);
225
231
  if (userParseResult.success) {
226
- advisoryWarn("[opencode-swarm] Project config ignored due to validation errors. Using user config.");
227
- return secure(userParseResult.data);
232
+ const warning = "Project config ignored due to validation errors. Using user config.";
233
+ advisoryWarn(`[opencode-swarm] ${warning}`);
234
+ return {
235
+ config: secure(userParseResult.data),
236
+ recovery: "user_only",
237
+ removedKeys: [],
238
+ warnings: [warning]
239
+ };
228
240
  }
229
241
  const userStripped = stripUnrecognizedKeys(userSanitized, userParseResult.error);
230
242
  if (userStripped.removed.length > 0) {
231
243
  const userRecovered = PluginConfigSchema.safeParse(userStripped.cleaned);
232
244
  if (userRecovered.success) {
233
- advisoryWarn(`[opencode-swarm] Project config ignored; also ignored ${userStripped.removed.length} unrecognized user-config key(s): ${userStripped.removed.join(", ")}.`);
234
- return secure(userRecovered.data);
245
+ const warning = `Project config ignored; also ignored ${userStripped.removed.length} unrecognized user-config key(s): ${userStripped.removed.join(", ")}.`;
246
+ advisoryWarn(`[opencode-swarm] ${warning}`);
247
+ return {
248
+ config: secure(userRecovered.data),
249
+ recovery: "user_only",
250
+ removedKeys: userStripped.removed,
251
+ warnings: [warning]
252
+ };
235
253
  }
236
254
  }
237
255
  }
238
256
  const offending = stripUnrecognizedKeys(mergedRaw, result.error).removed;
257
+ const warnings = [];
239
258
  if (offending.length > 0) {
240
- advisoryWarn(`[opencode-swarm] Merged config validation failed. Unrecognized key(s): ${offending.join(", ")}.`);
259
+ const warning = `Merged config validation failed. Unrecognized key(s): ${offending.join(", ")}.`;
260
+ advisoryWarn(`[opencode-swarm] ${warning}`);
261
+ warnings.push(warning);
241
262
  } else {
242
263
  advisoryWarn("[opencode-swarm] Merged config validation failed:", formatZodIssues(result.error));
264
+ warnings.push("Merged config validation failed.");
243
265
  }
244
- advisoryWarn("[opencode-swarm] \u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.");
245
- return PluginConfigSchema.parse({ guardrails: { enabled: true } });
266
+ const securityWarning = "\u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.";
267
+ advisoryWarn(`[opencode-swarm] ${securityWarning}`);
268
+ warnings.push(securityWarning);
269
+ return {
270
+ config: PluginConfigSchema.parse({ guardrails: { enabled: true } }),
271
+ recovery: "guardrails_defaults",
272
+ removedKeys: offending,
273
+ warnings
274
+ };
246
275
  }
247
276
  function rawFullAutoLocked(raw) {
248
277
  if (!raw || typeof raw !== "object")
@@ -285,17 +314,67 @@ function loadPluginConfig(directory) {
285
314
  }
286
315
  return result.data;
287
316
  }
288
- return parseConfigWithFallback(mergedRaw, rawUserConfig, result, loadedFromFile, configHadErrors);
317
+ const { config } = parseConfigWithFallback(mergedRaw, rawUserConfig, result, loadedFromFile, configHadErrors);
318
+ return config;
289
319
  }
290
320
  function loadPluginConfigWithMeta(directory) {
291
321
  const userConfigPath = path.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
292
322
  const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
293
323
  const userResult = loadRawConfigFromPath(userConfigPath);
294
324
  const projectResult = loadRawConfigFromPath(projectConfigPath);
325
+ const rawUserConfig = userResult.config;
326
+ const rawProjectConfig = projectResult.config;
295
327
  const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
296
328
  const configHadErrors = userResult.hadError || projectResult.hadError;
297
- const config = loadPluginConfig(directory);
298
- return { config, loadedFromFile, configHadErrors };
329
+ let mergedRaw = rawUserConfig ?? {};
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);
370
+ return {
371
+ config,
372
+ loadedFromFile,
373
+ configHadErrors,
374
+ recovery,
375
+ removedKeys,
376
+ warnings
377
+ };
299
378
  }
300
379
  async function loadRawConfigFromPathAsync(configPath) {
301
380
  try {
@@ -345,12 +424,24 @@ function reduceParsedConfig(rawUserConfig, rawProjectConfig, loadedFromFile, con
345
424
  const result = PluginConfigSchema.safeParse(mergedRaw);
346
425
  if (result.success) {
347
426
  if (loadedFromFile && configHadErrors) {
348
- return PluginConfigSchema.parse({
349
- ...mergedRaw,
350
- guardrails: { enabled: true }
351
- });
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
+ };
352
438
  }
353
- return result.data;
439
+ return {
440
+ config: result.data,
441
+ recovery: "none",
442
+ removedKeys: [],
443
+ warnings: []
444
+ };
354
445
  }
355
446
  return parseConfigWithFallback(mergedRaw, rawUserConfig, result, loadedFromFile, configHadErrors);
356
447
  }
@@ -363,8 +454,15 @@ async function loadPluginConfigWithMetaAsync(directory) {
363
454
  ]);
364
455
  const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
365
456
  const configHadErrors = userResult.hadError || projectResult.hadError;
366
- const config = reduceParsedConfig(userResult.config, projectResult.config, loadedFromFile, configHadErrors);
367
- return { config, loadedFromFile, configHadErrors };
457
+ const { config, recovery, removedKeys, warnings } = reduceParsedConfig(userResult.config, projectResult.config, loadedFromFile, configHadErrors);
458
+ return {
459
+ config,
460
+ loadedFromFile,
461
+ configHadErrors,
462
+ recovery,
463
+ removedKeys,
464
+ warnings
465
+ };
368
466
  }
369
467
  function loadAgentPrompt(agentName) {
370
468
  const promptsDir = path.join(getUserConfigDir(), "opencode", PROMPTS_DIR_NAME);
@@ -6,13 +6,13 @@ import {
6
6
  resolveSwarmKnowledgePath,
7
7
  transactKnowledge,
8
8
  wordBigrams
9
- } from "./index-1012f47p.js";
9
+ } from "./index-2yd75hms.js";
10
10
  import {
11
11
  countEntryContradictionsInWindow,
12
12
  countEntryViolationsInWindow,
13
13
  readKnowledgeEvents,
14
14
  recordKnowledgeEvent
15
- } from "./index-gbnpz7rh.js";
15
+ } from "./index-2bnfwmk3.js";
16
16
  import {
17
17
  init_knowledge_types,
18
18
  isActiveStatus
@@ -190,11 +190,11 @@ async function maybeQuarantineOnContradiction(directory, entryId, threshold, win
190
190
  alreadyInactive: true
191
191
  };
192
192
  }
193
- const { quarantineEntry } = await import("./knowledge-validator-yn06rh13.js");
193
+ const { quarantineEntry } = await import("./knowledge-validator-42xjmcmh.js");
194
194
  let policyConfig;
195
195
  try {
196
196
  const { KnowledgeConfigSchema } = await import("./schema-69z8w1ka.js");
197
- const { loadPluginConfigWithMeta } = await import("./index-4b1e5m0d.js");
197
+ const { loadPluginConfigWithMeta } = await import("./index-16z6txq3.js");
198
198
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
199
199
  policyConfig = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
200
200
  } catch {