opencode-swarm 7.107.3 → 7.107.5

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 (62) hide show
  1. package/.opencode/skills/consult/SKILL.md +10 -0
  2. package/.opencode/skills/council/SKILL.md +10 -0
  3. package/.opencode/skills/engineering-conventions/SKILL.md +20 -0
  4. package/README.md +2 -2
  5. package/dist/agents/agent-output-schema.d.ts +1 -1
  6. package/dist/cli/{config-doctor-cntnpyvj.js → config-doctor-kdq3vae4.js} +3 -2
  7. package/dist/cli/{curator-1nr4qszq.js → curator-k9swkynp.js} +17 -12
  8. package/dist/cli/{curator-llm-factory-x9tk7e6m.js → curator-llm-factory-ed67kywr.js} +17 -12
  9. package/dist/cli/{dispatch-e4ejrsz8.js → dispatch-anmxxhen.js} +56 -13
  10. package/dist/cli/{evidence-summary-service-9r28ds8t.js → evidence-summary-service-6zsgw7x7.js} +3 -3
  11. package/dist/cli/{gate-evidence-ywys9vfs.js → gate-evidence-pgr7d942.js} +2 -2
  12. package/dist/cli/{guardrail-explain-etdrhd4d.js → guardrail-explain-vd6da30t.js} +18 -13
  13. package/dist/cli/{guardrail-log-2rns4g6d.js → guardrail-log-fjypsmek.js} +4 -3
  14. package/dist/cli/{hive-promoter-j4e6rfa6.js → hive-promoter-gh0nva5c.js} +17 -12
  15. package/dist/cli/{index-r8f89sm9.js → index-0kxc7t16.js} +2 -1
  16. package/dist/cli/{index-tgtmbf3r.js → index-4vsgp5a8.js} +1 -1
  17. package/dist/cli/{index-kzfkggjx.js → index-6h82c2h0.js} +28 -11
  18. package/dist/cli/index-bfwt3abw.js +14 -0
  19. package/dist/cli/{index-9wstcavp.js → index-bpgqbwmf.js} +115 -1019
  20. package/dist/cli/index-bq8kd9r9.js +199 -0
  21. package/dist/cli/index-dfdg4ws5.js +741 -0
  22. package/dist/cli/{index-w15984gg.js → index-jrka8jd4.js} +2 -2
  23. package/dist/cli/index-kxm3bdjh.js +631 -0
  24. package/dist/cli/index-n1sptn1w.js +147 -0
  25. package/dist/cli/{index-2560cctg.js → index-pchpahdf.js} +11 -0
  26. package/dist/cli/{index-cyzzdbvw.js → index-vzq4h90s.js} +354 -116
  27. package/dist/cli/{index-502f6np6.js → index-w1tvqh4x.js} +22 -17
  28. package/dist/cli/{index-esg1554h.js → index-wvxhynxq.js} +1 -1
  29. package/dist/cli/{index-8w4d325g.js → index-xg18az81.js} +61 -22
  30. package/dist/cli/{index-f7nma02k.js → index-xmarctsf.js} +137 -175
  31. package/dist/cli/{index-m1xjr58n.js → index-zej8cy0j.js} +1 -1
  32. package/dist/cli/index.js +18 -13
  33. package/dist/cli/knowledge-escalator-3sgwrgy9.js +32 -0
  34. package/dist/cli/knowledge-events-kfc6xmkw.js +62 -0
  35. package/dist/cli/{knowledge-store-tsa8ezka.js → knowledge-store-kyacem71.js} +3 -1
  36. package/dist/cli/knowledge-validator-ez3ws8ef.js +57 -0
  37. package/dist/cli/{pr-subscriptions-0dpn4epk.js → pr-subscriptions-bpvazmsw.js} +2 -2
  38. package/dist/cli/{schema-vw2ffhe9.js → schema-x0ekqzvs.js} +2 -1
  39. package/dist/cli/{skill-generator-y6mmq8n5.js → skill-generator-x83re96d.js} +6 -2
  40. package/dist/commands/knowledge.d.ts +5 -1
  41. package/dist/commands/registry.d.ts +2 -2
  42. package/dist/config/evidence-schema.d.ts +9 -9
  43. package/dist/config/schema.d.ts +42 -12
  44. package/dist/hooks/knowledge-curator.d.ts +27 -0
  45. package/dist/hooks/knowledge-escalator.d.ts +16 -0
  46. package/dist/hooks/knowledge-events.d.ts +11 -0
  47. package/dist/hooks/knowledge-reader.d.ts +0 -17
  48. package/dist/hooks/knowledge-store.d.ts +16 -1
  49. package/dist/hooks/knowledge-types.d.ts +85 -0
  50. package/dist/hooks/knowledge-validator.d.ts +15 -0
  51. package/dist/hooks/skill-usage-log.d.ts +3 -0
  52. package/dist/index.js +312 -310
  53. package/dist/memory/consolidation.d.ts +1 -1
  54. package/dist/memory/schema.d.ts +4 -4
  55. package/dist/sast/rules/rust.d.ts +6 -0
  56. package/dist/tools/knowledge-archive.d.ts +6 -2
  57. package/dist/tools/lint.d.ts +2 -2
  58. package/dist/tools/secretscan.d.ts +16 -0
  59. package/dist/tools/test-runner.d.ts +1 -1
  60. package/package.json +1 -1
  61. package/dist/cli/{index-hkpw4wwa.js → index-4r5z8sgw.js} +3 -3
  62. package/dist/cli/{pending-delegations-ws51m1e1.js → pending-delegations-vfnpm8zt.js} +3 -3
@@ -1,10 +1,13 @@
1
1
  // @bun
2
+ import {
3
+ getGlobalEventBus
4
+ } from "./index-c8s9a3zh.js";
2
5
  import {
3
6
  detectStraySwarmDirs,
4
7
  readDoctorArtifact,
5
8
  removeStraySwarmDir,
6
9
  runConfigDoctor
7
- } from "./index-esg1554h.js";
10
+ } from "./index-wvxhynxq.js";
8
11
  import {
9
12
  MAX_TRANSIENT_RETRIES,
10
13
  PlanSchema,
@@ -44,13 +47,22 @@ import {
44
47
  savePlan,
45
48
  transientBackoff,
46
49
  validateProjectRoot
47
- } from "./index-kzfkggjx.js";
50
+ } from "./index-6h82c2h0.js";
51
+ import {
52
+ buildOpenSpecProjectionSync,
53
+ detectSpeckit,
54
+ loadSddStatusSync,
55
+ readEffectiveSpecSync,
56
+ resolveSpeckitProjection,
57
+ validateSpeckit,
58
+ writeProjectedSpecSync
59
+ } from "./index-91j1sqzm.js";
48
60
  import {
49
61
  _internals as _internals2,
50
62
  _internals1 as _internals3,
51
63
  isCommandAvailable,
52
64
  tool
53
- } from "./index-8w4d325g.js";
65
+ } from "./index-xg18az81.js";
54
66
  import {
55
67
  CURATOR_INIT_PROMPT,
56
68
  CURATOR_PHASE_PROMPT,
@@ -69,33 +81,42 @@ import {
69
81
  getCanonicalAgentRole,
70
82
  resolveExternalSkillsConfig,
71
83
  stripKnownSwarmPrefix
72
- } from "./index-2560cctg.js";
84
+ } from "./index-pchpahdf.js";
73
85
  import {
74
86
  DEFAULT_SKILL_MIN_CONFIDENCE,
75
87
  DEFAULT_SKILL_MIN_CONFIRMATIONS,
76
88
  appendRejectedSkillEdit,
77
89
  appendSkillChangelog,
78
- appendUnactionable,
79
90
  autoApplyProposals,
80
- effectiveRetrievalOutcomes,
81
91
  evaluateSkillChange,
82
92
  generateSkills,
83
93
  listSkills,
84
94
  parseDraftFrontmatter,
85
- quarantineEntry,
86
- readKnowledgeCounterRollups,
87
- readKnowledgeEvents,
88
95
  regenerateSkill,
89
- resolveKnowledgeEventsPath,
90
- resolveUnactionablePath,
91
- restoreEntry,
92
96
  retireOrMarkStale,
93
97
  retireSkill,
94
- selectCandidateEntries,
98
+ selectCandidateEntries
99
+ } from "./index-bpgqbwmf.js";
100
+ import {
101
+ appendUnactionable,
102
+ quarantineEntry,
103
+ resolveUnactionablePath,
104
+ restoreEntry,
105
+ unarchiveEntry,
95
106
  validateActionability,
96
107
  validateActionableFields,
97
108
  validateLesson
98
- } from "./index-9wstcavp.js";
109
+ } from "./index-dfdg4ws5.js";
110
+ import {
111
+ readRecentEscalations
112
+ } from "./index-bq8kd9r9.js";
113
+ import {
114
+ effectiveRetrievalOutcomes,
115
+ readKnowledgeCounterRollups,
116
+ readKnowledgeEvents,
117
+ recordKnowledgeEvent,
118
+ resolveKnowledgeEventsPath
119
+ } from "./index-kxm3bdjh.js";
99
120
  import {
100
121
  appendKnowledge,
101
122
  appendRejectedLesson,
@@ -107,36 +128,31 @@ import {
107
128
  findNearDuplicate,
108
129
  getArchivedKnowledgeIds,
109
130
  inferTags,
110
- isLinked,
111
131
  normalize,
112
132
  readKnowledge,
113
- readLinkPointer,
114
133
  readRejectedLessons,
115
134
  readRetractionRecords,
116
- removeLinkPointer,
117
135
  resolveHiveKnowledgePath,
118
136
  resolveHiveRejectedPath,
119
- resolveKnowledgeStoreDir,
120
- resolveLinkDir,
121
137
  resolveSwarmKnowledgePath,
122
138
  rewriteKnowledge,
123
- sanitizeLinkId,
124
139
  transactFile,
125
- transactKnowledge,
126
- writeLinkPointer
127
- } from "./index-f7nma02k.js";
140
+ transactKnowledge
141
+ } from "./index-xmarctsf.js";
128
142
  import {
129
- getGlobalEventBus
130
- } from "./index-c8s9a3zh.js";
143
+ isLinked,
144
+ readLinkPointer,
145
+ removeLinkPointer,
146
+ resolveKnowledgeStoreDir,
147
+ resolveLinkDir,
148
+ sanitizeLinkId,
149
+ writeLinkPointer
150
+ } from "./index-n1sptn1w.js";
131
151
  import {
132
- buildOpenSpecProjectionSync,
133
- detectSpeckit,
134
- loadSddStatusSync,
135
- readEffectiveSpecSync,
136
- resolveSpeckitProjection,
137
- validateSpeckit,
138
- writeProjectedSpecSync
139
- } from "./index-91j1sqzm.js";
152
+ KNOWLEDGE_SCHEMA_VERSION,
153
+ OUTCOME_BLOCK_THRESHOLD,
154
+ isActiveStatus
155
+ } from "./index-bfwt3abw.js";
140
156
  import {
141
157
  SandboxCapabilityProbe,
142
158
  _internals,
@@ -154,7 +170,7 @@ import {
154
170
  listActive,
155
171
  subscribe,
156
172
  unsubscribe
157
- } from "./index-hkpw4wwa.js";
173
+ } from "./index-4r5z8sgw.js";
158
174
  import {
159
175
  readSwarmFileAsync,
160
176
  safeHook,
@@ -169,13 +185,13 @@ import {
169
185
  log,
170
186
  warn
171
187
  } from "./index-zgwm4ryv.js";
188
+ import {
189
+ exports_external
190
+ } from "./index-293f68mj.js";
172
191
  import {
173
192
  require_proper_lockfile,
174
193
  tryAcquireLock
175
194
  } from "./index-3naa2ajc.js";
176
- import {
177
- exports_external
178
- } from "./index-293f68mj.js";
179
195
  import {
180
196
  bunSpawn,
181
197
  bunWrite
@@ -7916,15 +7932,15 @@ var _internals8 = {
7916
7932
  executePostMortemActions,
7917
7933
  repairPostMortemActions,
7918
7934
  loadDefaultKnowledgeConfig: async () => {
7919
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-vw2ffhe9.js");
7935
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-x0ekqzvs.js");
7920
7936
  return KnowledgeConfigSchema2.parse({});
7921
7937
  },
7922
7938
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
7923
- const { applyCuratorKnowledgeUpdates } = await import("./curator-1nr4qszq.js");
7939
+ const { applyCuratorKnowledgeUpdates } = await import("./curator-k9swkynp.js");
7924
7940
  return applyCuratorKnowledgeUpdates(directory, recommendations, knowledgeConfig);
7925
7941
  },
7926
7942
  checkHivePromotions: async (entries, knowledgeConfig) => {
7927
- const { checkHivePromotions } = await import("./hive-promoter-j4e6rfa6.js");
7943
+ const { checkHivePromotions } = await import("./hive-promoter-gh0nva5c.js");
7928
7944
  return checkHivePromotions(entries, knowledgeConfig);
7929
7945
  },
7930
7946
  applyProposalTriage: async (directory, triage) => {
@@ -7933,7 +7949,7 @@ var _internals8 = {
7933
7949
  activateProposal,
7934
7950
  listSkills: listSkills2,
7935
7951
  sanitizeSlug
7936
- } = await import("./skill-generator-y6mmq8n5.js");
7952
+ } = await import("./skill-generator-x83re96d.js");
7937
7953
  const result = {
7938
7954
  approved: [],
7939
7955
  rejected: [],
@@ -7988,34 +8004,6 @@ import { randomUUID as randomUUID5 } from "crypto";
7988
8004
  import * as fs5 from "fs";
7989
8005
  import * as path15 from "path";
7990
8006
 
7991
- // src/hooks/knowledge-escalator.ts
7992
- var ESCALATION_DISPLAY_WINDOW_DAYS = 7;
7993
- async function readRecentEscalations(directory, windowDays = ESCALATION_DISPLAY_WINDOW_DAYS, now = new Date) {
7994
- try {
7995
- const cutoff = now.getTime() - windowDays * 24 * 60 * 60 * 1000;
7996
- const events = await readKnowledgeEvents(directory);
7997
- const out = [];
7998
- for (const e of events) {
7999
- if (e.type !== "escalation")
8000
- continue;
8001
- const t = Date.parse(e.timestamp);
8002
- if (Number.isNaN(t) || t < cutoff)
8003
- continue;
8004
- out.push({
8005
- entry_id: e.entry_id,
8006
- from: e.from,
8007
- to: e.to,
8008
- reason: e.reason,
8009
- at: e.timestamp
8010
- });
8011
- }
8012
- out.sort((a, b) => a.at < b.at ? 1 : a.at > b.at ? -1 : 0);
8013
- return out;
8014
- } catch {
8015
- return [];
8016
- }
8017
- }
8018
-
8019
8007
  // src/services/learning-metrics.ts
8020
8008
  var SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
8021
8009
  var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;
@@ -9331,7 +9319,7 @@ async function applySkillUsageFeedback(directory, options) {
9331
9319
  delta: Math.max(-VIOLATION_DECAY, Math.min(COMPLIANCE_BOOST, netDelta))
9332
9320
  }));
9333
9321
  if (clampedDeltas.length > 0) {
9334
- await bumpKnowledgeConfidenceBatch(directory, clampedDeltas);
9322
+ await bumpKnowledgeConfidenceBatch(directory, clampedDeltas, options?.floorOptions);
9335
9323
  appendFeedbackAppliedMarker(directory, processedEntryIds);
9336
9324
  }
9337
9325
  } catch (err) {
@@ -10129,7 +10117,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
10129
10117
  }
10130
10118
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
10131
10119
  try {
10132
- const skillModule = await import("./skill-generator-y6mmq8n5.js");
10120
+ const skillModule = await import("./skill-generator-x83re96d.js");
10133
10121
  for (const cand of skillCandidates) {
10134
10122
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
10135
10123
  continue;
@@ -10297,9 +10285,11 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
10297
10285
  const knowledgePath = resolveSwarmKnowledgePath(directory);
10298
10286
  const appliedIds = new Set;
10299
10287
  const foundIds = new Set;
10288
+ const contradictedEntries = [];
10300
10289
  await transactKnowledge(knowledgePath, (entries) => {
10301
10290
  appliedIds.clear();
10302
10291
  foundIds.clear();
10292
+ contradictedEntries.length = 0;
10303
10293
  let txApplied = 0;
10304
10294
  let modified = false;
10305
10295
  for (const e of entries)
@@ -10319,19 +10309,29 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
10319
10309
  confidence: Math.min(1, (entry.confidence ?? 0) + 0.1),
10320
10310
  updated_at: new Date().toISOString()
10321
10311
  };
10322
- case "archive":
10312
+ case "archive": {
10313
+ if (entry.status === "archived") {
10314
+ return entry;
10315
+ }
10323
10316
  appliedIds.add(entry.id);
10324
10317
  txApplied++;
10325
10318
  modified = true;
10326
10319
  return {
10327
10320
  ...entry,
10328
10321
  status: "archived",
10322
+ archived_from: entry.status,
10323
+ archived_at: new Date().toISOString(),
10329
10324
  updated_at: new Date().toISOString()
10330
10325
  };
10326
+ }
10331
10327
  case "flag_contradiction":
10332
10328
  appliedIds.add(entry.id);
10333
10329
  txApplied++;
10334
10330
  modified = true;
10331
+ contradictedEntries.push({
10332
+ id: entry.id,
10333
+ reason: (rec.reason ?? "").slice(0, 200)
10334
+ });
10335
10335
  return {
10336
10336
  ...entry,
10337
10337
  tags: [
@@ -10373,6 +10373,27 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
10373
10373
  applied += txApplied;
10374
10374
  return modified ? updatedEntries : null;
10375
10375
  });
10376
+ for (const { id, reason } of contradictedEntries) {
10377
+ try {
10378
+ await recordKnowledgeEvent(directory, {
10379
+ type: "contradicted",
10380
+ knowledge_id: id,
10381
+ trace_id: `curator-${randomUUID5()}`,
10382
+ session_id: "curator",
10383
+ agent: "curator",
10384
+ reason: `flag_contradiction: ${reason}`,
10385
+ evidence: { summary: reason }
10386
+ });
10387
+ } catch {}
10388
+ }
10389
+ if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
10390
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-3sgwrgy9.js");
10391
+ for (const { id } of contradictedEntries) {
10392
+ try {
10393
+ await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
10394
+ } catch {}
10395
+ }
10396
+ }
10376
10397
  for (const rec of validRecommendations) {
10377
10398
  if (rec.entry_id !== undefined && !appliedIds.has(rec.entry_id)) {
10378
10399
  if (!foundIds.has(rec.entry_id)) {
@@ -10495,7 +10516,7 @@ function isHiveEligible(entry, autoPromoteDays) {
10495
10516
  return false;
10496
10517
  }
10497
10518
  function isActiveForHivePromotion(entry) {
10498
- return !["archived", "quarantined", "quarantined_unactionable"].includes(entry.status);
10519
+ return isActiveStatus(entry.status);
10499
10520
  }
10500
10521
  function countDistinctProjects(confirmedBy) {
10501
10522
  const projectNames = new Set;
@@ -10934,13 +10955,8 @@ async function rebuildSynonymMap(directory, entries, maxPairs = DEFAULT_MAX_PAIR
10934
10955
  init_logger();
10935
10956
 
10936
10957
  // src/hooks/knowledge-reinforcement.ts
10937
- var INACTIVE_STATUSES = new Set([
10938
- "archived",
10939
- "quarantined",
10940
- "quarantined_unactionable"
10941
- ]);
10942
10958
  function isActiveSwarmKnowledgeEntry(entry) {
10943
- return !INACTIVE_STATUSES.has(entry.status);
10959
+ return isActiveStatus(entry.status);
10944
10960
  }
10945
10961
  function findActiveSwarmNearDuplicate(lesson, entries, threshold) {
10946
10962
  return findNearDuplicate(lesson, entries.filter(isActiveSwarmKnowledgeEntry), threshold);
@@ -12764,10 +12780,13 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
12764
12780
  }
12765
12781
  if (!options?.skipAutoPromotion) {
12766
12782
  await _internals14.runAutoPromotion(directory, config);
12783
+ if (phaseInfo.phase_number > 0) {
12784
+ await _internals14.runAutoDemotion(directory, config, phaseInfo.phase_number);
12785
+ }
12767
12786
  }
12768
12787
  return { stored, reinforced, skipped, rejected, quarantined };
12769
12788
  }
12770
- var OUTCOME_PROMOTION_BLOCK = -0.3;
12789
+ var OUTCOME_PROMOTION_BLOCK = OUTCOME_BLOCK_THRESHOLD;
12771
12790
  async function runAutoPromotion(directory, config) {
12772
12791
  const knowledgePath = resolveSwarmKnowledgePath(directory);
12773
12792
  const entries = await readKnowledge(knowledgePath) ?? [];
@@ -12802,6 +12821,42 @@ async function runAutoPromotion(directory, config) {
12802
12821
  await rewriteKnowledge(knowledgePath, entries);
12803
12822
  }
12804
12823
  }
12824
+ async function runAutoDemotion(directory, config, phaseNumber) {
12825
+ const knowledgePath = resolveSwarmKnowledgePath(directory);
12826
+ const entries = await readKnowledge(knowledgePath) ?? [];
12827
+ const counterRollups = await readKnowledgeCounterRollups(directory);
12828
+ let changed = false;
12829
+ for (const entry of entries) {
12830
+ if (entry.status !== "promoted")
12831
+ continue;
12832
+ if (entry.last_demotion_phase === phaseNumber)
12833
+ continue;
12834
+ const signal = computeOutcomeSignal(effectiveRetrievalOutcomes(entry.retrieval_outcomes, counterRollups.get(entry.id)));
12835
+ const threshold = config.promoted_demotion_signal_threshold;
12836
+ const minPhases = config.promoted_demotion_min_negative_phases;
12837
+ const prevCount = entry.recent_negative_phase_count ?? 0;
12838
+ const next = signal <= threshold ? prevCount + 1 : 0;
12839
+ const counterChanged = next !== prevCount;
12840
+ const willDemote = next >= minPhases;
12841
+ if (!counterChanged && !willDemote) {
12842
+ entry.last_demotion_phase = phaseNumber;
12843
+ continue;
12844
+ }
12845
+ entry.recent_negative_phase_count = next;
12846
+ entry.last_demotion_phase = phaseNumber;
12847
+ if (willDemote) {
12848
+ entry.status = "established";
12849
+ entry.hive_eligible = false;
12850
+ entry.confidence_floor_demoted = false;
12851
+ entry.recent_negative_phase_count = 0;
12852
+ }
12853
+ entry.updated_at = new Date().toISOString();
12854
+ changed = true;
12855
+ }
12856
+ if (changed) {
12857
+ await rewriteKnowledge(knowledgePath, entries);
12858
+ }
12859
+ }
12805
12860
  function createKnowledgeCuratorHook(directory, config, options = {}) {
12806
12861
  const handler = async (input, output) => {
12807
12862
  pruneSeenRetroSections();
@@ -12881,6 +12936,7 @@ var _internals14 = {
12881
12936
  isWriteToEvidenceFile,
12882
12937
  curateAndStoreSwarm,
12883
12938
  runAutoPromotion,
12939
+ runAutoDemotion,
12884
12940
  createKnowledgeCuratorHook,
12885
12941
  seenRetroSections,
12886
12942
  recordSeenRetroSection,
@@ -15104,7 +15160,7 @@ async function runFinalizeStage(ctx) {
15104
15160
  }
15105
15161
  }
15106
15162
  try {
15107
- const { CuratorConfigSchema: CCS } = await import("./schema-vw2ffhe9.js");
15163
+ const { CuratorConfigSchema: CCS } = await import("./schema-x0ekqzvs.js");
15108
15164
  const { config: pmLoadedConfig } = _internals18.loadPluginConfigWithMeta(ctx.directory);
15109
15165
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
15110
15166
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -17209,9 +17265,9 @@ var _internals22 = {
17209
17265
  readSwarmFileAsync,
17210
17266
  loadCuratorDeps: async () => {
17211
17267
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
17212
- import("./schema-vw2ffhe9.js"),
17213
- import("./curator-1nr4qszq.js"),
17214
- import("./curator-llm-factory-x9tk7e6m.js")
17268
+ import("./schema-x0ekqzvs.js"),
17269
+ import("./curator-k9swkynp.js"),
17270
+ import("./curator-llm-factory-ed67kywr.js")
17215
17271
  ]);
17216
17272
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
17217
17273
  }
@@ -17707,7 +17763,7 @@ import { fileURLToPath } from "url";
17707
17763
  // package.json
17708
17764
  var package_default = {
17709
17765
  name: "opencode-swarm",
17710
- version: "7.107.3",
17766
+ version: "7.107.5",
17711
17767
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
17712
17768
  main: "dist/index.js",
17713
17769
  types: "dist/index.d.ts",
@@ -19151,7 +19207,7 @@ async function handleDoctorCommand(directory, args) {
19151
19207
  const result = runConfigDoctor(config, directory);
19152
19208
  let output;
19153
19209
  if (enableAutoFix && result.hasAutoFixableIssues) {
19154
- const { runConfigDoctorWithFixes } = await import("./config-doctor-cntnpyvj.js");
19210
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-kdq3vae4.js");
19155
19211
  const fixResult = await runConfigDoctorWithFixes(directory, config, true);
19156
19212
  output = formatDoctorMarkdown(fixResult.result);
19157
19213
  } else {
@@ -19964,7 +20020,7 @@ async function handleEvidenceCommand(directory, args) {
19964
20020
  return formatTaskEvidenceMarkdown(evidenceData);
19965
20021
  }
19966
20022
  async function handleEvidenceSummaryCommand(directory) {
19967
- const { buildEvidenceSummary } = await import("./evidence-summary-service-9r28ds8t.js");
20023
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-6zsgw7x7.js");
19968
20024
  const artifact = await buildEvidenceSummary(directory);
19969
20025
  if (!artifact) {
19970
20026
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -21482,11 +21538,6 @@ import { existsSync as existsSync27, readFileSync as readFileSync16 } from "fs";
21482
21538
  import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile12 } from "fs/promises";
21483
21539
  import * as os11 from "os";
21484
21540
  import * as path44 from "path";
21485
-
21486
- // src/hooks/knowledge-types.ts
21487
- var KNOWLEDGE_SCHEMA_VERSION = 2;
21488
-
21489
- // src/hooks/knowledge-migrator.ts
21490
21541
  async function migrateKnowledgeToExternal(_directory, _config) {
21491
21542
  const externalSentinelPath = path44.join(_directory, ".swarm", ".knowledge-external-migrated");
21492
21543
  const contextPath = path44.join(_directory, ".swarm", "context.md");
@@ -21957,10 +22008,23 @@ async function handleKnowledgeRestoreCommand(directory, args) {
21957
22008
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
21958
22009
  }
21959
22010
  try {
22011
+ const swarmEntries = await readKnowledge(resolveSwarmKnowledgePath(directory));
22012
+ const swarmResolved = resolveEntryByPrefix(swarmEntries, inputId);
22013
+ if ("entry" in swarmResolved && swarmResolved.entry.status === "archived") {
22014
+ const fullId2 = swarmResolved.entry.id;
22015
+ const result = await unarchiveEntry(directory, fullId2);
22016
+ if (result.restored) {
22017
+ return `\u2705 Archived entry ${fullId2} restored to '${result.restored_to}'.`;
22018
+ }
22019
+ return `\u274C Entry ${fullId2} could not be unarchived${result.reason ? ` (${result.reason})` : ""}.`;
22020
+ }
21960
22021
  const quarantinePath = join38(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
21961
22022
  const entries = await readKnowledge(quarantinePath);
21962
22023
  const resolved = resolveEntryByPrefix(entries, inputId);
21963
22024
  if ("error" in resolved) {
22025
+ if ("entry" in swarmResolved) {
22026
+ return `\u274C Entry ${swarmResolved.entry.id} is neither archived nor quarantined (status: '${swarmResolved.entry.status}'). Only archived or quarantined entries can be restored.`;
22027
+ }
21964
22028
  return `\u274C ${resolved.error}`;
21965
22029
  }
21966
22030
  const fullId = resolved.entry.id;
@@ -24181,6 +24245,14 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
24181
24245
  const base = useBundle ? ["bundle", "exec", "rubocop"] : ["rubocop"];
24182
24246
  return mode === "fix" ? [...base, "-A"] : base;
24183
24247
  }
24248
+ case "phpstan":
24249
+ return [phpVendorBin(cwd, "phpstan"), "analyse"];
24250
+ case "pint":
24251
+ return mode === "fix" ? [phpVendorBin(cwd, "pint")] : [phpVendorBin(cwd, "pint"), "--test"];
24252
+ case "php-cs-fixer":
24253
+ return mode === "fix" ? [phpVendorBin(cwd, "php-cs-fixer"), "fix"] : [phpVendorBin(cwd, "php-cs-fixer"), "fix", "--dry-run", "--diff"];
24254
+ case "phpcs":
24255
+ return [phpVendorBin(cwd, "phpcs")];
24184
24256
  }
24185
24257
  }
24186
24258
  function detectRuff(cwd) {
@@ -24202,22 +24274,59 @@ function detectClippy(cwd) {
24202
24274
  function detectGolangciLint(cwd) {
24203
24275
  return fs18.existsSync(path50.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
24204
24276
  }
24277
+ function readTextFileSafe(filePath) {
24278
+ try {
24279
+ return fs18.readFileSync(filePath, "utf-8");
24280
+ } catch {
24281
+ return "";
24282
+ }
24283
+ }
24284
+ function phpVendorBin(_cwd, name) {
24285
+ const fileName = process.platform === "win32" ? `${name}.bat` : name;
24286
+ return path50.join("vendor", "bin", fileName);
24287
+ }
24288
+ function phpVendorBinExists(cwd, name) {
24289
+ const local = path50.join(cwd, "vendor", "bin", name);
24290
+ const localWin = path50.join(cwd, "vendor", "bin", `${name}.bat`);
24291
+ return fs18.existsSync(local) || fs18.existsSync(localWin);
24292
+ }
24205
24293
  function detectCheckstyle(cwd) {
24206
24294
  const hasMaven = fs18.existsSync(path50.join(cwd, "pom.xml"));
24207
- const hasGradle = fs18.existsSync(path50.join(cwd, "build.gradle")) || fs18.existsSync(path50.join(cwd, "build.gradle.kts"));
24208
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs18.existsSync(path50.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
24209
- return (hasMaven || hasGradle) && hasBinary;
24295
+ const gradleFiles = ["build.gradle", "build.gradle.kts"].map((file) => path50.join(cwd, file)).filter((file) => fs18.existsSync(file));
24296
+ const hasGradleCheckstyleSignal = fs18.existsSync(path50.join(cwd, "checkstyle.xml")) || fs18.existsSync(path50.join(cwd, "config", "checkstyle", "checkstyle.xml")) || gradleFiles.some((file) => /\bcheckstyle\b/i.test(readTextFileSafe(file)));
24297
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradleCheckstyleSignal && (fs18.existsSync(path50.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
24298
+ return (hasMaven || hasGradleCheckstyleSignal) && hasBinary;
24299
+ }
24300
+ function hasRootKotlinFile(cwd) {
24301
+ try {
24302
+ return fs18.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24303
+ } catch {
24304
+ return false;
24305
+ }
24306
+ }
24307
+ function buildGradleHasKotlinSignal(cwd) {
24308
+ const content = readTextFileSafe(path50.join(cwd, "build.gradle"));
24309
+ return /\b(kotlin|org\.jetbrains\.kotlin|ktlint)\b/i.test(content);
24210
24310
  }
24211
24311
  function detectKtlint(cwd) {
24212
- const hasKotlin = fs18.existsSync(path50.join(cwd, "build.gradle.kts")) || fs18.existsSync(path50.join(cwd, "build.gradle")) || (() => {
24213
- try {
24214
- return fs18.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
24215
- } catch {
24216
- return false;
24217
- }
24218
- })();
24312
+ const hasKotlin = fs18.existsSync(path50.join(cwd, "build.gradle.kts")) || fs18.existsSync(path50.join(cwd, "build.gradle")) && buildGradleHasKotlinSignal(cwd) || hasRootKotlinFile(cwd);
24219
24313
  return hasKotlin && isCommandAvailable("ktlint");
24220
24314
  }
24315
+ function detectPhpLinter(cwd) {
24316
+ if ((fs18.existsSync(path50.join(cwd, "phpstan.neon")) || fs18.existsSync(path50.join(cwd, "phpstan.neon.dist"))) && phpVendorBinExists(cwd, "phpstan")) {
24317
+ return "phpstan";
24318
+ }
24319
+ if (fs18.existsSync(path50.join(cwd, "pint.json")) && phpVendorBinExists(cwd, "pint")) {
24320
+ return "pint";
24321
+ }
24322
+ if (fs18.existsSync(path50.join(cwd, ".php-cs-fixer.php")) && phpVendorBinExists(cwd, "php-cs-fixer")) {
24323
+ return "php-cs-fixer";
24324
+ }
24325
+ if (fs18.existsSync(path50.join(cwd, "phpcs.xml")) && phpVendorBinExists(cwd, "phpcs")) {
24326
+ return "phpcs";
24327
+ }
24328
+ return null;
24329
+ }
24221
24330
  function detectDotnetFormat(cwd) {
24222
24331
  try {
24223
24332
  const files = fs18.readdirSync(cwd);
@@ -24261,10 +24370,13 @@ function detectAdditionalLinter(cwd) {
24261
24370
  return "clippy";
24262
24371
  if (detectGolangciLint(cwd))
24263
24372
  return "golangci-lint";
24264
- if (detectCheckstyle(cwd))
24265
- return "checkstyle";
24373
+ const phpLinter = detectPhpLinter(cwd);
24374
+ if (phpLinter)
24375
+ return phpLinter;
24266
24376
  if (detectKtlint(cwd))
24267
24377
  return "ktlint";
24378
+ if (detectCheckstyle(cwd))
24379
+ return "checkstyle";
24268
24380
  if (detectDotnetFormat(cwd))
24269
24381
  return "dotnet-format";
24270
24382
  if (detectCppcheck(cwd))
@@ -25222,9 +25334,68 @@ async function runSecretscan(directory) {
25222
25334
  return errorResult;
25223
25335
  }
25224
25336
  }
25337
+ async function runSecretscanOnFiles(files, directory) {
25338
+ try {
25339
+ const findings = [];
25340
+ let filesScanned = 0;
25341
+ let skippedFiles = 0;
25342
+ for (const file of files) {
25343
+ if (typeof file !== "string") {
25344
+ skippedFiles++;
25345
+ continue;
25346
+ }
25347
+ const resolvedPath = path51.isAbsolute(file) ? path51.resolve(file) : path51.resolve(directory, file);
25348
+ if (!isPathWithinScope(resolvedPath, directory)) {
25349
+ skippedFiles++;
25350
+ continue;
25351
+ }
25352
+ const ext = path51.extname(resolvedPath).toLowerCase();
25353
+ if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
25354
+ skippedFiles++;
25355
+ continue;
25356
+ }
25357
+ if (!fs19.existsSync(resolvedPath)) {
25358
+ skippedFiles++;
25359
+ continue;
25360
+ }
25361
+ const fileFindings = scanFileForSecrets(resolvedPath);
25362
+ filesScanned++;
25363
+ findings.push(...fileFindings);
25364
+ if (findings.length >= MAX_FINDINGS) {
25365
+ findings.length = MAX_FINDINGS;
25366
+ break;
25367
+ }
25368
+ }
25369
+ findings.sort((a, b) => {
25370
+ if (a.path < b.path)
25371
+ return -1;
25372
+ if (a.path > b.path)
25373
+ return 1;
25374
+ return a.line - b.line;
25375
+ });
25376
+ return {
25377
+ scan_dir: directory,
25378
+ findings,
25379
+ count: findings.length,
25380
+ files_scanned: filesScanned,
25381
+ skipped_files: skippedFiles
25382
+ };
25383
+ } catch (e) {
25384
+ return {
25385
+ error: e instanceof Error ? `scan failed: ${e.message}` : "scan failed: unknown error",
25386
+ scan_dir: directory,
25387
+ findings: [],
25388
+ count: 0,
25389
+ files_scanned: 0,
25390
+ skipped_files: 0
25391
+ };
25392
+ }
25393
+ }
25225
25394
  var _internals41 = {
25226
25395
  secretscan,
25227
- runSecretscan
25396
+ runSecretscan,
25397
+ runSecretscanOnFiles,
25398
+ SECRET_PATTERNS: SECRET_PATTERNS2
25228
25399
  };
25229
25400
 
25230
25401
  // src/tools/test-runner.ts
@@ -26401,14 +26572,19 @@ var DISPATCH_FRAMEWORK_MAP = {
26401
26572
  "dart-test": "dart-test",
26402
26573
  rspec: "rspec",
26403
26574
  minitest: "minitest",
26575
+ pest: "pest",
26576
+ phpunit: "phpunit",
26577
+ "php-artisan": "php-artisan",
26404
26578
  "bun:test": "bun",
26405
26579
  "xcodebuild-test": "swift-test",
26406
26580
  "flutter test": "dart-test",
26407
- "dart test": "dart-test"
26581
+ "dart test": "dart-test",
26582
+ Pest: "pest",
26583
+ PHPUnit: "phpunit"
26408
26584
  };
26409
26585
  async function detectTestFrameworkViaDispatch(cwd) {
26410
26586
  try {
26411
- const { pickBackend } = await import("./dispatch-e4ejrsz8.js");
26587
+ const { pickBackend } = await import("./dispatch-anmxxhen.js");
26412
26588
  const backend = await pickBackend(cwd);
26413
26589
  if (!backend?.selectTestFramework)
26414
26590
  return "none";
@@ -26424,7 +26600,7 @@ async function buildTestCommandViaDispatch(framework, scope, files, coverage, ba
26424
26600
  if (framework === "none")
26425
26601
  return null;
26426
26602
  try {
26427
- const { pickBackend } = await import("./dispatch-e4ejrsz8.js");
26603
+ const { pickBackend } = await import("./dispatch-anmxxhen.js");
26428
26604
  const backend = await pickBackend(baseDir);
26429
26605
  if (backend?.buildTestCommand) {
26430
26606
  const cmd = backend.buildTestCommand(framework, files, baseDir, {
@@ -26444,7 +26620,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
26444
26620
  if (framework === "none")
26445
26621
  return null;
26446
26622
  try {
26447
- const { pickBackend } = await import("./dispatch-e4ejrsz8.js");
26623
+ const { pickBackend } = await import("./dispatch-anmxxhen.js");
26448
26624
  const backend = await pickBackend(baseDir);
26449
26625
  if (!backend?.parseTestOutput)
26450
26626
  return null;
@@ -26535,6 +26711,9 @@ async function detectTestFramework(cwd) {
26535
26711
  return "pester";
26536
26712
  }
26537
26713
  } catch {}
26714
+ const phpFramework = detectPhpTest(baseDir);
26715
+ if (phpFramework)
26716
+ return phpFramework;
26538
26717
  if (detectGoTest(baseDir))
26539
26718
  return "go-test";
26540
26719
  if (detectJavaMaven(baseDir))
@@ -26555,6 +26734,17 @@ async function detectTestFramework(cwd) {
26555
26734
  return "minitest";
26556
26735
  return "none";
26557
26736
  }
26737
+ function detectPhpTest(cwd) {
26738
+ if (fs23.existsSync(path55.join(cwd, "artisan")) && fs23.existsSync(path55.join(cwd, "composer.json"))) {
26739
+ return "php-artisan";
26740
+ }
26741
+ if (fs23.existsSync(path55.join(cwd, "Pest.php")))
26742
+ return "pest";
26743
+ if (fs23.existsSync(path55.join(cwd, "phpunit.xml")) || fs23.existsSync(path55.join(cwd, "phpunit.xml.dist"))) {
26744
+ return "phpunit";
26745
+ }
26746
+ return null;
26747
+ }
26558
26748
  var COMPOUND_TEST_EXTENSIONS = [
26559
26749
  ".test.ts",
26560
26750
  ".test.tsx",
@@ -26608,6 +26798,12 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
26608
26798
  `${nameWithoutExt}Tests.kt`,
26609
26799
  `Test${nameWithoutExt}.kt`
26610
26800
  ];
26801
+ case ".php":
26802
+ return [
26803
+ `${nameWithoutExt}Test.php`,
26804
+ `${nameWithoutExt}Tests.php`,
26805
+ `Test${nameWithoutExt}.php`
26806
+ ];
26611
26807
  case ".ps1":
26612
26808
  return [`${nameWithoutExt}.Tests.ps1`, `${nameWithoutExt}.tests.ps1`];
26613
26809
  default:
@@ -26648,6 +26844,8 @@ function isLanguageSpecificTestFile(basename11) {
26648
26844
  return true;
26649
26845
  if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename11) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
26650
26846
  return true;
26847
+ if (lower.endsWith(".php") && (/^Test[A-Z]/.test(basename11) || basename11.endsWith("Test.php") || basename11.endsWith("Tests.php")))
26848
+ return true;
26651
26849
  if (lower.endsWith(".tests.ps1"))
26652
26850
  return true;
26653
26851
  return false;
@@ -26945,10 +27143,31 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
26945
27143
  "-e",
26946
27144
  'Dir.glob("test/**/*_test.rb").sort.each { |f| require_relative f }'
26947
27145
  ];
27146
+ case "pest": {
27147
+ const args = [phpVendorBin2("pest")];
27148
+ if (scope !== "all" && files.length > 0)
27149
+ args.push(...files);
27150
+ return args;
27151
+ }
27152
+ case "phpunit": {
27153
+ const args = [phpVendorBin2("phpunit")];
27154
+ if (scope !== "all" && files.length > 0)
27155
+ args.push(...files);
27156
+ return args;
27157
+ }
27158
+ case "php-artisan": {
27159
+ const args = ["php", "artisan", "test"];
27160
+ if (scope !== "all" && files.length > 0)
27161
+ args.push(...files);
27162
+ return args;
27163
+ }
26948
27164
  default:
26949
27165
  return null;
26950
27166
  }
26951
27167
  }
27168
+ function phpVendorBin2(name) {
27169
+ return path55.join("vendor", "bin", process.platform === "win32" ? `${name}.bat` : name);
27170
+ }
26952
27171
  function mapFrameworkStatusToResult(status) {
26953
27172
  if (typeof status !== "string")
26954
27173
  return null;
@@ -27272,6 +27491,24 @@ function parseTestOutput(framework, output) {
27272
27491
  }
27273
27492
  break;
27274
27493
  }
27494
+ case "pest":
27495
+ case "phpunit":
27496
+ case "php-artisan": {
27497
+ const phpunitMatch = output.match(/Tests:\s*(\d+),\s*Assertions:\s*\d+(?:,\s*Failures:\s*(\d+))?(?:,\s*Errors:\s*(\d+))?(?:,\s*Skipped:\s*(\d+))?/);
27498
+ const okMatch = output.match(/OK\s*\((\d+)\s+tests?/);
27499
+ if (phpunitMatch) {
27500
+ totals.total = parseInt(phpunitMatch[1], 10);
27501
+ const failures = phpunitMatch[2] ? parseInt(phpunitMatch[2], 10) : 0;
27502
+ const errors = phpunitMatch[3] ? parseInt(phpunitMatch[3], 10) : 0;
27503
+ totals.skipped = phpunitMatch[4] ? parseInt(phpunitMatch[4], 10) : 0;
27504
+ totals.failed = failures + errors;
27505
+ totals.passed = totals.total - totals.failed - totals.skipped;
27506
+ } else if (okMatch) {
27507
+ totals.total = parseInt(okMatch[1], 10);
27508
+ totals.passed = totals.total;
27509
+ }
27510
+ break;
27511
+ }
27275
27512
  default:
27276
27513
  break;
27277
27514
  }
@@ -27492,6 +27729,7 @@ var SOURCE_EXTENSIONS = new Set([
27492
27729
  ".hpp",
27493
27730
  ".cc",
27494
27731
  ".cxx",
27732
+ ".php",
27495
27733
  ".swift",
27496
27734
  ".dart",
27497
27735
  ".rb",
@@ -32049,7 +32287,7 @@ function buildDetailedHelp(commandName, entry) {
32049
32287
  async function handleHelpCommand(ctx) {
32050
32288
  const targetCommand = ctx.args.join(" ");
32051
32289
  if (!targetCommand) {
32052
- const { buildHelpText } = await import("./index-502f6np6.js");
32290
+ const { buildHelpText } = await import("./index-w1tvqh4x.js");
32053
32291
  return buildHelpText();
32054
32292
  }
32055
32293
  const tokens = targetCommand.split(/\s+/);
@@ -32058,7 +32296,7 @@ async function handleHelpCommand(ctx) {
32058
32296
  return _internals49.buildDetailedHelp(resolved.key, resolved.entry);
32059
32297
  }
32060
32298
  const similar = _internals49.findSimilarCommands(targetCommand);
32061
- const { buildHelpText: fullHelp } = await import("./index-502f6np6.js");
32299
+ const { buildHelpText: fullHelp } = await import("./index-w1tvqh4x.js");
32062
32300
  if (similar.length > 0) {
32063
32301
  return `Command '/swarm ${targetCommand}' not found.
32064
32302
 
@@ -32191,7 +32429,7 @@ var COMMAND_REGISTRY = {
32191
32429
  },
32192
32430
  "guardrail explain": {
32193
32431
  handler: async (ctx) => {
32194
- const { handleGuardrailExplain } = await import("./guardrail-explain-etdrhd4d.js");
32432
+ const { handleGuardrailExplain } = await import("./guardrail-explain-vd6da30t.js");
32195
32433
  return handleGuardrailExplain(ctx.directory, ctx.args);
32196
32434
  },
32197
32435
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -32201,7 +32439,7 @@ var COMMAND_REGISTRY = {
32201
32439
  },
32202
32440
  "guardrail-log": {
32203
32441
  handler: async (ctx) => {
32204
- const { handleGuardrailLog } = await import("./guardrail-log-2rns4g6d.js");
32442
+ const { handleGuardrailLog } = await import("./guardrail-log-fjypsmek.js");
32205
32443
  return handleGuardrailLog(ctx.directory, ctx.args);
32206
32444
  },
32207
32445
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -32803,9 +33041,9 @@ Subcommands:
32803
33041
  },
32804
33042
  "knowledge restore": {
32805
33043
  handler: (ctx) => handleKnowledgeRestoreCommand(ctx.directory, ctx.args),
32806
- description: "Restore a quarantined knowledge entry <id>",
33044
+ description: "Restore a quarantined or archived knowledge entry <id>",
32807
33045
  subcommandOf: "knowledge",
32808
- details: "Restores a quarantined knowledge entry back to the active knowledge store by ID. Validates entry ID format (1-64 alphanumeric/hyphen/underscore). Entry must currently be in quarantine state.",
33046
+ details: "Restores a quarantined or archived knowledge entry back to the active knowledge store by ID. Dispatches by current status: an 'archived' entry is restored to its pre-archive status; a 'quarantined' entry is restored from the quarantine sidecar. Validates entry ID format (1-64 alphanumeric/hyphen/underscore).",
32809
33047
  args: "<entry-id>",
32810
33048
  category: "utility"
32811
33049
  },
@@ -37127,7 +37365,7 @@ function hasActiveEpicMode(sessionID) {
37127
37365
  async function rehydratePrSubscriptions(sessionID, directory) {
37128
37366
  const map = new Map;
37129
37367
  try {
37130
- const { listActive: listActive2 } = await import("./pr-subscriptions-0dpn4epk.js");
37368
+ const { listActive: listActive2 } = await import("./pr-subscriptions-bpvazmsw.js");
37131
37369
  const records = await listActive2(directory);
37132
37370
  for (const record of records) {
37133
37371
  if (record.sessionID !== sessionID)