opencode-swarm 7.3.6 → 7.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -34,7 +34,7 @@ var package_default;
34
34
  var init_package = __esm(() => {
35
35
  package_default = {
36
36
  name: "opencode-swarm",
37
- version: "7.3.6",
37
+ version: "7.3.7",
38
38
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
39
39
  main: "dist/index.js",
40
40
  types: "dist/index.d.ts",
@@ -7,7 +7,31 @@
7
7
  * This hook runs as a chat.message transform — it inspects the architect's output
8
8
  * and injects the critic's autonomous oversight response when escalation is detected.
9
9
  */
10
+ import type { OpencodeClient } from '@opencode-ai/sdk';
11
+ import type { AgentDefinition } from '../agents/architect.js';
10
12
  import type { PluginConfig } from '../config';
13
+ import type { AgentSessionState } from '../state.js';
14
+ /**
15
+ * Test-only dependency-injection seam. Production code accesses state through
16
+ * `_internals.*` so tests can swap individual functions on this object without
17
+ * resorting to `mock.module('../../../src/state.js', ...)`, which leaks across
18
+ * test files in Bun's shared test-runner process and contaminates unrelated
19
+ * suites (see `gitignore-warning.ts:_internals` and `diff-scope.ts:_internals`
20
+ * for the pattern rationale). Tests should restore overridden properties in
21
+ * `afterEach`.
22
+ *
23
+ * All fields default to `null`. In production the lazy loaders (`_loadState`,
24
+ * `_loadCritic`) are used as fallbacks. In tests, set a non-null override
25
+ * before calling the hook to bypass the real module entirely.
26
+ */
27
+ export declare const _internals: {
28
+ hasActiveFullAuto: ((sessionId?: string) => boolean) | null;
29
+ ensureAgentSession: ((sessionId: string) => AgentSessionState) | null;
30
+ swarmState: {
31
+ opencodeClient: OpencodeClient | null;
32
+ } | null;
33
+ createCriticAutonomousOversightAgent: ((model: string, customAppendPrompt?: string) => AgentDefinition) | null;
34
+ };
11
35
  interface MessageWithParts {
12
36
  info: {
13
37
  role: string;
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ var package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "opencode-swarm",
36
- version: "7.3.6",
36
+ version: "7.3.7",
37
37
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
38
38
  main: "dist/index.js",
39
39
  types: "dist/index.d.ts",
@@ -58236,6 +58236,18 @@ ${HARD_RULES}
58236
58236
  });
58237
58237
 
58238
58238
  // src/agents/critic.ts
58239
+ var exports_critic = {};
58240
+ __export(exports_critic, {
58241
+ parseSoundingBoardResponse: () => parseSoundingBoardResponse,
58242
+ createCriticDriftVerifierAgent: () => createCriticDriftVerifierAgent,
58243
+ createCriticAutonomousOversightAgent: () => createCriticAutonomousOversightAgent,
58244
+ createCriticAgent: () => createCriticAgent,
58245
+ SOUNDING_BOARD_PROMPT: () => SOUNDING_BOARD_PROMPT,
58246
+ PLAN_CRITIC_PROMPT: () => PLAN_CRITIC_PROMPT,
58247
+ PHASE_DRIFT_VERIFIER_PROMPT: () => PHASE_DRIFT_VERIFIER_PROMPT,
58248
+ HALLUCINATION_VERIFIER_PROMPT: () => HALLUCINATION_VERIFIER_PROMPT,
58249
+ AUTONOMOUS_OVERSIGHT_PROMPT: () => AUTONOMOUS_OVERSIGHT_PROMPT
58250
+ });
58239
58251
  function parseSoundingBoardResponse(raw) {
58240
58252
  if (typeof raw !== "string" || raw.trim().length === 0)
58241
58253
  return null;
@@ -58301,6 +58313,25 @@ ${customAppendPrompt}` : rolePrompt;
58301
58313
  }
58302
58314
  };
58303
58315
  }
58316
+ function createCriticDriftVerifierAgent(model, customAppendPrompt) {
58317
+ const prompt = customAppendPrompt ? `${PHASE_DRIFT_VERIFIER_PROMPT}
58318
+
58319
+ ${customAppendPrompt}` : PHASE_DRIFT_VERIFIER_PROMPT;
58320
+ return {
58321
+ name: "critic",
58322
+ description: "Phase drift verifier. Independently verifies that every task in a completed phase was actually implemented as specified.",
58323
+ config: {
58324
+ model,
58325
+ temperature: 0.1,
58326
+ prompt,
58327
+ tools: {
58328
+ write: false,
58329
+ edit: false,
58330
+ patch: false
58331
+ }
58332
+ }
58333
+ };
58334
+ }
58304
58335
  function createCriticAutonomousOversightAgent(model, customAppendPrompt) {
58305
58336
  const prompt = customAppendPrompt ? `${AUTONOMOUS_OVERSIGHT_PROMPT}
58306
58337
 
@@ -66200,10 +66231,29 @@ function createDelegationTrackerHook(config3, guardrailsEnabled = true) {
66200
66231
  // src/hooks/full-auto-intercept.ts
66201
66232
  init_schema();
66202
66233
  init_file_locks();
66203
- init_state();
66204
66234
  init_telemetry();
66205
66235
  init_utils2();
66206
66236
  import * as fs35 from "node:fs";
66237
+ var _stateCache = null;
66238
+ async function _loadState() {
66239
+ if (_stateCache === null) {
66240
+ _stateCache = await Promise.resolve().then(() => (init_state(), exports_state));
66241
+ }
66242
+ return _stateCache;
66243
+ }
66244
+ var _criticCache = null;
66245
+ async function _loadCritic() {
66246
+ if (_criticCache === null) {
66247
+ _criticCache = await Promise.resolve().then(() => exports_critic);
66248
+ }
66249
+ return _criticCache;
66250
+ }
66251
+ var _internals = {
66252
+ hasActiveFullAuto: null,
66253
+ ensureAgentSession: null,
66254
+ swarmState: null,
66255
+ createCriticAutonomousOversightAgent: null
66256
+ };
66207
66257
  var END_OF_SENTENCE_QUESTION_PATTERN = /\?\s*$/;
66208
66258
  var PHASE_COMPLETION_PATTERNS = [
66209
66259
  /Ready for Phase (?:\d+|\[?N\+1\]?)\??/i,
@@ -66510,7 +66560,8 @@ Critic reasoning: ${criticResult.reasoning}`
66510
66560
  }
66511
66561
  }
66512
66562
  async function dispatchCriticAndWriteEvent(directory, architectOutput, criticContext, criticModel, escalationType, interactionCount, deadlockCount, oversightAgentName) {
66513
- const client = swarmState.opencodeClient;
66563
+ const swarmState2 = _internals.swarmState ?? (await _loadState()).swarmState;
66564
+ const client = swarmState2.opencodeClient;
66514
66565
  if (!client) {
66515
66566
  warn("[full-auto-intercept] No opencodeClient — critic dispatch skipped (fallback to PENDING)");
66516
66567
  const result = {
@@ -66524,7 +66575,8 @@ async function dispatchCriticAndWriteEvent(directory, architectOutput, criticCon
66524
66575
  await writeAutoOversightEvent(directory, architectOutput, result.verdict, result.reasoning, result.evidenceChecked, interactionCount, deadlockCount, escalationType);
66525
66576
  return result;
66526
66577
  }
66527
- const oversightAgent = createCriticAutonomousOversightAgent(criticModel, criticContext);
66578
+ const createCriticFn = _internals.createCriticAutonomousOversightAgent ?? (await _loadCritic()).createCriticAutonomousOversightAgent;
66579
+ const oversightAgent = createCriticFn(criticModel, criticContext);
66528
66580
  log(`[full-auto-intercept] Dispatching critic: ${oversightAgent.name} using model ${criticModel}`);
66529
66581
  let ephemeralSessionId;
66530
66582
  const cleanup = () => {
@@ -66630,11 +66682,12 @@ function createFullAutoInterceptHook(config3, directory) {
66630
66682
  if (!architectText)
66631
66683
  return;
66632
66684
  const sessionID = architectMessage.info?.sessionID;
66633
- if (!hasActiveFullAuto(sessionID))
66685
+ const hasActiveFullAuto2 = _internals.hasActiveFullAuto ?? (await _loadState()).hasActiveFullAuto;
66686
+ if (!hasActiveFullAuto2(sessionID))
66634
66687
  return;
66688
+ const ensureAgentSession2 = _internals.ensureAgentSession ?? (await _loadState()).ensureAgentSession;
66635
66689
  let session = null;
66636
66690
  if (sessionID) {
66637
- const { ensureAgentSession: ensureAgentSession2 } = await Promise.resolve().then(() => (init_state(), exports_state));
66638
66691
  session = ensureAgentSession2(sessionID);
66639
66692
  }
66640
66693
  if (session) {
@@ -66672,7 +66725,8 @@ function createFullAutoInterceptHook(config3, directory) {
66672
66725
  log(`[full-auto-intercept] Escalation detected (${escalationType}) — triggering autonomous oversight`);
66673
66726
  const criticContext = buildCriticContext(architectText, escalationType);
66674
66727
  const criticModel = fullAutoConfig.critic_model ?? "claude-sonnet-4-20250514";
66675
- const oversightAgent = createCriticAutonomousOversightAgent(criticModel, criticContext);
66728
+ const createCriticFn = _internals.createCriticAutonomousOversightAgent ?? (await _loadCritic()).createCriticAutonomousOversightAgent;
66729
+ const oversightAgent = createCriticFn(criticModel, criticContext);
66676
66730
  const architectAgent = architectMessage.info?.agent;
66677
66731
  const resolvedOversightAgentName = resolveOversightAgentName(architectAgent);
66678
66732
  const dispatchAgentName = resolvedOversightAgentName && resolvedOversightAgentName.length > 0 ? resolvedOversightAgentName : "critic_oversight";
@@ -88348,7 +88402,7 @@ function slugify2(str) {
88348
88402
  return str.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_");
88349
88403
  }
88350
88404
  var GENERATE_MUTANTS_TIMEOUT_MS = 90000;
88351
- var _internals = {
88405
+ var _internals2 = {
88352
88406
  timeoutMs: GENERATE_MUTANTS_TIMEOUT_MS
88353
88407
  };
88354
88408
  function extractJsonArray(text) {
@@ -88458,7 +88512,7 @@ Return ONLY a valid JSON array. No markdown, no code fences, no explanation. Sta
88458
88512
  });
88459
88513
  }
88460
88514
  return patches2;
88461
- })(), _internals.timeoutMs, new Error("generateMutants: LLM call timed out"));
88515
+ })(), _internals2.timeoutMs, new Error("generateMutants: LLM call timed out"));
88462
88516
  return patches;
88463
88517
  } catch (error93) {
88464
88518
  console.warn(`[generateMutants] LLM call failed: ${error93 instanceof Error ? error93.message : String(error93)}; returning empty patch set`);
@@ -89694,7 +89748,7 @@ import * as path105 from "node:path";
89694
89748
  init_bun_compat();
89695
89749
  import * as fs84 from "node:fs";
89696
89750
  import * as path104 from "node:path";
89697
- var _internals2 = { bunSpawn };
89751
+ var _internals3 = { bunSpawn };
89698
89752
  var _swarmGitExcludedChecked = false;
89699
89753
  function fileCoversSwarm(content) {
89700
89754
  for (const rawLine of content.split(`
@@ -89721,7 +89775,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
89721
89775
  _swarmGitExcludedChecked = true;
89722
89776
  const { quiet = false } = options;
89723
89777
  try {
89724
- const gitRootProc = _internals2.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
89778
+ const gitRootProc = _internals3.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
89725
89779
  let gitRootExitCode;
89726
89780
  let gitRootOutput;
89727
89781
  try {
@@ -89739,7 +89793,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
89739
89793
  const gitRoot = gitRootOutput.trim();
89740
89794
  if (!gitRoot)
89741
89795
  return;
89742
- const excludePathProc = _internals2.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
89796
+ const excludePathProc = _internals3.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
89743
89797
  let excludePathExitCode;
89744
89798
  let excludePathRaw;
89745
89799
  try {
@@ -89758,7 +89812,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
89758
89812
  if (!excludeRelPath)
89759
89813
  return;
89760
89814
  const excludePath = path104.isAbsolute(excludeRelPath) ? excludeRelPath : path104.join(directory, excludeRelPath);
89761
- const checkIgnoreProc = _internals2.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
89815
+ const checkIgnoreProc = _internals3.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
89762
89816
  let checkIgnoreExitCode;
89763
89817
  try {
89764
89818
  checkIgnoreExitCode = await checkIgnoreProc.exited;
@@ -89785,7 +89839,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
89785
89839
  }
89786
89840
  } catch {}
89787
89841
  }
89788
- const trackedProc = _internals2.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
89842
+ const trackedProc = _internals3.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
89789
89843
  let trackedExitCode;
89790
89844
  let trackedOutput;
89791
89845
  try {
@@ -89810,7 +89864,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
89810
89864
  }
89811
89865
 
89812
89866
  // src/hooks/diff-scope.ts
89813
- var _internals3 = { bunSpawn };
89867
+ var _internals4 = { bunSpawn };
89814
89868
  function getDeclaredScope(taskId, directory) {
89815
89869
  try {
89816
89870
  const planPath = path105.join(directory, ".swarm", "plan.json");
@@ -89845,7 +89899,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
89845
89899
  };
89846
89900
  async function getChangedFiles(directory) {
89847
89901
  try {
89848
- const proc = _internals3.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
89902
+ const proc = _internals4.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
89849
89903
  cwd: directory,
89850
89904
  ...GIT_DIFF_SPAWN_OPTIONS
89851
89905
  });
@@ -89862,7 +89916,7 @@ async function getChangedFiles(directory) {
89862
89916
  return stdout.trim().split(`
89863
89917
  `).map((f) => f.trim()).filter((f) => f.length > 0);
89864
89918
  }
89865
- const proc2 = _internals3.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
89919
+ const proc2 = _internals4.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
89866
89920
  cwd: directory,
89867
89921
  ...GIT_DIFF_SPAWN_OPTIONS
89868
89922
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.3.6",
3
+ "version": "7.3.7",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",