opencode-swarm 7.52.3 → 7.54.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.
package/dist/cli/index.js CHANGED
@@ -52,7 +52,7 @@ var package_default;
52
52
  var init_package = __esm(() => {
53
53
  package_default = {
54
54
  name: "opencode-swarm",
55
- version: "7.52.3",
55
+ version: "7.54.0",
56
56
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
57
57
  main: "dist/index.js",
58
58
  types: "dist/index.d.ts",
@@ -16874,11 +16874,11 @@ var init_tool_metadata = __esm(() => {
16874
16874
  agents: ["architect"]
16875
16875
  },
16876
16876
  web_search: {
16877
- description: "External web search (Tavily or Brave) for architect-driven council research. Returns titled results with snippets and URLs. Config-gated on council.general.enabled; requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents.",
16877
+ description: "External web search (Tavily or Brave) for architect-driven council research. Returns titled results with snippets, URLs, normalized query metadata, temporal intent, freshness, and removed stale years. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides. Requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents.",
16878
16878
  agents: ["architect", "skill_improver"]
16879
16879
  },
16880
16880
  convene_general_council: {
16881
- description: "Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled.",
16881
+ description: "Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",
16882
16882
  agents: ["architect"]
16883
16883
  },
16884
16884
  write_final_council_evidence: {
@@ -21331,6 +21331,8 @@ ROUND 1 \u2014 Independent Analysis and Answer
21331
21331
  - Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.
21332
21332
  - Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).
21333
21333
  - State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.
21334
+ - For current, latest, today, now, or otherwise time-sensitive claims, training knowledge is NOT evidence. If the RESEARCH CONTEXT is missing, stale, or ambiguous, say the claim is not established instead of filling the gap from memory.
21335
+ - Treat the dispatch message's CURRENT DATE as authoritative for relative time. Do not append your own training cutoff year to search-oriented reasoning or recommendations.
21334
21336
  - Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.
21335
21337
  - Do NOT coordinate with other members. You will not see their responses until Round 2.
21336
21338
  - Do NOT pad. Be concise. Substance over volume.
@@ -21373,7 +21375,8 @@ Notes:
21373
21375
  - For Round 1: leave \`disagreementTopics\` as []. For Round 2: list the specific disagreement topics this response addresses.`, HARD_RULES = `================================================================
21374
21376
  HARD RULES
21375
21377
  ================================================================
21376
- - You have no tools. Reason from the provided RESEARCH CONTEXT and your training knowledge.
21378
+ - You have no tools. Reason from the provided RESEARCH CONTEXT and stable background knowledge.
21379
+ - Training knowledge may provide stable background only; it must not support current facts, rankings, prices, release status, active best practices, or "state of the art" claims.
21377
21380
  - Never invent sources. If the RESEARCH CONTEXT does not cover a needed claim, say so in \`areasOfUncertainty\`.
21378
21381
  - Never echo other members' responses verbatim. Paraphrase or quote with attribution.
21379
21382
  - Stay within your role and persona. The architect chose you for a specific perspective.`, GENERALIST_COUNCIL_PROMPT, SKEPTIC_COUNCIL_PROMPT, DOMAIN_EXPERT_COUNCIL_PROMPT;
@@ -21719,7 +21722,7 @@ var init_guardrails = __esm(() => {
21719
21722
  function clearPendingCoderScope() {
21720
21723
  pendingCoderScopeByTaskId.clear();
21721
21724
  }
21722
- var EvidenceTaskIdPlanSchema, pendingCoderScopeByTaskId, ACTIVE_PARALLEL_TASK_STATES;
21725
+ var EvidenceTaskIdPlanSchema, pendingCoderScopeByTaskId, SWARM_BACKGROUND_TASK_BLOCKED_MESSAGE, ACTIVE_PARALLEL_TASK_STATES;
21723
21726
  var init_delegation_gate = __esm(() => {
21724
21727
  init_zod();
21725
21728
  init_schema();
@@ -21740,6 +21743,7 @@ var init_delegation_gate = __esm(() => {
21740
21743
  }).passthrough()).optional()
21741
21744
  }).passthrough();
21742
21745
  pendingCoderScopeByTaskId = new Map;
21746
+ SWARM_BACKGROUND_TASK_BLOCKED_MESSAGE = "SWARM_BACKGROUND_TASK_BLOCKED: OpenCode background subagents (Task with background=true, " + "requires OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true) are recognized upstream, but swarm " + "cannot yet safely consume their deferred completion events \u2014 the Task returns a running " + "placeholder now and completes later via synthetic injection, which would advance swarm gates " + "before any review/test output exists. Omit `background` (or set background=false) for swarm " + "delegations until the completion-ingestion PR lands.";
21743
21747
  ACTIVE_PARALLEL_TASK_STATES = new Set([
21744
21748
  "coder_delegated",
21745
21749
  "pre_check_passed",
@@ -39867,7 +39871,7 @@ var init_council = __esm(() => {
39867
39871
  " --preset <name> Use a named member preset from council.general.presets",
39868
39872
  " --spec-review Use spec_review mode (single advisory pass on a draft spec)",
39869
39873
  "",
39870
- "Requires council.general.enabled: true and a configured search API key in opencode-swarm.json."
39874
+ "Requires council.general.enabled: true and a configured search API key in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides."
39871
39875
  ].join(`
39872
39876
  `);
39873
39877
  });
@@ -49905,7 +49909,7 @@ var init_plan = __esm(() => {
49905
49909
  init_plan_service();
49906
49910
  });
49907
49911
 
49908
- // src/commands/pr-review.ts
49912
+ // src/commands/pr-ref.ts
49909
49913
  import { execSync as execSync3 } from "child_process";
49910
49914
  function sanitizeUrl2(raw) {
49911
49915
  let urlStr = raw.trim();
@@ -49924,6 +49928,22 @@ function sanitizeUrl2(raw) {
49924
49928
  }
49925
49929
  return urlStr.trim();
49926
49930
  }
49931
+ function sanitizeInstructions(raw) {
49932
+ const collapsed = raw.replace(/\s+/g, " ").trim();
49933
+ const stripped = collapsed.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
49934
+ const normalized = stripped.replace(/\s+/g, " ").trim();
49935
+ if (normalized.length <= MAX_INSTRUCTIONS_LEN)
49936
+ return normalized;
49937
+ return `${normalized.slice(0, MAX_INSTRUCTIONS_LEN)}\u2026`;
49938
+ }
49939
+ function hasNonAsciiHostname(hostname5) {
49940
+ for (const ch of hostname5) {
49941
+ const cp = ch.codePointAt(0);
49942
+ if (cp !== undefined && cp > 127)
49943
+ return true;
49944
+ }
49945
+ return false;
49946
+ }
49927
49947
  function isPrivateHost2(url3) {
49928
49948
  const host = url3.hostname.toLowerCase();
49929
49949
  if (host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "0.0.0.0") {
@@ -49958,8 +49978,7 @@ function validateAndSanitizeUrl2(rawUrl) {
49958
49978
  }
49959
49979
  try {
49960
49980
  const url3 = new URL(sanitized);
49961
- const hostname5 = url3.hostname;
49962
- if (/[\u0080-\u{10FFFF}]/u.test(hostname5)) {
49981
+ if (hasNonAsciiHostname(url3.hostname)) {
49963
49982
  return { error: "Non-ASCII hostnames are not allowed" };
49964
49983
  }
49965
49984
  if (isPrivateHost2(url3)) {
@@ -49976,18 +49995,7 @@ function validateAndSanitizeUrl2(rawUrl) {
49976
49995
  return { error: "Invalid URL format" };
49977
49996
  }
49978
49997
  }
49979
- function parseArgs5(args) {
49980
- const out = { council: false, rest: [] };
49981
- for (const token of args) {
49982
- if (token === "--council") {
49983
- out.council = true;
49984
- continue;
49985
- }
49986
- out.rest.push(token);
49987
- }
49988
- return out;
49989
- }
49990
- function parsePrRef(input) {
49998
+ function parsePrRef(input, cwd) {
49991
49999
  const urlMatch = input.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/i);
49992
50000
  if (urlMatch) {
49993
50001
  return {
@@ -50007,7 +50015,7 @@ function parsePrRef(input) {
50007
50015
  const bareMatch = input.match(/^(\d+)$/);
50008
50016
  if (bareMatch) {
50009
50017
  const prNumber = parseInt(bareMatch[1], 10);
50010
- const remoteUrl = detectGitRemote2();
50018
+ const remoteUrl = detectGitRemote2(cwd);
50011
50019
  if (!remoteUrl) {
50012
50020
  return null;
50013
50021
  }
@@ -50023,12 +50031,13 @@ function parsePrRef(input) {
50023
50031
  }
50024
50032
  return null;
50025
50033
  }
50026
- function detectGitRemote2() {
50034
+ function detectGitRemote2(cwd) {
50027
50035
  try {
50028
- const remoteUrl = execSync3("git remote get-url origin", {
50036
+ const remoteUrl = _internals21.execSync("git remote get-url origin", {
50029
50037
  encoding: "utf-8",
50030
50038
  stdio: ["pipe", "pipe", "pipe"],
50031
- timeout: 5000
50039
+ timeout: 5000,
50040
+ ...cwd ? { cwd } : {}
50032
50041
  }).trim();
50033
50042
  return remoteUrl || null;
50034
50043
  } catch {
@@ -50059,41 +50068,115 @@ function parseGitRemoteUrl2(remoteUrl) {
50059
50068
  }
50060
50069
  return null;
50061
50070
  }
50062
- function handlePrReviewCommand(_directory, args) {
50063
- const parsed = parseArgs5(args);
50064
- const rawInput = parsed.rest.join(" ").trim();
50065
- if (!rawInput) {
50066
- return USAGE5;
50071
+ function looksLikePrRef(token) {
50072
+ return /^https?:\/\//i.test(token) || /^[^/]+\/[^#]+#\d+$/.test(token) || /^\d+$/.test(token);
50073
+ }
50074
+ function resolvePrCommandInput(rest, cwd) {
50075
+ if (rest.length === 0) {
50076
+ return null;
50067
50077
  }
50068
- const isFullUrl = /^https?:\/\//i.test(rawInput);
50069
- const prInfo = parsePrRef(isFullUrl ? sanitizeUrl2(rawInput) : rawInput);
50078
+ const refToken = rest[0];
50079
+ const instructions = sanitizeInstructions(rest.slice(1).join(" "));
50080
+ const isFullUrl = /^https?:\/\//i.test(refToken);
50081
+ const prInfo = parsePrRef(isFullUrl ? sanitizeUrl2(refToken) : refToken, cwd);
50070
50082
  if (!prInfo) {
50071
- return `Error: Could not parse PR reference from "${rawInput}"
50072
-
50073
- ${USAGE5}`;
50083
+ return { error: `Could not parse PR reference from "${refToken}"` };
50074
50084
  }
50075
50085
  const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
50076
50086
  const result = validateAndSanitizeUrl2(prUrl);
50077
50087
  if ("error" in result) {
50078
- return `Error: ${result.error}
50088
+ return { error: result.error };
50089
+ }
50090
+ return { prUrl: result.sanitized, instructions };
50091
+ }
50092
+ var _internals21, MAX_URL_LEN2 = 2048, MAX_INSTRUCTIONS_LEN = 1000;
50093
+ var init_pr_ref = __esm(() => {
50094
+ _internals21 = { execSync: execSync3 };
50095
+ });
50096
+
50097
+ // src/commands/pr-feedback.ts
50098
+ function handlePrFeedbackCommand(directory, args) {
50099
+ const rest = args.filter((t) => t.trim().length > 0);
50100
+ if (rest.length === 0) {
50101
+ return "[MODE: PR_FEEDBACK]";
50102
+ }
50103
+ const resolved = resolvePrCommandInput(rest, directory);
50104
+ if (resolved && "prUrl" in resolved) {
50105
+ const signal = `[MODE: PR_FEEDBACK pr="${resolved.prUrl}"]`;
50106
+ return resolved.instructions ? `${signal} ${resolved.instructions}` : signal;
50107
+ }
50108
+ if (resolved && "error" in resolved && looksLikePrRef(rest[0])) {
50109
+ return [
50110
+ `Error: ${resolved.error}`,
50111
+ "",
50112
+ "That looked like a PR reference but could not be resolved. Pass a full",
50113
+ "URL or `owner/repo#N`, or omit the reference to start a no-PR feedback",
50114
+ "session (e.g. `/swarm pr-feedback address the review notes`)."
50115
+ ].join(`
50116
+ `);
50117
+ }
50118
+ const instructions = sanitizeInstructions(rest.join(" "));
50119
+ return instructions ? `[MODE: PR_FEEDBACK] ${instructions}` : "[MODE: PR_FEEDBACK]";
50120
+ }
50121
+ var init_pr_feedback = __esm(() => {
50122
+ init_pr_ref();
50123
+ });
50124
+
50125
+ // src/commands/pr-review.ts
50126
+ function parseArgs5(args) {
50127
+ const out = { council: false, rest: [] };
50128
+ for (const token of args) {
50129
+ if (token === "--council") {
50130
+ out.council = true;
50131
+ continue;
50132
+ }
50133
+ if (token.startsWith("--")) {
50134
+ if (out.unknownFlag === undefined)
50135
+ out.unknownFlag = token;
50136
+ continue;
50137
+ }
50138
+ if (token.trim().length === 0)
50139
+ continue;
50140
+ out.rest.push(token);
50141
+ }
50142
+ return out;
50143
+ }
50144
+ function handlePrReviewCommand(directory, args) {
50145
+ const parsed = parseArgs5(args);
50146
+ if (parsed.unknownFlag) {
50147
+ return `Error: Unknown flag "${parsed.unknownFlag}"
50148
+
50149
+ ${USAGE5}`;
50150
+ }
50151
+ const resolved = resolvePrCommandInput(parsed.rest, directory);
50152
+ if (resolved === null) {
50153
+ return USAGE5;
50154
+ }
50155
+ if ("error" in resolved) {
50156
+ return `Error: ${resolved.error}
50079
50157
 
50080
50158
  ${USAGE5}`;
50081
50159
  }
50082
50160
  const councilFlag = parsed.council ? "council=true" : "council=false";
50083
- return `[MODE: PR_REVIEW pr="${result.sanitized}" ${councilFlag}]`;
50161
+ const signal = `[MODE: PR_REVIEW pr="${resolved.prUrl}" ${councilFlag}]`;
50162
+ return resolved.instructions ? `${signal} ${resolved.instructions}` : signal;
50084
50163
  }
50085
- var MAX_URL_LEN2 = 2048, USAGE5;
50164
+ var USAGE5;
50086
50165
  var init_pr_review = __esm(() => {
50166
+ init_pr_ref();
50087
50167
  USAGE5 = [
50088
- "Usage: /swarm pr-review <url|owner/repo#N|N> [--council]",
50168
+ "Usage: /swarm pr-review <url|owner/repo#N|N> [--council] [instructions...]",
50089
50169
  "",
50090
50170
  "Run a full swarm PR review on a GitHub pull request.",
50091
50171
  " /swarm pr-review https://github.com/owner/repo/pull/42",
50092
50172
  " /swarm pr-review owner/repo#42",
50093
50173
  " /swarm pr-review 42 --council",
50174
+ " /swarm pr-review 42 focus on the auth refactor and the new retry logic",
50094
50175
  "",
50095
50176
  "Flags:",
50096
- " --council Run adversarial council variant (all lanes assume work is wrong)"
50177
+ " --council Run adversarial council variant (all lanes assume work is wrong)",
50178
+ "",
50179
+ "Any text after the PR reference is forwarded to the reviewer as extra instructions."
50097
50180
  ].join(`
50098
50181
  `);
50099
50182
  });
@@ -50483,7 +50566,7 @@ async function runAdditionalLint(linter, mode, cwd) {
50483
50566
  };
50484
50567
  }
50485
50568
  }
50486
- var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals21;
50569
+ var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals22;
50487
50570
  var init_lint = __esm(() => {
50488
50571
  init_zod();
50489
50572
  init_discovery();
@@ -50515,15 +50598,15 @@ var init_lint = __esm(() => {
50515
50598
  }
50516
50599
  const { mode } = args;
50517
50600
  const cwd = directory;
50518
- const linter = await _internals21.detectAvailableLinter(directory);
50601
+ const linter = await _internals22.detectAvailableLinter(directory);
50519
50602
  if (linter) {
50520
- const result = await _internals21.runLint(linter, mode, directory);
50603
+ const result = await _internals22.runLint(linter, mode, directory);
50521
50604
  return JSON.stringify(result, null, 2);
50522
50605
  }
50523
- const additionalLinter = _internals21.detectAdditionalLinter(cwd);
50606
+ const additionalLinter = _internals22.detectAdditionalLinter(cwd);
50524
50607
  if (additionalLinter) {
50525
50608
  warn(`[lint] Using ${additionalLinter} linter for this project`);
50526
- const result = await _internals21.runAdditionalLint(additionalLinter, mode, cwd);
50609
+ const result = await _internals22.runAdditionalLint(additionalLinter, mode, cwd);
50527
50610
  return JSON.stringify(result, null, 2);
50528
50611
  }
50529
50612
  const errorResult = {
@@ -50537,7 +50620,7 @@ For Rust: rustup component add clippy`
50537
50620
  return JSON.stringify(errorResult, null, 2);
50538
50621
  }
50539
50622
  });
50540
- _internals21 = {
50623
+ _internals22 = {
50541
50624
  detectAvailableLinter,
50542
50625
  runLint,
50543
50626
  detectAdditionalLinter,
@@ -50851,7 +50934,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
50851
50934
  }
50852
50935
  async function runSecretscan(directory) {
50853
50936
  try {
50854
- const result = await _internals22.secretscan.execute({ directory }, {});
50937
+ const result = await _internals23.secretscan.execute({ directory }, {});
50855
50938
  const jsonStr = typeof result === "string" ? result : result.output;
50856
50939
  return JSON.parse(jsonStr);
50857
50940
  } catch (e) {
@@ -50866,7 +50949,7 @@ async function runSecretscan(directory) {
50866
50949
  return errorResult;
50867
50950
  }
50868
50951
  }
50869
- var MAX_FILE_PATH_LENGTH = 500, MAX_FILE_SIZE_BYTES, MAX_FILES_SCANNED = 1000, MAX_FINDINGS = 100, MAX_OUTPUT_BYTES2 = 512000, MAX_LINE_LENGTH = 1e4, MAX_CONTENT_BYTES, BINARY_SIGNATURES, BINARY_PREFIX_BYTES = 4, BINARY_NULL_CHECK_BYTES = 8192, BINARY_NULL_THRESHOLD = 0.1, DEFAULT_EXCLUDE_DIRS, DEFAULT_EXCLUDE_EXTENSIONS, SECRET_PATTERNS2, O_NOFOLLOW, secretscan, _internals22;
50952
+ var MAX_FILE_PATH_LENGTH = 500, MAX_FILE_SIZE_BYTES, MAX_FILES_SCANNED = 1000, MAX_FINDINGS = 100, MAX_OUTPUT_BYTES2 = 512000, MAX_LINE_LENGTH = 1e4, MAX_CONTENT_BYTES, BINARY_SIGNATURES, BINARY_PREFIX_BYTES = 4, BINARY_NULL_CHECK_BYTES = 8192, BINARY_NULL_THRESHOLD = 0.1, DEFAULT_EXCLUDE_DIRS, DEFAULT_EXCLUDE_EXTENSIONS, SECRET_PATTERNS2, O_NOFOLLOW, secretscan, _internals23;
50870
50953
  var init_secretscan = __esm(() => {
50871
50954
  init_zod();
50872
50955
  init_path_security();
@@ -51238,7 +51321,7 @@ var init_secretscan = __esm(() => {
51238
51321
  }
51239
51322
  }
51240
51323
  });
51241
- _internals22 = {
51324
+ _internals23 = {
51242
51325
  secretscan,
51243
51326
  runSecretscan
51244
51327
  };
@@ -51830,14 +51913,14 @@ function buildGoBackend() {
51830
51913
  selectEntryPoints
51831
51914
  };
51832
51915
  }
51833
- var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE, _internals23;
51916
+ var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE, _internals24;
51834
51917
  var init_go = __esm(() => {
51835
51918
  init_default_backend();
51836
51919
  init_profiles();
51837
51920
  IMPORT_REGEX_SINGLE = /^\s*import\s+(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/gm;
51838
51921
  IMPORT_REGEX_GROUP = /^\s*import\s*\(([\s\S]*?)\)/gm;
51839
51922
  IMPORT_REGEX_GROUP_LINE = /(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/g;
51840
- _internals23 = { extractImports };
51923
+ _internals24 = { extractImports };
51841
51924
  });
51842
51925
 
51843
51926
  // src/lang/backends/python.ts
@@ -51949,13 +52032,13 @@ function buildPythonBackend() {
51949
52032
  selectEntryPoints: selectEntryPoints2
51950
52033
  };
51951
52034
  }
51952
- var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT, _internals24;
52035
+ var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT, _internals25;
51953
52036
  var init_python = __esm(() => {
51954
52037
  init_default_backend();
51955
52038
  init_profiles();
51956
52039
  IMPORT_REGEX_FROM_WITH_TARGETS = /^\s*from\s+(\.*[\w.]*)\s+import\s+(\([^)]*\)|[^\n#]+)/gm;
51957
52040
  IMPORT_REGEX_IMPORT = /^\s*import\s+([^\n#]+)/gm;
51958
- _internals24 = { extractImports: extractImports2 };
52041
+ _internals25 = { extractImports: extractImports2 };
51959
52042
  });
51960
52043
 
51961
52044
  // src/test-impact/analyzer.ts
@@ -52179,7 +52262,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
52179
52262
  return;
52180
52263
  }
52181
52264
  if (PYTHON_EXTENSIONS.has(ext)) {
52182
- const modules = _internals24.extractImports(testFile, content);
52265
+ const modules = _internals25.extractImports(testFile, content);
52183
52266
  for (const mod of modules) {
52184
52267
  const resolved = resolvePythonImport(testDir, mod);
52185
52268
  if (resolved !== null)
@@ -52188,7 +52271,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
52188
52271
  return;
52189
52272
  }
52190
52273
  if (GO_EXTENSIONS.has(ext)) {
52191
- const imports = _internals23.extractImports(testFile, content);
52274
+ const imports = _internals24.extractImports(testFile, content);
52192
52275
  for (const importPath of imports) {
52193
52276
  const sourceFiles = resolveGoImport(testDir, importPath);
52194
52277
  for (const source of sourceFiles)
@@ -52215,8 +52298,8 @@ async function buildImpactMapInternal(cwd) {
52215
52298
  return impactMap;
52216
52299
  }
52217
52300
  async function buildImpactMap(cwd) {
52218
- const impactMap = await _internals25.buildImpactMapInternal(cwd);
52219
- await _internals25.saveImpactMap(cwd, impactMap);
52301
+ const impactMap = await _internals26.buildImpactMapInternal(cwd);
52302
+ await _internals26.saveImpactMap(cwd, impactMap);
52220
52303
  return impactMap;
52221
52304
  }
52222
52305
  async function loadImpactMap(cwd, options) {
@@ -52230,7 +52313,7 @@ async function loadImpactMap(cwd, options) {
52230
52313
  const hasValidValues = Object.values(map3).every((v) => Array.isArray(v) && v.every((item) => typeof item === "string"));
52231
52314
  if (hasValidValues) {
52232
52315
  const generatedAt = new Date(data.generatedAt).getTime();
52233
- if (!_internals25.isCacheStale(map3, generatedAt)) {
52316
+ if (!_internals26.isCacheStale(map3, generatedAt)) {
52234
52317
  return map3;
52235
52318
  }
52236
52319
  if (options?.skipRebuild) {
@@ -52250,13 +52333,13 @@ async function loadImpactMap(cwd, options) {
52250
52333
  if (options?.skipRebuild) {
52251
52334
  return {};
52252
52335
  }
52253
- return _internals25.buildImpactMap(cwd);
52336
+ return _internals26.buildImpactMap(cwd);
52254
52337
  }
52255
52338
  async function saveImpactMap(cwd, impactMap) {
52256
52339
  if (!path40.isAbsolute(cwd)) {
52257
52340
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
52258
52341
  }
52259
- _internals25.validateProjectRoot(cwd);
52342
+ _internals26.validateProjectRoot(cwd);
52260
52343
  const cacheDir2 = path40.join(cwd, ".swarm", "cache");
52261
52344
  const cachePath = path40.join(cacheDir2, "impact-map.json");
52262
52345
  if (!fs18.existsSync(cacheDir2)) {
@@ -52280,7 +52363,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
52280
52363
  };
52281
52364
  }
52282
52365
  const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
52283
- const impactMap = await _internals25.loadImpactMap(cwd);
52366
+ const impactMap = await _internals26.loadImpactMap(cwd);
52284
52367
  const impactedTestsSet = new Set;
52285
52368
  const untestedFiles = [];
52286
52369
  let visitedCount = 0;
@@ -52365,7 +52448,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
52365
52448
  budgetExceeded
52366
52449
  };
52367
52450
  }
52368
- var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache, _internals25;
52451
+ var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache, _internals26;
52369
52452
  var init_analyzer = __esm(() => {
52370
52453
  init_manager2();
52371
52454
  init_go();
@@ -52378,7 +52461,7 @@ var init_analyzer = __esm(() => {
52378
52461
  GO_EXTENSIONS = new Set([".go"]);
52379
52462
  EXTENSIONS_TO_TRY = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
52380
52463
  goModuleCache = new Map;
52381
- _internals25 = {
52464
+ _internals26 = {
52382
52465
  validateProjectRoot,
52383
52466
  normalizePath,
52384
52467
  isCacheStale,
@@ -52714,7 +52797,7 @@ function batchAppendTestRuns(records, workingDir) {
52714
52797
  }
52715
52798
  const historyPath = getHistoryPath(workingDir);
52716
52799
  const historyDir = path41.dirname(historyPath);
52717
- _internals26.validateProjectRoot(workingDir);
52800
+ _internals27.validateProjectRoot(workingDir);
52718
52801
  if (!fs19.existsSync(historyDir)) {
52719
52802
  fs19.mkdirSync(historyDir, { recursive: true });
52720
52803
  }
@@ -52837,7 +52920,7 @@ function getAllHistory(workingDir) {
52837
52920
  records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
52838
52921
  return records;
52839
52922
  }
52840
- var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, HISTORY_WRITE_LOCK_TIMEOUT_MS = 5000, HISTORY_WRITE_LOCK_STALE_MS = 60000, HISTORY_WRITE_LOCK_BACKOFF_MS = 10, DANGEROUS_PROPERTY_NAMES, _internals26;
52923
+ var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, HISTORY_WRITE_LOCK_TIMEOUT_MS = 5000, HISTORY_WRITE_LOCK_STALE_MS = 60000, HISTORY_WRITE_LOCK_BACKOFF_MS = 10, DANGEROUS_PROPERTY_NAMES, _internals27;
52841
52924
  var init_history_store = __esm(() => {
52842
52925
  init_manager2();
52843
52926
  DANGEROUS_PROPERTY_NAMES = new Set([
@@ -52845,7 +52928,7 @@ var init_history_store = __esm(() => {
52845
52928
  "constructor",
52846
52929
  "prototype"
52847
52930
  ]);
52848
- _internals26 = {
52931
+ _internals27 = {
52849
52932
  validateProjectRoot
52850
52933
  };
52851
52934
  });
@@ -52971,7 +53054,7 @@ function readPackageJsonRaw(dir) {
52971
53054
  }
52972
53055
  }
52973
53056
  function readPackageJson(dir) {
52974
- return _internals27.readPackageJsonRaw(dir);
53057
+ return _internals28.readPackageJsonRaw(dir);
52975
53058
  }
52976
53059
  function readPackageJsonTestScript(dir) {
52977
53060
  return readPackageJson(dir)?.scripts?.test ?? null;
@@ -53141,7 +53224,7 @@ function buildTypescriptBackend() {
53141
53224
  selectEntryPoints: selectEntryPoints3
53142
53225
  };
53143
53226
  }
53144
- var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals27;
53227
+ var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals28;
53145
53228
  var init_typescript = __esm(() => {
53146
53229
  init_default_backend();
53147
53230
  init_profiles();
@@ -53150,7 +53233,7 @@ var init_typescript = __esm(() => {
53150
53233
  IMPORT_REGEX_REQUIRE2 = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
53151
53234
  IMPORT_REGEX_DYNAMIC = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
53152
53235
  IMPORT_REGEX_REEXPORT2 = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
53153
- _internals27 = {
53236
+ _internals28 = {
53154
53237
  readPackageJsonRaw,
53155
53238
  readPackageJsonTestScript,
53156
53239
  frameworkFromScriptsTest
@@ -53181,7 +53264,7 @@ __export(exports_dispatch, {
53181
53264
  pickedProfiles: () => pickedProfiles,
53182
53265
  pickBackend: () => pickBackend,
53183
53266
  clearDispatchCache: () => clearDispatchCache,
53184
- _internals: () => _internals28
53267
+ _internals: () => _internals29
53185
53268
  });
53186
53269
  import * as fs22 from "fs";
53187
53270
  import * as path44 from "path";
@@ -53236,7 +53319,7 @@ function findManifestRoot(start) {
53236
53319
  return start;
53237
53320
  }
53238
53321
  function evictIfNeeded() {
53239
- if (cache.size <= _internals28.cacheCapacity)
53322
+ if (cache.size <= _internals29.cacheCapacity)
53240
53323
  return;
53241
53324
  let oldestKey;
53242
53325
  let oldestOrder = Infinity;
@@ -53267,7 +53350,7 @@ async function pickBackend(dir) {
53267
53350
  evictIfNeeded();
53268
53351
  return null;
53269
53352
  }
53270
- const profiles = await _internals28.detectProjectLanguages(root);
53353
+ const profiles = await _internals29.detectProjectLanguages(root);
53271
53354
  if (profiles.length === 0) {
53272
53355
  cache.set(cacheKey, {
53273
53356
  hash: hash3,
@@ -53299,12 +53382,12 @@ function clearDispatchCache() {
53299
53382
  manifestRootCache.clear();
53300
53383
  insertCounter = 0;
53301
53384
  }
53302
- var _internals28, cache, insertCounter = 0, MANIFEST_FILES, _MANIFEST_SET, manifestRootCache;
53385
+ var _internals29, cache, insertCounter = 0, MANIFEST_FILES, _MANIFEST_SET, manifestRootCache;
53303
53386
  var init_dispatch = __esm(() => {
53304
53387
  init_backends();
53305
53388
  init_detector();
53306
53389
  init_registry_backend();
53307
- _internals28 = {
53390
+ _internals29 = {
53308
53391
  detectProjectLanguages,
53309
53392
  cacheCapacity: 64
53310
53393
  };
@@ -55161,9 +55244,9 @@ function getVersionFileVersion(dir) {
55161
55244
  async function runVersionCheck(dir, _timeoutMs) {
55162
55245
  const startTime = Date.now();
55163
55246
  try {
55164
- const packageVersion = _internals29.getPackageVersion(dir);
55165
- const changelogVersion = _internals29.getChangelogVersion(dir);
55166
- const versionFileVersion = _internals29.getVersionFileVersion(dir);
55247
+ const packageVersion = _internals30.getPackageVersion(dir);
55248
+ const changelogVersion = _internals30.getChangelogVersion(dir);
55249
+ const versionFileVersion = _internals30.getVersionFileVersion(dir);
55167
55250
  const versions3 = [];
55168
55251
  if (packageVersion)
55169
55252
  versions3.push(`package.json: ${packageVersion}`);
@@ -55528,7 +55611,7 @@ async function runPreflight(dir, phase, config3) {
55528
55611
  const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
55529
55612
  let validatedDir;
55530
55613
  try {
55531
- validatedDir = _internals29.validateDirectoryPath(dir);
55614
+ validatedDir = _internals30.validateDirectoryPath(dir);
55532
55615
  } catch (error93) {
55533
55616
  return {
55534
55617
  id: reportId,
@@ -55548,7 +55631,7 @@ async function runPreflight(dir, phase, config3) {
55548
55631
  }
55549
55632
  let validatedTimeout;
55550
55633
  try {
55551
- validatedTimeout = _internals29.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
55634
+ validatedTimeout = _internals30.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
55552
55635
  } catch (error93) {
55553
55636
  return {
55554
55637
  id: reportId,
@@ -55589,12 +55672,12 @@ async function runPreflight(dir, phase, config3) {
55589
55672
  });
55590
55673
  const checks5 = [];
55591
55674
  log("[Preflight] Running lint check...");
55592
- const lintResult = await _internals29.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
55675
+ const lintResult = await _internals30.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
55593
55676
  checks5.push(lintResult);
55594
55677
  log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
55595
55678
  if (!cfg.skipTests) {
55596
55679
  log("[Preflight] Running tests check...");
55597
- const testsResult = await _internals29.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
55680
+ const testsResult = await _internals30.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
55598
55681
  checks5.push(testsResult);
55599
55682
  log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
55600
55683
  } else {
@@ -55606,7 +55689,7 @@ async function runPreflight(dir, phase, config3) {
55606
55689
  }
55607
55690
  if (!cfg.skipSecrets) {
55608
55691
  log("[Preflight] Running secrets check...");
55609
- const secretsResult = await _internals29.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
55692
+ const secretsResult = await _internals30.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
55610
55693
  checks5.push(secretsResult);
55611
55694
  log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
55612
55695
  } else {
@@ -55618,7 +55701,7 @@ async function runPreflight(dir, phase, config3) {
55618
55701
  }
55619
55702
  if (!cfg.skipEvidence) {
55620
55703
  log("[Preflight] Running evidence check...");
55621
- const evidenceResult = await _internals29.runEvidenceCheck(validatedDir);
55704
+ const evidenceResult = await _internals30.runEvidenceCheck(validatedDir);
55622
55705
  checks5.push(evidenceResult);
55623
55706
  log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
55624
55707
  } else {
@@ -55629,12 +55712,12 @@ async function runPreflight(dir, phase, config3) {
55629
55712
  });
55630
55713
  }
55631
55714
  log("[Preflight] Running requirement coverage check...");
55632
- const reqCoverageResult = await _internals29.runRequirementCoverageCheck(validatedDir, phase);
55715
+ const reqCoverageResult = await _internals30.runRequirementCoverageCheck(validatedDir, phase);
55633
55716
  checks5.push(reqCoverageResult);
55634
55717
  log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
55635
55718
  if (!cfg.skipVersion) {
55636
55719
  log("[Preflight] Running version check...");
55637
- const versionResult = await _internals29.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
55720
+ const versionResult = await _internals30.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
55638
55721
  checks5.push(versionResult);
55639
55722
  log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
55640
55723
  } else {
@@ -55697,10 +55780,10 @@ function formatPreflightMarkdown(report) {
55697
55780
  async function handlePreflightCommand(directory, _args) {
55698
55781
  const plan = await loadPlan(directory);
55699
55782
  const phase = plan?.current_phase ?? 1;
55700
- const report = await _internals29.runPreflight(directory, phase);
55701
- return _internals29.formatPreflightMarkdown(report);
55783
+ const report = await _internals30.runPreflight(directory, phase);
55784
+ return _internals30.formatPreflightMarkdown(report);
55702
55785
  }
55703
- var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG, _internals29;
55786
+ var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG, _internals30;
55704
55787
  var init_preflight_service = __esm(() => {
55705
55788
  init_gate_bridge();
55706
55789
  init_manager2();
@@ -55718,7 +55801,7 @@ var init_preflight_service = __esm(() => {
55718
55801
  testScope: "convention",
55719
55802
  linter: "biome"
55720
55803
  };
55721
- _internals29 = {
55804
+ _internals30 = {
55722
55805
  runPreflight,
55723
55806
  formatPreflightMarkdown,
55724
55807
  handlePreflightCommand,
@@ -57340,7 +57423,7 @@ async function getStatusData(directory, agents) {
57340
57423
  }
57341
57424
  function enrichWithLeanTurbo(status, directory) {
57342
57425
  const turboMode = hasActiveTurboMode();
57343
- const leanActive = _internals30.hasActiveLeanTurbo();
57426
+ const leanActive = _internals31.hasActiveLeanTurbo();
57344
57427
  let turboStrategy = "off";
57345
57428
  if (leanActive) {
57346
57429
  turboStrategy = "lean";
@@ -57359,7 +57442,7 @@ function enrichWithLeanTurbo(status, directory) {
57359
57442
  }
57360
57443
  }
57361
57444
  if (leanSessionID) {
57362
- const runState = _internals30.loadLeanTurboRunState(directory, leanSessionID);
57445
+ const runState = _internals31.loadLeanTurboRunState(directory, leanSessionID);
57363
57446
  if (runState) {
57364
57447
  status.leanTurboPhase = runState.phase;
57365
57448
  status.leanMaxParallelCoders = runState.maxParallelCoders;
@@ -57391,7 +57474,7 @@ function enrichWithLeanTurbo(status, directory) {
57391
57474
  }
57392
57475
  }
57393
57476
  }
57394
- status.fullAutoActive = _internals30.hasActiveFullAuto();
57477
+ status.fullAutoActive = _internals31.hasActiveFullAuto();
57395
57478
  return status;
57396
57479
  }
57397
57480
  function formatStatusMarkdown(status) {
@@ -57473,7 +57556,7 @@ async function handleStatusCommand(directory, agents) {
57473
57556
  }
57474
57557
  return formatStatusMarkdown(statusData);
57475
57558
  }
57476
- var _internals30;
57559
+ var _internals31;
57477
57560
  var init_status_service = __esm(() => {
57478
57561
  init_extractors();
57479
57562
  init_utils2();
@@ -57482,7 +57565,7 @@ var init_status_service = __esm(() => {
57482
57565
  init_state3();
57483
57566
  init_compaction_service();
57484
57567
  init_context_budget_service();
57485
- _internals30 = {
57568
+ _internals31 = {
57486
57569
  loadLeanTurboRunState,
57487
57570
  hasActiveLeanTurbo,
57488
57571
  hasActiveFullAuto
@@ -57573,7 +57656,7 @@ async function handleTurboCommand(directory, args, sessionID) {
57573
57656
  if (arg0 === "on") {
57574
57657
  let strategy = "standard";
57575
57658
  try {
57576
- const { config: config3 } = _internals31.loadPluginConfigWithMeta(directory);
57659
+ const { config: config3 } = _internals32.loadPluginConfigWithMeta(directory);
57577
57660
  if (config3.turbo?.strategy === "lean") {
57578
57661
  strategy = "lean";
57579
57662
  }
@@ -57628,7 +57711,7 @@ function enableLeanTurbo(session, directory, sessionID) {
57628
57711
  let maxParallelCoders = 4;
57629
57712
  let conflictPolicy = "serialize";
57630
57713
  try {
57631
- const { config: config3 } = _internals31.loadPluginConfigWithMeta(directory);
57714
+ const { config: config3 } = _internals32.loadPluginConfigWithMeta(directory);
57632
57715
  const leanConfig = config3.turbo?.lean;
57633
57716
  if (leanConfig) {
57634
57717
  maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
@@ -57698,13 +57781,13 @@ function buildStatusMessage2(session, directory, sessionID) {
57698
57781
  ].join(`
57699
57782
  `);
57700
57783
  }
57701
- var _internals31;
57784
+ var _internals32;
57702
57785
  var init_turbo = __esm(() => {
57703
57786
  init_config();
57704
57787
  init_state();
57705
57788
  init_state3();
57706
57789
  init_logger();
57707
- _internals31 = {
57790
+ _internals32 = {
57708
57791
  loadPluginConfigWithMeta
57709
57792
  };
57710
57793
  });
@@ -57797,7 +57880,7 @@ function formatCommandNotFound(tokens) {
57797
57880
  const attemptedCommand = tokens[0] || "";
57798
57881
  const MAX_DISPLAY = 100;
57799
57882
  const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
57800
- const similar = _internals32.findSimilarCommands(attemptedCommand);
57883
+ const similar = _internals33.findSimilarCommands(attemptedCommand);
57801
57884
  const header = `Command \`/swarm ${displayCommand}\` not found.`;
57802
57885
  const suggestions = similar.length > 0 ? `Did you mean:
57803
57886
  ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
@@ -58299,7 +58382,7 @@ async function buildSwarmCommandPrompt(args) {
58299
58382
  activeAgentName,
58300
58383
  registeredAgents
58301
58384
  } = args;
58302
- const resolved = _internals32.resolveCommand(tokens);
58385
+ const resolved = _internals33.resolveCommand(tokens);
58303
58386
  if (!resolved) {
58304
58387
  if (tokens.length === 0) {
58305
58388
  return buildHelpText();
@@ -58360,6 +58443,19 @@ function agentHasSwarmCommandTool(activeAgentName, agents, registeredAgents) {
58360
58443
  return AGENT_TOOL_MAP[baseName]?.includes("swarm_command") === true;
58361
58444
  }
58362
58445
  function formatCanonicalPromptFallback(args) {
58446
+ if (/^\s*\[MODE:/.test(args.text)) {
58447
+ return [
58448
+ `The user typed \`${args.original}\`.`,
58449
+ "The line below is a swarm MODE-activation signal, NOT output to display.",
58450
+ "Enter the mode named in its `[MODE: X ...]` header now: follow your",
58451
+ 'prompt\u2019s "### MODE: X" section, load the SKILL.md it references, and',
58452
+ "follow that protocol exactly. Treat any text after the closing bracket as",
58453
+ "additional instructions. Do NOT echo this signal verbatim.",
58454
+ "",
58455
+ args.text
58456
+ ].join(`
58457
+ `);
58458
+ }
58363
58459
  return [
58364
58460
  `The user typed \`${args.original}\`.`,
58365
58461
  "Canonical opencode-swarm command output follows.",
@@ -58452,7 +58548,7 @@ function findSimilarCommands(query) {
58452
58548
  }
58453
58549
  const scored = VALID_COMMANDS.map((cmd) => {
58454
58550
  const cmdLower = cmd.toLowerCase();
58455
- const fullScore = _internals32.levenshteinDistance(q, cmdLower);
58551
+ const fullScore = _internals33.levenshteinDistance(q, cmdLower);
58456
58552
  let tokenScore = Infinity;
58457
58553
  if (cmd.includes(" ") || cmd.includes("-")) {
58458
58554
  const qTokens = q.split(/[\s-]+/);
@@ -58465,7 +58561,7 @@ function findSimilarCommands(query) {
58465
58561
  for (const ct of cmdTokens) {
58466
58562
  if (ct.length === 0)
58467
58563
  continue;
58468
- const dist = _internals32.levenshteinDistance(qt, ct);
58564
+ const dist = _internals33.levenshteinDistance(qt, ct);
58469
58565
  if (dist < minDist)
58470
58566
  minDist = dist;
58471
58567
  }
@@ -58475,7 +58571,7 @@ function findSimilarCommands(query) {
58475
58571
  }
58476
58572
  const dashStrippedQ = q.replace(/-/g, "");
58477
58573
  const dashStrippedCmd = cmdLower.replace(/-/g, "");
58478
- const dashScore = _internals32.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
58574
+ const dashScore = _internals33.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
58479
58575
  const score = Math.min(fullScore, tokenScore, dashScore);
58480
58576
  return { cmd, score };
58481
58577
  });
@@ -58507,11 +58603,11 @@ async function handleHelpCommand(ctx) {
58507
58603
  return buildHelpText2();
58508
58604
  }
58509
58605
  const tokens = targetCommand.split(/\s+/);
58510
- const resolved = _internals32.resolveCommand(tokens);
58606
+ const resolved = _internals33.resolveCommand(tokens);
58511
58607
  if (resolved) {
58512
- return _internals32.buildDetailedHelp(resolved.key, resolved.entry);
58608
+ return _internals33.buildDetailedHelp(resolved.key, resolved.entry);
58513
58609
  }
58514
- const similar = _internals32.findSimilarCommands(targetCommand);
58610
+ const similar = _internals33.findSimilarCommands(targetCommand);
58515
58611
  const { buildHelpText: fullHelp } = await Promise.resolve().then(() => (init_commands(), exports_commands));
58516
58612
  if (similar.length > 0) {
58517
58613
  return `Command '/swarm ${targetCommand}' not found.
@@ -58605,7 +58701,7 @@ function resolveCommand(tokens) {
58605
58701
  }
58606
58702
  return null;
58607
58703
  }
58608
- var COMMAND_REGISTRY, VALID_COMMANDS, _internals32, validation;
58704
+ var COMMAND_REGISTRY, VALID_COMMANDS, _internals33, validation;
58609
58705
  var init_registry = __esm(() => {
58610
58706
  init_acknowledge_spec_drift();
58611
58707
  init_agents();
@@ -58631,6 +58727,7 @@ var init_registry = __esm(() => {
58631
58727
  init_knowledge();
58632
58728
  init_memory2();
58633
58729
  init_plan();
58730
+ init_pr_feedback();
58634
58731
  init_pr_review();
58635
58732
  init_preflight();
58636
58733
  init_promote();
@@ -58678,7 +58775,7 @@ var init_registry = __esm(() => {
58678
58775
  clashesWithNativeCcCommand: "/agents"
58679
58776
  },
58680
58777
  help: {
58681
- handler: (ctx) => _internals32.handleHelpCommand(ctx),
58778
+ handler: (ctx) => _internals33.handleHelpCommand(ctx),
58682
58779
  description: "Show help for swarm commands",
58683
58780
  category: "core",
58684
58781
  args: "[command]",
@@ -58911,7 +59008,7 @@ Subcommands:
58911
59008
  handler: (ctx) => handleCouncilCommand(ctx.directory, ctx.args),
58912
59009
  description: "Enter architect MODE: COUNCIL \u2014 multi-model deliberation [question] [--preset <name>] [--spec-review]",
58913
59010
  args: "<question> [--preset <name>] [--spec-review]",
58914
- details: "Triggers the architect to convene a three-agent General Council: Generalist (reviewer model), Skeptic (critic model), and Domain Expert (SME model). Use --preset <name> to choose a named member preset from council.general.presets. " + "The architect first runs 1\u20133 targeted web searches and passes a compiled RESEARCH CONTEXT " + "to all three agents before dispatching them in parallel. Agents deliberate using the NSED peer-review protocol (Round 1 independent analysis, Round 2 MAINTAIN/CONCEDE/NUANCE for disagreements). The architect synthesizes the final answer directly from convene_general_council output. --spec-review switches to single-pass advisory mode for spec review. Requires council.general.enabled: true and a search API key in opencode-swarm.json.",
59011
+ details: "Triggers the architect to convene a three-agent General Council: Generalist (reviewer model), Skeptic (critic model), and Domain Expert (SME model). Use --preset <name> to choose a named member preset from council.general.presets. " + "The architect first runs 1\u20133 targeted web searches and passes a compiled RESEARCH CONTEXT " + "to all three agents before dispatching them in parallel. Agents deliberate using the NSED peer-review protocol (Round 1 independent analysis, Round 2 MAINTAIN/CONCEDE/NUANCE for disagreements). The architect synthesizes the final answer directly from convene_general_council output. --spec-review switches to single-pass advisory mode for spec review. Requires council.general.enabled: true and a search API key in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",
58915
59012
  category: "agent"
58916
59013
  },
58917
59014
  "pr-review": {
@@ -58921,6 +59018,13 @@ Subcommands:
58921
59018
  details: "Launches a structured PR review: reconstructs PR intent via obligation extraction cascade, runs 6 parallel explorer lanes (correctness, security, dependencies, docs-intent-vs-actual, tests, performance-architecture), validates findings through independent reviewer confirmation, applies critic challenge to HIGH/CRITICAL findings, synthesizes structured report. --council variant fires adversarial multi-model review. Supports full GitHub URL, owner/repo#N shorthand, or bare PR number (resolves against origin remote).",
58922
59019
  category: "agent"
58923
59020
  },
59021
+ "pr-feedback": {
59022
+ handler: async (ctx) => handlePrFeedbackCommand(ctx.directory, ctx.args),
59023
+ description: "Ingest and close known PR feedback (review comments, CI failures, conflicts) [pr] [instructions]",
59024
+ args: "[url|owner/repo#N|N] [instructions...]",
59025
+ details: "Triggers MODE: PR_FEEDBACK \u2014 ingests existing pull-request feedback (review threads, requested changes, CI/check failures, merge conflicts, stale branch state, pasted notes), verifies every claim against source, clusters related problems, fixes confirmed items, validates the branch, and reports closure status for every ledger item. Distinct from /swarm pr-review, which discovers new findings. The PR reference is optional: with none, the architect builds the ledger from the current PR/branch; text after the reference is forwarded as extra instructions. Supports full GitHub URL, owner/repo#N shorthand, or bare PR number (resolved against origin).",
59026
+ category: "agent"
59027
+ },
58924
59028
  "deep-dive": {
58925
59029
  handler: async (ctx) => handleDeepDiveCommand(ctx.directory, ctx.args),
58926
59030
  description: "Launch deep codebase audit with parallel explorer waves, dual reviewers, and critic challenge [scope]",
@@ -59149,7 +59253,7 @@ Subcommands:
59149
59253
  }
59150
59254
  };
59151
59255
  VALID_COMMANDS = Object.keys(COMMAND_REGISTRY);
59152
- _internals32 = {
59256
+ _internals33 = {
59153
59257
  handleHelpCommand,
59154
59258
  validateAliases,
59155
59259
  resolveCommand,
@@ -59157,7 +59261,7 @@ Subcommands:
59157
59261
  findSimilarCommands,
59158
59262
  buildDetailedHelp
59159
59263
  };
59160
- validation = _internals32.validateAliases();
59264
+ validation = _internals33.validateAliases();
59161
59265
  if (!validation.valid) {
59162
59266
  throw new Error(`COMMAND_REGISTRY alias validation failed:
59163
59267
  ${validation.errors.join(`