opencode-swarm 7.44.1 → 7.45.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.44.1",
55
+ version: "7.45.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",
@@ -35881,27 +35881,25 @@ function normalizeEntry(raw) {
35881
35881
  ro = {};
35882
35882
  obj.retrieval_outcomes = ro;
35883
35883
  }
35884
- {
35885
- if (typeof ro.shown_count !== "number") {
35886
- ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
35887
- }
35888
- if (typeof ro.acknowledged_count !== "number")
35889
- ro.acknowledged_count = 0;
35890
- if (typeof ro.applied_explicit_count !== "number") {
35891
- ro.applied_explicit_count = 0;
35892
- }
35893
- if (typeof ro.ignored_count !== "number")
35894
- ro.ignored_count = 0;
35895
- if (typeof ro.violated_count !== "number")
35896
- ro.violated_count = 0;
35897
- if (typeof ro.contradicted_count !== "number")
35898
- ro.contradicted_count = 0;
35899
- if (typeof ro.succeeded_after_shown_count !== "number") {
35900
- ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
35901
- }
35902
- if (typeof ro.failed_after_shown_count !== "number") {
35903
- ro.failed_after_shown_count = typeof ro.failed_after_count === "number" ? ro.failed_after_count : 0;
35904
- }
35884
+ if (typeof ro.shown_count !== "number") {
35885
+ ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
35886
+ }
35887
+ if (typeof ro.acknowledged_count !== "number")
35888
+ ro.acknowledged_count = 0;
35889
+ if (typeof ro.applied_explicit_count !== "number") {
35890
+ ro.applied_explicit_count = 0;
35891
+ }
35892
+ if (typeof ro.ignored_count !== "number")
35893
+ ro.ignored_count = 0;
35894
+ if (typeof ro.violated_count !== "number")
35895
+ ro.violated_count = 0;
35896
+ if (typeof ro.contradicted_count !== "number")
35897
+ ro.contradicted_count = 0;
35898
+ if (typeof ro.succeeded_after_shown_count !== "number") {
35899
+ ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
35900
+ }
35901
+ if (typeof ro.failed_after_shown_count !== "number") {
35902
+ ro.failed_after_shown_count = typeof ro.failed_after_count === "number" ? ro.failed_after_count : 0;
35905
35903
  }
35906
35904
  try {
35907
35905
  if (typeof obj.encounter_score !== "number" || Number.isNaN(obj.encounter_score)) {
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.44.1",
72
+ version: "7.45.0",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -56168,27 +56168,25 @@ function normalizeEntry(raw) {
56168
56168
  ro = {};
56169
56169
  obj.retrieval_outcomes = ro;
56170
56170
  }
56171
- {
56172
- if (typeof ro.shown_count !== "number") {
56173
- ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
56174
- }
56175
- if (typeof ro.acknowledged_count !== "number")
56176
- ro.acknowledged_count = 0;
56177
- if (typeof ro.applied_explicit_count !== "number") {
56178
- ro.applied_explicit_count = 0;
56179
- }
56180
- if (typeof ro.ignored_count !== "number")
56181
- ro.ignored_count = 0;
56182
- if (typeof ro.violated_count !== "number")
56183
- ro.violated_count = 0;
56184
- if (typeof ro.contradicted_count !== "number")
56185
- ro.contradicted_count = 0;
56186
- if (typeof ro.succeeded_after_shown_count !== "number") {
56187
- ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
56188
- }
56189
- if (typeof ro.failed_after_shown_count !== "number") {
56190
- ro.failed_after_shown_count = typeof ro.failed_after_count === "number" ? ro.failed_after_count : 0;
56191
- }
56171
+ if (typeof ro.shown_count !== "number") {
56172
+ ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
56173
+ }
56174
+ if (typeof ro.acknowledged_count !== "number")
56175
+ ro.acknowledged_count = 0;
56176
+ if (typeof ro.applied_explicit_count !== "number") {
56177
+ ro.applied_explicit_count = 0;
56178
+ }
56179
+ if (typeof ro.ignored_count !== "number")
56180
+ ro.ignored_count = 0;
56181
+ if (typeof ro.violated_count !== "number")
56182
+ ro.violated_count = 0;
56183
+ if (typeof ro.contradicted_count !== "number")
56184
+ ro.contradicted_count = 0;
56185
+ if (typeof ro.succeeded_after_shown_count !== "number") {
56186
+ ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
56187
+ }
56188
+ if (typeof ro.failed_after_shown_count !== "number") {
56189
+ ro.failed_after_shown_count = typeof ro.failed_after_count === "number" ? ro.failed_after_count : 0;
56192
56190
  }
56193
56191
  try {
56194
56192
  if (typeof obj.encounter_score !== "number" || Number.isNaN(obj.encounter_score)) {
@@ -97943,6 +97941,12 @@ function extractSignature(node, languageId) {
97943
97941
  return paramsNode.text;
97944
97942
  }
97945
97943
  }
97944
+ if (node.type === "class_declaration" || node.type === "class_definition" || node.type === "class") {
97945
+ const classBodyNode = node.children.find((c) => c !== null && (c.type === "class_body" || c.type === "declaration_list"));
97946
+ if (classBodyNode) {
97947
+ return classBodyNode.text;
97948
+ }
97949
+ }
97946
97950
  return;
97947
97951
  }
97948
97952
  function compareSymbols(oldSymbols, newSymbols) {
@@ -98004,7 +98008,7 @@ function compareSymbols(oldSymbols, newSymbols) {
98004
98008
  return changes;
98005
98009
  }
98006
98010
  function findRenamedSymbol(newSymbol, oldSymbols, matchedOldSymbols) {
98007
- if (newSymbol.category !== "function" && newSymbol.category !== "type") {
98011
+ if (newSymbol.category !== "function" && newSymbol.category !== "type" && newSymbol.category !== "class") {
98008
98012
  return null;
98009
98013
  }
98010
98014
  if (!newSymbol.signature) {
@@ -98236,11 +98240,51 @@ function generateSummaryMarkdown(summary) {
98236
98240
  `);
98237
98241
  }
98238
98242
 
98243
+ // src/utils/git-binary-missing-error.ts
98244
+ class GitBinaryMissingError extends Error {
98245
+ name = "GitBinaryMissingError";
98246
+ constructor(message = "git binary is not available", options) {
98247
+ super(message, options);
98248
+ }
98249
+ }
98250
+ function isGitBinaryMissing(err2) {
98251
+ return typeof err2 === "object" && err2 !== null && "code" in err2 && err2.code === "ENOENT";
98252
+ }
98253
+
98239
98254
  // src/hooks/semantic-diff-injection.ts
98255
+ async function execGit(directory, args2, options) {
98256
+ try {
98257
+ const stdout = await new Promise((resolve31, reject) => {
98258
+ const execOpts = {
98259
+ encoding: "utf-8",
98260
+ cwd: directory,
98261
+ timeout: options?.timeout,
98262
+ maxBuffer: options?.maxBuffer,
98263
+ stdio: ["ignore", "pipe", "pipe"]
98264
+ };
98265
+ child_process5.execFile("git", args2, execOpts, (error93, output, _stderr) => {
98266
+ if (error93) {
98267
+ reject(error93);
98268
+ return;
98269
+ }
98270
+ resolve31(output ?? "");
98271
+ });
98272
+ });
98273
+ return stdout;
98274
+ } catch (err2) {
98275
+ if (isGitBinaryMissing(err2)) {
98276
+ throw new GitBinaryMissingError("git binary is not available", {
98277
+ cause: err2
98278
+ });
98279
+ }
98280
+ throw err2;
98281
+ }
98282
+ }
98240
98283
  async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
98241
98284
  if (changedFiles.length === 0)
98242
98285
  return null;
98243
98286
  try {
98287
+ const realDirectory = fs55.realpathSync(directory);
98244
98288
  const filesToProcess = changedFiles.slice(0, maxFiles);
98245
98289
  const astDiffs = [];
98246
98290
  const graph = getCachedGraph2(directory);
@@ -98260,37 +98304,40 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
98260
98304
  if (relativeToDir.startsWith("..") || path92.isAbsolute(relativeToDir)) {
98261
98305
  continue;
98262
98306
  }
98307
+ let realResolvedPath;
98308
+ try {
98309
+ realResolvedPath = fs55.realpathSync(resolvedPath);
98310
+ } catch {
98311
+ continue;
98312
+ }
98313
+ const realRelativeToDir = path92.relative(realDirectory, realResolvedPath);
98314
+ if (realRelativeToDir.startsWith("..") || path92.isAbsolute(realRelativeToDir)) {
98315
+ continue;
98316
+ }
98263
98317
  try {
98264
98318
  let fileExistsInHead = false;
98265
98319
  try {
98266
- child_process5.execFileSync("git", ["cat-file", "-e", `HEAD:${filePath}`], {
98267
- encoding: "utf-8",
98268
- timeout: 3000,
98269
- cwd: directory,
98270
- stdio: "pipe"
98320
+ await execGit(directory, ["cat-file", "-e", `HEAD:${filePath}`], {
98321
+ timeout: 3000
98271
98322
  });
98272
98323
  fileExistsInHead = true;
98273
98324
  } catch (err2) {
98274
- if (err2.code === "ENOENT") {
98275
- err2._gitBinaryMissing = true;
98325
+ if (err2 instanceof GitBinaryMissingError) {
98276
98326
  throw err2;
98277
98327
  }
98278
98328
  fileExistsInHead = false;
98279
98329
  }
98280
- const oldContent = fileExistsInHead ? child_process5.execFileSync("git", ["show", `HEAD:${filePath}`], {
98281
- encoding: "utf-8",
98330
+ const oldContent = fileExistsInHead ? await execGit(directory, ["show", `HEAD:${filePath}`], {
98282
98331
  timeout: 5000,
98283
- cwd: directory,
98284
- stdio: "pipe",
98285
98332
  maxBuffer: 5 * 1024 * 1024
98286
98333
  }) : "";
98287
- const newContent = fs55.readFileSync(path92.join(directory, filePath), "utf-8");
98334
+ const newContent = await fs55.promises.readFile(realResolvedPath, "utf-8");
98288
98335
  const astResult = await computeASTDiff(filePath, oldContent, newContent);
98289
98336
  if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
98290
98337
  astDiffs.push(astResult);
98291
98338
  }
98292
98339
  } catch (err2) {
98293
- if (err2.code === "ENOENT" && err2._gitBinaryMissing) {
98340
+ if (err2 instanceof GitBinaryMissingError) {
98294
98341
  throw err2;
98295
98342
  }
98296
98343
  }
@@ -106633,8 +106680,8 @@ ${body2}`);
106633
106680
 
106634
106681
  // src/council/council-evidence-writer.ts
106635
106682
  init_task_file();
106636
- import { appendFileSync as appendFileSync12, existsSync as existsSync62, mkdirSync as mkdirSync27, readFileSync as readFileSync46 } from "node:fs";
106637
- import { join as join94 } from "node:path";
106683
+ import { appendFileSync as appendFileSync12, existsSync as existsSync62, mkdirSync as mkdirSync27, readFileSync as readFileSync45 } from "node:fs";
106684
+ import { join as join93 } from "node:path";
106638
106685
  var EVIDENCE_DIR2 = ".swarm/evidence";
106639
106686
  var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
106640
106687
  var COUNCIL_GATE_NAME = "council";
@@ -106671,14 +106718,14 @@ async function writeCouncilEvidence(workingDir, synthesis) {
106671
106718
  if (!VALID_TASK_ID.test(synthesis.taskId)) {
106672
106719
  throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
106673
106720
  }
106674
- const dir = join94(workingDir, EVIDENCE_DIR2);
106721
+ const dir = join93(workingDir, EVIDENCE_DIR2);
106675
106722
  mkdirSync27(dir, { recursive: true });
106676
106723
  const filePath = taskEvidencePath(workingDir, synthesis.taskId);
106677
106724
  await _internals49.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
106678
106725
  const existingRoot = Object.create(null);
106679
106726
  if (existsSync62(filePath)) {
106680
106727
  try {
106681
- const parsed = JSON.parse(readFileSync46(filePath, "utf-8"));
106728
+ const parsed = JSON.parse(readFileSync45(filePath, "utf-8"));
106682
106729
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
106683
106730
  safeAssignOwnProps(existingRoot, parsed);
106684
106731
  }
@@ -106709,7 +106756,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
106709
106756
  await atomicWriteFile(filePath, JSON.stringify(updated, null, 2));
106710
106757
  });
106711
106758
  try {
106712
- const councilDir = join94(workingDir, ".swarm", "council");
106759
+ const councilDir = join93(workingDir, ".swarm", "council");
106713
106760
  mkdirSync27(councilDir, { recursive: true });
106714
106761
  const auditLine = JSON.stringify({
106715
106762
  round: synthesis.roundNumber,
@@ -106717,7 +106764,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
106717
106764
  timestamp: synthesis.timestamp,
106718
106765
  vetoedBy: synthesis.vetoedBy
106719
106766
  });
106720
- appendFileSync12(join94(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
106767
+ appendFileSync12(join93(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
106721
106768
  `);
106722
106769
  } catch (auditError) {
106723
106770
  console.warn(`writeCouncilEvidence: failed to append round-history audit log: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
@@ -107039,25 +107086,25 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
107039
107086
  }
107040
107087
 
107041
107088
  // src/council/criteria-store.ts
107042
- import { existsSync as existsSync63, mkdirSync as mkdirSync28, readFileSync as readFileSync47, writeFileSync as writeFileSync20 } from "node:fs";
107043
- import { join as join95 } from "node:path";
107089
+ import { existsSync as existsSync63, mkdirSync as mkdirSync28, readFileSync as readFileSync46, writeFileSync as writeFileSync20 } from "node:fs";
107090
+ import { join as join94 } from "node:path";
107044
107091
  var COUNCIL_DIR = ".swarm/council";
107045
107092
  function writeCriteria(workingDir, taskId, criteria) {
107046
- const dir = join95(workingDir, COUNCIL_DIR);
107093
+ const dir = join94(workingDir, COUNCIL_DIR);
107047
107094
  mkdirSync28(dir, { recursive: true });
107048
107095
  const payload = {
107049
107096
  taskId,
107050
107097
  criteria,
107051
107098
  declaredAt: new Date().toISOString()
107052
107099
  };
107053
- writeFileSync20(join95(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
107100
+ writeFileSync20(join94(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
107054
107101
  }
107055
107102
  function readCriteria(workingDir, taskId) {
107056
- const filePath = join95(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
107103
+ const filePath = join94(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
107057
107104
  if (!existsSync63(filePath))
107058
107105
  return null;
107059
107106
  try {
107060
- const parsed = JSON.parse(readFileSync47(filePath, "utf-8"));
107107
+ const parsed = JSON.parse(readFileSync46(filePath, "utf-8"));
107061
107108
  if (parsed && typeof parsed === "object" && typeof parsed.taskId === "string" && Array.isArray(parsed.criteria)) {
107062
107109
  return parsed;
107063
107110
  }
@@ -108319,7 +108366,6 @@ var diff = createSwarmTool({
108319
108366
  const fileCount = files.length;
108320
108367
  const astDiffs = [];
108321
108368
  const filesForAST = files.slice(0, MAX_AST_FILES);
108322
- const astSkippedCount = files.length > MAX_AST_FILES ? files.length - MAX_AST_FILES : 0;
108323
108369
  for (const file3 of filesForAST) {
108324
108370
  try {
108325
108371
  let oldContent;
@@ -108378,6 +108424,7 @@ var diff = createSwarmTool({
108378
108424
  markdownSummary = generateSummaryMarkdown(semanticSummary);
108379
108425
  } catch {}
108380
108426
  }
108427
+ const astSkippedCount = files.length > MAX_AST_FILES ? files.length - MAX_AST_FILES : 0;
108381
108428
  const truncated = diffLines.length > MAX_DIFF_LINES;
108382
108429
  const summary = truncated ? `${fileCount} files changed. Contract changes: ${hasContractChanges ? "YES" : "NO"}. (truncated to ${MAX_DIFF_LINES} lines)` : `${fileCount} files changed. Contract changes: ${hasContractChanges ? "YES" : "NO"}`;
108383
108430
  const result = {
@@ -108409,6 +108456,34 @@ import * as fs79 from "node:fs";
108409
108456
  import * as path116 from "node:path";
108410
108457
  init_create_tool();
108411
108458
  init_resolve_working_directory();
108459
+ async function execGit2(workingDir, args2, options) {
108460
+ try {
108461
+ const stdout = await new Promise((resolve40, reject) => {
108462
+ const execOpts = {
108463
+ encoding: "utf-8",
108464
+ cwd: workingDir,
108465
+ timeout: options?.timeout,
108466
+ maxBuffer: options?.maxBuffer,
108467
+ stdio: ["ignore", "pipe", "pipe"]
108468
+ };
108469
+ child_process8.execFile("git", args2, execOpts, (error93, output, _stderr) => {
108470
+ if (error93) {
108471
+ reject(error93);
108472
+ return;
108473
+ }
108474
+ resolve40(output ?? "");
108475
+ });
108476
+ });
108477
+ return stdout;
108478
+ } catch (err2) {
108479
+ if (isGitBinaryMissing(err2)) {
108480
+ throw new GitBinaryMissingError("git binary is not available", {
108481
+ cause: err2
108482
+ });
108483
+ }
108484
+ throw err2;
108485
+ }
108486
+ }
108412
108487
  var diff_summary = createSwarmTool({
108413
108488
  description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
108414
108489
  args: {
@@ -108434,45 +108509,33 @@ var diff_summary = createSwarmTool({
108434
108509
  const astDiffs = [];
108435
108510
  for (const filePath of typedArgs.files) {
108436
108511
  let astResult = null;
108437
- let gitBinaryMissing = false;
108438
- let gitError = null;
108439
108512
  let fileExistsInHead = false;
108440
108513
  try {
108441
- child_process8.execFileSync("git", ["cat-file", "-e", `HEAD:${filePath}`], {
108442
- encoding: "utf-8",
108443
- timeout: 3000,
108444
- cwd: workingDir,
108445
- stdio: "pipe"
108514
+ await execGit2(workingDir, ["cat-file", "-e", `HEAD:${filePath}`], {
108515
+ timeout: 3000
108446
108516
  });
108447
108517
  fileExistsInHead = true;
108448
108518
  } catch (e) {
108449
- if (e && typeof e === "object" && "code" in e) {
108450
- const err2 = e;
108451
- if (err2.code === "ENOENT") {
108452
- gitBinaryMissing = true;
108453
- gitError = e;
108454
- }
108519
+ if (e instanceof GitBinaryMissingError) {
108520
+ throw e;
108455
108521
  }
108456
108522
  }
108457
- if (gitBinaryMissing && gitError) {
108458
- throw gitError;
108459
- }
108460
108523
  try {
108461
108524
  let oldContent;
108462
- const newContent = fs79.readFileSync(path116.join(workingDir, filePath), "utf-8");
108525
+ const newContent = await fs79.promises.readFile(path116.join(workingDir, filePath), "utf-8");
108463
108526
  if (fileExistsInHead) {
108464
- oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
108465
- encoding: "utf-8",
108527
+ oldContent = await execGit2(workingDir, ["show", `HEAD:${filePath}`], {
108466
108528
  timeout: 5000,
108467
- cwd: workingDir,
108468
- stdio: "pipe",
108469
108529
  maxBuffer: 5 * 1024 * 1024
108470
108530
  });
108471
108531
  } else {
108472
108532
  oldContent = "";
108473
108533
  }
108474
108534
  astResult = await computeASTDiff(filePath, oldContent, newContent);
108475
- } catch (_e) {
108535
+ } catch (e) {
108536
+ if (e instanceof GitBinaryMissingError) {
108537
+ throw e;
108538
+ }
108476
108539
  astResult = null;
108477
108540
  }
108478
108541
  if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
@@ -119867,7 +119930,7 @@ init_loader();
119867
119930
  import {
119868
119931
  existsSync as existsSync81,
119869
119932
  mkdirSync as mkdirSync34,
119870
- readFileSync as readFileSync65,
119933
+ readFileSync as readFileSync63,
119871
119934
  renameSync as renameSync21,
119872
119935
  unlinkSync as unlinkSync18,
119873
119936
  writeFileSync as writeFileSync27
@@ -120004,7 +120067,7 @@ var submit_phase_council_verdicts = createSwarmTool({
120004
120067
  function getPhaseMutationGapFinding(phaseNumber, workingDir) {
120005
120068
  const mutationGatePath = path138.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
120006
120069
  try {
120007
- const raw = readFileSync65(mutationGatePath, "utf-8");
120070
+ const raw = readFileSync63(mutationGatePath, "utf-8");
120008
120071
  const parsed = JSON.parse(raw);
120009
120072
  const gateEntry = (parsed.entries ?? []).find((entry) => entry?.type === "mutation-gate");
120010
120073
  if (!gateEntry) {
@@ -13,6 +13,10 @@ export interface DiffResult {
13
13
  astDiffs?: ASTDiffResult[];
14
14
  semanticSummary?: SemanticDiffSummary;
15
15
  markdownSummary?: string;
16
+ /**
17
+ * @deprecated This field is no longer computed and will be removed in a future version.
18
+ * It is retained for backward compatibility with existing consumers.
19
+ */
16
20
  astSkippedCount?: number;
17
21
  }
18
22
  export interface DiffErrorResult {
@@ -1,4 +1,5 @@
1
1
  import type { tool } from '@opencode-ai/plugin';
2
+ import { getAllHistory, type TestRunRecord } from '../test-impact/history-store.js';
2
3
  export declare const MAX_OUTPUT_BYTES = 512000;
3
4
  export declare const MAX_COMMAND_LENGTH = 500;
4
5
  export declare const DEFAULT_TIMEOUT_MS = 60000;
@@ -127,4 +128,10 @@ export declare function isLanguageSpecificTestFile(basename: string): boolean;
127
128
  */
128
129
  export declare function getTestFilesFromConvention(sourceFiles: string[], workingDir?: string): string[];
129
130
  export declare function runTests(framework: TestFramework, scope: 'all' | 'convention' | 'graph' | 'impact', files: string[], coverage: boolean, timeout_ms: number, cwd: string): Promise<TestResult>;
131
+ declare function selectHistoryForAnalysis(history: ReturnType<typeof getAllHistory>): TestRunRecord[];
130
132
  export declare const test_runner: ReturnType<typeof tool>;
133
+ export declare const _internals: {
134
+ readonly selectHistoryForAnalysis: typeof selectHistoryForAnalysis;
135
+ readonly AGGREGATE_TEST_NAME: "(aggregate)";
136
+ };
137
+ export {};
@@ -0,0 +1,9 @@
1
+ export declare class GitBinaryMissingError extends Error {
2
+ readonly name = "GitBinaryMissingError";
3
+ constructor(message?: string, options?: {
4
+ cause?: unknown;
5
+ });
6
+ }
7
+ export declare function isGitBinaryMissing(err: unknown): err is {
8
+ code?: string;
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.44.1",
3
+ "version": "7.45.0",
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",