opencode-swarm 7.128.0 → 7.129.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 (29) hide show
  1. package/dist/cli/{curation-policy-82czah39.js → curation-policy-qwj9yxvp.js} +2 -2
  2. package/dist/cli/{curator-llm-factory-rz4cbq28.js → curator-llm-factory-j35jd864.js} +9 -9
  3. package/dist/cli/{curator-x5dzf1p7.js → curator-wywrxn1j.js} +9 -9
  4. package/dist/cli/{guardrail-explain-fwvxteqe.js → guardrail-explain-850vrn06.js} +10 -10
  5. package/dist/cli/{hive-promoter-z8gc80zq.js → hive-promoter-w2hf8w69.js} +9 -9
  6. package/dist/cli/{index-nmedh7bw.js → index-3a0dthh5.js} +10 -10
  7. package/dist/cli/{index-edv27z4p.js → index-4gsqjp9p.js} +1 -1
  8. package/dist/cli/{index-c4mcheyz.js → index-9s0ztmmz.js} +3 -3
  9. package/dist/cli/{index-ns62nv6t.js → index-b2m6mtde.js} +2 -2
  10. package/dist/cli/{index-1mwdhq2p.js → index-d4zjjtqs.js} +1 -1
  11. package/dist/cli/{index-hv2p03f3.js → index-dbn9d4kj.js} +237 -4
  12. package/dist/cli/{index-npycj2tr.js → index-e3xtpsmf.js} +26 -26
  13. package/dist/cli/{index-72envp1b.js → index-gy9h08cg.js} +3 -3
  14. package/dist/cli/{index-ff3j65em.js → index-her5rv14.js} +4 -4
  15. package/dist/cli/{index-3ntrn97w.js → index-jmsnbct2.js} +1 -1
  16. package/dist/cli/{index-rczj39pc.js → index-rmyxgxpj.js} +1 -1
  17. package/dist/cli/{index-gn62e04k.js → index-zty6p8ps.js} +1 -1
  18. package/dist/cli/index.js +9 -9
  19. package/dist/cli/{knowledge-escalator-b3k4b8pk.js → knowledge-escalator-h6jhw20r.js} +3 -3
  20. package/dist/cli/{knowledge-events-4z5rkefv.js → knowledge-events-wtyjkcg0.js} +1 -1
  21. package/dist/cli/{knowledge-store-c0t16yr4.js → knowledge-store-a1xr70yg.js} +1 -1
  22. package/dist/cli/{knowledge-validator-cs33ws57.js → knowledge-validator-afpv79e3.js} +4 -4
  23. package/dist/cli/{scan-cursor-rgnarf67.js → scan-cursor-hh6gdzrg.js} +2 -2
  24. package/dist/cli/{skill-generator-e8c2r816.js → skill-generator-dmshq3p6.js} +5 -5
  25. package/dist/config/loader-recovery.d.ts +95 -0
  26. package/dist/config/loader.d.ts +5 -1
  27. package/dist/config/sanitize-malformed-values.d.ts +53 -0
  28. package/dist/index.js +7 -7
  29. package/package.json +1 -1
@@ -94,15 +94,15 @@ import {
94
94
  retireSkill,
95
95
  selectCandidateEntries,
96
96
  syncBundledProjectSkillsIfMissingAsync
97
- } from "./index-c4mcheyz.js";
97
+ } from "./index-9s0ztmmz.js";
98
98
  import {
99
99
  readRecentEscalations
100
- } from "./index-ff3j65em.js";
100
+ } from "./index-her5rv14.js";
101
101
  import {
102
102
  alreadyCuratedThisGeneration,
103
103
  claimNextScanBatch,
104
104
  resolveCohortId
105
- } from "./index-gn62e04k.js";
105
+ } from "./index-zty6p8ps.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-ns62nv6t.js";
138
+ } from "./index-b2m6mtde.js";
139
139
  import {
140
140
  authorizeCuration,
141
141
  buildConfigFingerprintInput
142
- } from "./index-3ntrn97w.js";
142
+ } from "./index-jmsnbct2.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-72envp1b.js";
172
+ } from "./index-gy9h08cg.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-1mwdhq2p.js";
182
+ } from "./index-d4zjjtqs.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-hv2p03f3.js";
204
+ } from "./index-dbn9d4kj.js";
205
205
  import {
206
206
  RetrospectiveEvidenceSchema
207
207
  } from "./index-k5jrywpr.js";
@@ -10987,7 +10987,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
10987
10987
  }
10988
10988
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
10989
10989
  try {
10990
- const skillModule = await import("./skill-generator-e8c2r816.js");
10990
+ const skillModule = await import("./skill-generator-dmshq3p6.js");
10991
10991
  for (const cand of skillCandidates) {
10992
10992
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
10993
10993
  continue;
@@ -11324,7 +11324,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
11324
11324
  } catch {}
11325
11325
  }
11326
11326
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
11327
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-b3k4b8pk.js");
11327
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-h6jhw20r.js");
11328
11328
  for (const { id } of contradictedEntries) {
11329
11329
  try {
11330
11330
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -12123,7 +12123,7 @@ async function runCuratorPostMortem(directory, options = {}) {
12123
12123
  warnings.push("Failed to collect knowledge summary.");
12124
12124
  }
12125
12125
  try {
12126
- const { getScanStatus } = await import("./scan-cursor-rgnarf67.js");
12126
+ const { getScanStatus } = await import("./scan-cursor-hh6gdzrg.js");
12127
12127
  const scanStatus = await getScanStatus(directory);
12128
12128
  if (scanStatus.remaining_estimate > 0) {
12129
12129
  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.`);
@@ -12297,7 +12297,7 @@ var _internals15 = {
12297
12297
  loadDefaultKnowledgeConfig: async (directory) => {
12298
12298
  const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-2x7wsb0n.js");
12299
12299
  try {
12300
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-edv27z4p.js");
12300
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4gsqjp9p.js");
12301
12301
  const loaded = loadPluginConfigWithMeta2(directory);
12302
12302
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
12303
12303
  } catch {
@@ -12305,11 +12305,11 @@ var _internals15 = {
12305
12305
  }
12306
12306
  },
12307
12307
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
12308
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-x5dzf1p7.js");
12308
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-wywrxn1j.js");
12309
12309
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
12310
12310
  },
12311
12311
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
12312
- const { checkHivePromotions } = await import("./hive-promoter-z8gc80zq.js");
12312
+ const { checkHivePromotions } = await import("./hive-promoter-w2hf8w69.js");
12313
12313
  return checkHivePromotions(entries, knowledgeConfig, directory);
12314
12314
  },
12315
12315
  applyProposalTriage: async (directory, triage) => {
@@ -12318,7 +12318,7 @@ var _internals15 = {
12318
12318
  activateProposal,
12319
12319
  listSkills: listSkills2,
12320
12320
  sanitizeSlug
12321
- } = await import("./skill-generator-e8c2r816.js");
12321
+ } = await import("./skill-generator-dmshq3p6.js");
12322
12322
  const result = {
12323
12323
  approved: [],
12324
12324
  rejected: [],
@@ -14845,7 +14845,7 @@ function hashContent(content) {
14845
14845
  async function loadConfigForPolicyCurator(directory) {
14846
14846
  const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-2x7wsb0n.js");
14847
14847
  try {
14848
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-edv27z4p.js");
14848
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4gsqjp9p.js");
14849
14849
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
14850
14850
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
14851
14851
  } catch {
@@ -20176,8 +20176,8 @@ var _internals28 = {
20176
20176
  loadCuratorDeps: async () => {
20177
20177
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
20178
20178
  import("./schema-2x7wsb0n.js"),
20179
- import("./curator-x5dzf1p7.js"),
20180
- import("./curator-llm-factory-rz4cbq28.js")
20179
+ import("./curator-wywrxn1j.js"),
20180
+ import("./curator-llm-factory-j35jd864.js")
20181
20181
  ]);
20182
20182
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
20183
20183
  }
@@ -20676,7 +20676,7 @@ import { fileURLToPath } from "url";
20676
20676
  // package.json
20677
20677
  var package_default = {
20678
20678
  name: "opencode-swarm",
20679
- version: "7.128.0",
20679
+ version: "7.129.0",
20680
20680
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
20681
20681
  main: "dist/index.js",
20682
20682
  types: "dist/index.d.ts",
@@ -21198,7 +21198,7 @@ async function computeCurationDiagnostics(directory, entries) {
21198
21198
  let scanCompleted = false;
21199
21199
  let scanRemaining = 0;
21200
21200
  try {
21201
- const { getScanStatus } = await import("./scan-cursor-rgnarf67.js");
21201
+ const { getScanStatus } = await import("./scan-cursor-hh6gdzrg.js");
21202
21202
  const status = await getScanStatus(directory);
21203
21203
  scanGeneration = status.generation;
21204
21204
  scanCompleted = status.completed;
@@ -21211,14 +21211,14 @@ async function computeCurationDiagnostics(directory, entries) {
21211
21211
  const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-2x7wsb0n.js");
21212
21212
  let config;
21213
21213
  try {
21214
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-edv27z4p.js");
21214
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4gsqjp9p.js");
21215
21215
  const loaded = loadPluginConfigWithMeta2(directory);
21216
21216
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
21217
21217
  } catch {
21218
21218
  config = KnowledgeConfigSchema2.parse({});
21219
21219
  }
21220
21220
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
21221
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-82czah39.js");
21221
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-qwj9yxvp.js");
21222
21222
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
21223
21223
  const cohortFp = await readCohortConfigFingerprint(directory);
21224
21224
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -41238,7 +41238,7 @@ function buildDetailedHelp(commandName, entry) {
41238
41238
  async function handleHelpCommand(ctx) {
41239
41239
  const targetCommand = ctx.args.join(" ");
41240
41240
  if (!targetCommand) {
41241
- const { buildHelpText } = await import("./index-nmedh7bw.js");
41241
+ const { buildHelpText } = await import("./index-3a0dthh5.js");
41242
41242
  return buildHelpText();
41243
41243
  }
41244
41244
  const tokens = targetCommand.split(/\s+/);
@@ -41247,7 +41247,7 @@ async function handleHelpCommand(ctx) {
41247
41247
  return _internals63.buildDetailedHelp(resolved.key, resolved.entry);
41248
41248
  }
41249
41249
  const similar = _internals63.findSimilarCommands(targetCommand);
41250
- const { buildHelpText: fullHelp } = await import("./index-nmedh7bw.js");
41250
+ const { buildHelpText: fullHelp } = await import("./index-3a0dthh5.js");
41251
41251
  if (similar.length > 0) {
41252
41252
  return `Command '/swarm ${targetCommand}' not found.
41253
41253
 
@@ -41386,7 +41386,7 @@ var COMMAND_REGISTRY = {
41386
41386
  },
41387
41387
  "guardrail explain": {
41388
41388
  handler: async (ctx) => {
41389
- const { handleGuardrailExplain } = await import("./guardrail-explain-fwvxteqe.js");
41389
+ const { handleGuardrailExplain } = await import("./guardrail-explain-850vrn06.js");
41390
41390
  return handleGuardrailExplain(ctx.directory, ctx.args);
41391
41391
  },
41392
41392
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -41396,7 +41396,7 @@ var COMMAND_REGISTRY = {
41396
41396
  },
41397
41397
  "guardrail-explain": {
41398
41398
  handler: async (ctx) => {
41399
- const { handleGuardrailExplain } = await import("./guardrail-explain-fwvxteqe.js");
41399
+ const { handleGuardrailExplain } = await import("./guardrail-explain-850vrn06.js");
41400
41400
  return handleGuardrailExplain(ctx.directory, ctx.args);
41401
41401
  },
41402
41402
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -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-4z5rkefv.js");
653
+ const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-wtyjkcg0.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-cs33ws57.js");
720
+ const { quarantineEntry } = await import("./knowledge-validator-afpv79e3.js");
721
721
  const { KnowledgeConfigSchema } = await import("./schema-2x7wsb0n.js");
722
722
  let config;
723
723
  try {
724
- const { loadPluginConfigWithMeta } = await import("./index-edv27z4p.js");
724
+ const { loadPluginConfigWithMeta } = await import("./index-4gsqjp9p.js");
725
725
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
726
726
  config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
727
727
  } catch {
@@ -6,13 +6,13 @@ import {
6
6
  resolveSwarmKnowledgePath,
7
7
  transactKnowledge,
8
8
  wordBigrams
9
- } from "./index-72envp1b.js";
9
+ } from "./index-gy9h08cg.js";
10
10
  import {
11
11
  countEntryContradictionsInWindow,
12
12
  countEntryViolationsInWindow,
13
13
  readKnowledgeEvents,
14
14
  recordKnowledgeEvent
15
- } from "./index-1mwdhq2p.js";
15
+ } from "./index-d4zjjtqs.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-cs33ws57.js");
193
+ const { quarantineEntry } = await import("./knowledge-validator-afpv79e3.js");
194
194
  let policyConfig;
195
195
  try {
196
196
  const { KnowledgeConfigSchema } = await import("./schema-2x7wsb0n.js");
197
- const { loadPluginConfigWithMeta } = await import("./index-edv27z4p.js");
197
+ const { loadPluginConfigWithMeta } = await import("./index-4gsqjp9p.js");
198
198
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
199
199
  policyConfig = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
200
200
  } catch {
@@ -4,7 +4,7 @@ import {
4
4
  } from "./index-rtry5xyf.js";
5
5
  import {
6
6
  readKnowledgeEvents
7
- } from "./index-1mwdhq2p.js";
7
+ } from "./index-d4zjjtqs.js";
8
8
  import {
9
9
  isLinked,
10
10
  readLinkPointer,
@@ -12,7 +12,7 @@ import {
12
12
  detectPosixWrites,
13
13
  detectWindowsWrites,
14
14
  resolveWriteTargets
15
- } from "./index-npycj2tr.js";
15
+ } from "./index-e3xtpsmf.js";
16
16
  import {
17
17
  checkFileAuthority,
18
18
  classifyFile,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  readKnowledge,
4
4
  transactKnowledge
5
- } from "./index-72envp1b.js";
5
+ } from "./index-gy9h08cg.js";
6
6
  import {
7
7
  resolveKnowledgeStoreDir
8
8
  } from "./index-q27bajqb.js";
package/dist/cli/index.js CHANGED
@@ -7,28 +7,28 @@ import {
7
7
  getPluginLockFilePaths,
8
8
  package_default,
9
9
  resolveCommand
10
- } from "./index-npycj2tr.js";
10
+ } from "./index-e3xtpsmf.js";
11
11
  import"./index-v4n224r1.js";
12
12
  import"./index-cpssctv1.js";
13
13
  import"./index-kk1scggc.js";
14
14
  import"./index-4905hd2m.js";
15
15
  import"./index-134d35c1.js";
16
16
  import"./index-6n2jpz7x.js";
17
- import"./index-c4mcheyz.js";
18
- import"./index-ff3j65em.js";
19
- import"./index-gn62e04k.js";
17
+ import"./index-9s0ztmmz.js";
18
+ import"./index-her5rv14.js";
19
+ import"./index-zty6p8ps.js";
20
20
  import"./index-vxv732ex.js";
21
21
  import"./index-c8s9a3zh.js";
22
22
  import"./index-9ss2m4rs.js";
23
23
  import"./index-23zsx7dm.js";
24
- import"./index-ns62nv6t.js";
25
- import"./index-3ntrn97w.js";
24
+ import"./index-b2m6mtde.js";
25
+ import"./index-jmsnbct2.js";
26
26
  import"./index-rtry5xyf.js";
27
- import"./index-72envp1b.js";
28
- import"./index-1mwdhq2p.js";
27
+ import"./index-gy9h08cg.js";
28
+ import"./index-d4zjjtqs.js";
29
29
  import"./index-ae75rja9.js";
30
30
  import"./index-q27bajqb.js";
31
- import"./index-hv2p03f3.js";
31
+ import"./index-dbn9d4kj.js";
32
32
  import"./index-k5jrywpr.js";
33
33
  import"./index-n832052r.js";
34
34
  import {
@@ -8,9 +8,9 @@ import {
8
8
  maybeEscalateOnViolation,
9
9
  maybeQuarantineOnContradiction,
10
10
  readRecentEscalations
11
- } from "./index-ff3j65em.js";
12
- import"./index-72envp1b.js";
13
- import"./index-1mwdhq2p.js";
11
+ } from "./index-her5rv14.js";
12
+ import"./index-gy9h08cg.js";
13
+ import"./index-d4zjjtqs.js";
14
14
  import"./index-ae75rja9.js";
15
15
  import"./index-q27bajqb.js";
16
16
  import"./index-bk5tah7q.js";
@@ -26,7 +26,7 @@ import {
26
26
  resolveKnowledgeCounterBaselinePath,
27
27
  resolveKnowledgeEventsPath,
28
28
  resolveLegacyApplicationLogPath
29
- } from "./index-1mwdhq2p.js";
29
+ } from "./index-d4zjjtqs.js";
30
30
  import"./index-ae75rja9.js";
31
31
  import"./index-q27bajqb.js";
32
32
  import"./index-zgwm4ryv.js";
@@ -40,7 +40,7 @@ import {
40
40
  transactKnowledge,
41
41
  transactKnowledgeWithCas,
42
42
  wordBigrams
43
- } from "./index-72envp1b.js";
43
+ } from "./index-gy9h08cg.js";
44
44
  import {
45
45
  resolveHiveDataDir
46
46
  } from "./index-ae75rja9.js";
@@ -23,11 +23,11 @@ import {
23
23
  validateLesson,
24
24
  validateSkillCandidatePath,
25
25
  validateSkillPath
26
- } from "./index-ns62nv6t.js";
27
- import"./index-3ntrn97w.js";
26
+ } from "./index-b2m6mtde.js";
27
+ import"./index-jmsnbct2.js";
28
28
  import"./index-rtry5xyf.js";
29
- import"./index-72envp1b.js";
30
- import"./index-1mwdhq2p.js";
29
+ import"./index-gy9h08cg.js";
30
+ import"./index-d4zjjtqs.js";
31
31
  import"./index-ae75rja9.js";
32
32
  import"./index-q27bajqb.js";
33
33
  import"./index-bk5tah7q.js";
@@ -4,8 +4,8 @@ import {
4
4
  alreadyCuratedThisGeneration,
5
5
  claimNextScanBatch,
6
6
  getScanStatus
7
- } from "./index-gn62e04k.js";
8
- import"./index-72envp1b.js";
7
+ } from "./index-zty6p8ps.js";
8
+ import"./index-gy9h08cg.js";
9
9
  import"./index-ae75rja9.js";
10
10
  import"./index-q27bajqb.js";
11
11
  import"./index-bk5tah7q.js";
@@ -33,12 +33,12 @@ import {
33
33
  sanitizeSlug,
34
34
  selectCandidateEntries,
35
35
  writeEvalStub
36
- } from "./index-c4mcheyz.js";
37
- import"./index-ns62nv6t.js";
38
- import"./index-3ntrn97w.js";
36
+ } from "./index-9s0ztmmz.js";
37
+ import"./index-b2m6mtde.js";
38
+ import"./index-jmsnbct2.js";
39
39
  import"./index-rtry5xyf.js";
40
- import"./index-72envp1b.js";
41
- import"./index-1mwdhq2p.js";
40
+ import"./index-gy9h08cg.js";
41
+ import"./index-d4zjjtqs.js";
42
42
  import"./index-ae75rja9.js";
43
43
  import"./index-q27bajqb.js";
44
44
  import"./index-bk5tah7q.js";
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Config loader recovery persistence module.
3
+ *
4
+ * Persists recovery metadata emitted by the config loader so that:
5
+ * - `/swarm config doctor` can surface stale recovery artifacts
6
+ * (left by a prior process that crashed before cleanup).
7
+ * - Post-init flush (via `flushPendingLoaderRecovery`) can record
8
+ * recovery warnings without blocking plugin init.
9
+ * - Stale artifacts from older loads are cleaned up atomically
10
+ * when a newer load completes successfully (SC-002.3).
11
+ *
12
+ * Conflict resolution: every completed load writes a recovery artifact
13
+ * tagged with the tuple `{loadStartedAt, pid, inProcessCounter}`. When
14
+ * an artifact already exists, the new load wins iff its tuple is
15
+ * numerically greater than the existing one (component-wise comparison).
16
+ * This prevents a slower or earlier process from overwriting a newer
17
+ * recovery result.
18
+ *
19
+ * Artifact format (JSON):
20
+ * ```json
21
+ * {
22
+ * "loadStartedAt": number,
23
+ * "pid": number,
24
+ * "inProcessCounter": number,
25
+ * "sources": string[],
26
+ * "fingerprint": string,
27
+ * "warnings": RecoveryWarning[]
28
+ * }
29
+ * ```
30
+ *
31
+ * Lives under `src/config/` alongside `loader.ts` so the loader can
32
+ * import it without cross-module dependency violations.
33
+ */
34
+ import * as fsPromises from 'node:fs/promises';
35
+ import { bunWrite } from '../utils/bun-compat.js';
36
+ import type { RecoveryWarning } from './sanitize-malformed-values.js';
37
+ /** Shape of the on-disk recovery artifact. */
38
+ export interface LoaderRecoveryArtifact {
39
+ /** Date.now() when the config load started. */
40
+ loadStartedAt: number;
41
+ /** process.pid of the loading process. */
42
+ pid: number;
43
+ /** Monotonic per-process counter for same-process disambiguation. */
44
+ inProcessCounter: number;
45
+ /** Sorted source paths that contributed to the config merge. */
46
+ sources: string[];
47
+ /** SHA-256 fingerprint of the merged raw config. */
48
+ fingerprint: string;
49
+ /** Recovery warnings from the load (empty for clean loads). */
50
+ warnings: RecoveryWarning[];
51
+ }
52
+ /**
53
+ * Input shape accepted by the public API.
54
+ * Matches `LoadPluginConfigWithRecoveryResult.pendingPersistence`
55
+ * from `loader.ts`.
56
+ */
57
+ export type PendingLoaderRecoveryData = Omit<LoaderRecoveryArtifact, 'warnings'> & {
58
+ warnings: RecoveryWarning[];
59
+ };
60
+ /**
61
+ * Test-only dependency-injection seam — replaces `fsPromises.readFile`
62
+ * and `bunWrite` so tests can exercise failure paths without
63
+ * `mock.module` leakage (AGENTS.md §7).
64
+ */
65
+ export declare const _internals: {
66
+ readFile: typeof fsPromises.readFile;
67
+ write: typeof bunWrite;
68
+ };
69
+ /**
70
+ * Persist loader recovery data to `<directory>/.swarm/advisories/loader-recovery.json`.
71
+ *
72
+ * Every completed load atomically writes the artifact under deterministic
73
+ * conflict resolution: the new load wins iff its `{loadStartedAt, pid,
74
+ * inProcessCounter}` tuple is numerically greater than the existing artifact's.
75
+ * Clean loads (no recovery warnings) write `warnings: []`, which serves as
76
+ * the SC-002.3 stale-artifact cleanup signal.
77
+ *
78
+ * Failures (filesystem errors, permission issues) are logged via
79
+ * `advisoryWarn` and never thrown — this is best-effort persistence.
80
+ *
81
+ * @param directory - Project root directory (the `.swarm/` parent).
82
+ * @param data - Recovery data from the loader's `pendingPersistence`.
83
+ */
84
+ export declare function persistLoaderRecovery(directory: string, data: PendingLoaderRecoveryData): Promise<void>;
85
+ /**
86
+ * Synchronous wrapper that defers `persistLoaderRecovery` via `queueMicrotask`.
87
+ *
88
+ * This is designed for the post-init flush path (task 1.5) where the caller
89
+ * must not await the write — the write is fire-and-forget, with errors
90
+ * routed to `advisoryWarn` inside `persistLoaderRecovery`.
91
+ *
92
+ * @param directory - Project root directory (the `.swarm/` parent).
93
+ * @param pendingData - Recovery data from the loader's `pendingPersistence`.
94
+ */
95
+ export declare function flushPendingLoaderRecovery(directory: string, pendingData: PendingLoaderRecoveryData): void;
@@ -24,10 +24,14 @@ export declare function formatZodIssues(error: z.ZodError): string;
24
24
  * the remaining configuration was preserved.
25
25
  * 'user_only' – project config was discarded (failed validation and
26
26
  * targeted recovery); user config alone was used.
27
+ * 'sanitized_values' – merged and user configs both failed, but recursive
28
+ * malformed-value recovery (step 7b, issue #1690)
29
+ * dropped the smallest invalid leaves/sections so the
30
+ * remaining valid configuration could load.
27
31
  * 'guardrails_defaults'– neither merged nor user config was recoverable;
28
32
  * fell back to fail-secure guardrails-only defaults.
29
33
  */
30
- export type ConfigRecovery = 'none' | 'stripped_keys' | 'user_only' | 'guardrails_defaults';
34
+ export type ConfigRecovery = 'none' | 'stripped_keys' | 'user_only' | 'sanitized_values' | 'guardrails_defaults';
31
35
  /** Full result from the shared config-build core. */
32
36
  export type ConfigBuildResult = {
33
37
  config: PluginConfig;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Fixed-point recovery helper for malformed config values.
3
+ *
4
+ * Given a Zod schema and a raw config object, this module iteratively
5
+ * removes malformed fields/sections until the config validates cleanly.
6
+ * It uses ONLY `safeParse` + `issue.path`/`issue.code`/`issue.keys` as
7
+ * signals — no schema introspection (`_def`, `.shape`, `instanceof` along
8
+ * paths), making it robust across Zod versions (v3 and v4+).
9
+ *
10
+ * Algorithm (SME-designed fixed-point):
11
+ * 1. Fast path: if `safeParse` succeeds, return the original reference
12
+ * (no clone cost on the happy path).
13
+ * 2. Deep-clone the input exactly once.
14
+ * 3. Loop: parse → build leaf drop-set from issue paths → remove deepest
15
+ * leaves first → re-parse. If no new leaves found but fresh issues
16
+ * remain, escalate to nearest non-removed ancestor. If still stuck,
17
+ * drop entire implicated top-level sections.
18
+ * 4. Terminate when parse succeeds or fuel is exhausted.
19
+ * 5. Emit ancestor-suppressed, deterministically-ordered warnings.
20
+ *
21
+ * This is a PURE function — no side effects, no I/O, no logging.
22
+ */
23
+ import type { z } from 'zod';
24
+ /** Dotted path identifying the dropped unit, e.g. "council.enabled" or "pr_monitor". */
25
+ export interface RecoveryWarning {
26
+ section: string;
27
+ /** Currently always 'warn'; reserved for future severity levels. */
28
+ severity: 'warn';
29
+ /** Human-readable description of what was dropped and why. */
30
+ message: string;
31
+ /** Full Zod error path if available (for debugging / downstream use). */
32
+ path?: string;
33
+ }
34
+ export interface SanitizeResult {
35
+ /** The recovered config object. Keys omitted here will be filled by Zod defaults
36
+ * at parse time — callers should re-parse this through the schema. */
37
+ config: Record<string, unknown>;
38
+ /** Warnings for every field or section that was dropped during recovery. */
39
+ recoveryWarnings: RecoveryWarning[];
40
+ }
41
+ /**
42
+ * Attempt to recover a malformed config by iteratively dropping invalid
43
+ * values until the config validates. This is a generic helper that works
44
+ * with any Zod schema and avoids all schema introspection.
45
+ *
46
+ * The returned `config` is the cleaned raw config — callers should pass it
47
+ * through `schema.parse()` to get fully typed output with defaults applied.
48
+ *
49
+ * @param schema - The Zod schema to validate against.
50
+ * @param rawConfig - The raw parsed-config object (not yet Zod-validated).
51
+ * @returns The cleaned config plus any warnings emitted during recovery.
52
+ */
53
+ export declare function sanitizeMalformedValues(schema: z.ZodTypeAny, rawConfig: Record<string, unknown>): SanitizeResult;