opencode-swarm 7.77.7 → 7.78.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.77.7",
55
+ version: "7.78.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",
@@ -150,6 +150,7 @@ export declare const RECEIPT_EVENT_TYPES: ReadonlySet<string>;
150
150
  export declare function resolveKnowledgeEventsPath(directory: string): string;
151
151
  /** Returns `.swarm/knowledge-counter-baseline.json` for folded event counters. */
152
152
  export declare function resolveKnowledgeCounterBaselinePath(directory: string): string;
153
+ export declare function resolveHiveEventsPath(): string;
153
154
  /** Returns `.swarm/knowledge-application.jsonl` for legacy v2 audit records. */
154
155
  export declare function resolveLegacyApplicationLogPath(directory: string): string;
155
156
  /** Generate a fresh trace id. One per retrieval; receipts reference it. */
@@ -169,12 +170,29 @@ export declare function appendKnowledgeEvent(directory: string, event: Knowledge
169
170
  * execution). Never throws; logs a warning and returns null on failure.
170
171
  */
171
172
  export declare function recordKnowledgeEvent(directory: string, event: KnowledgeEventInput): Promise<KnowledgeEvent | null>;
173
+ /**
174
+ * Append one event to the shared, cross-project hive events log. Use for audit
175
+ * tombstones of mutations to the hive store so any project can read why a hive
176
+ * entry was archived/quarantined/purged. Throws on I/O failure; hot paths should
177
+ * prefer {@link recordHiveKnowledgeEvent}.
178
+ */
179
+ export declare function appendHiveKnowledgeEvent(event: KnowledgeEventInput): Promise<KnowledgeEvent>;
180
+ /**
181
+ * Fail-open variant of {@link appendHiveKnowledgeEvent} for hot paths. Never
182
+ * throws; logs a warning and returns null on failure.
183
+ */
184
+ export declare function recordHiveKnowledgeEvent(event: KnowledgeEventInput): Promise<KnowledgeEvent | null>;
172
185
  /**
173
186
  * Read all events from the log. Skips corrupted JSONL lines (logging a warning
174
187
  * for each) and returns an empty array when the file does not exist — mirrors
175
188
  * `readKnowledge` in knowledge-store.ts.
176
189
  */
177
190
  export declare function readKnowledgeEvents(directory: string): Promise<KnowledgeEvent[]>;
191
+ /**
192
+ * Read all events from the shared, cross-project hive events log. Skips
193
+ * corrupted JSONL lines and returns an empty array when the file does not exist.
194
+ */
195
+ export declare function readHiveKnowledgeEvents(): Promise<KnowledgeEvent[]>;
178
196
  /**
179
197
  * Read legacy knowledge-application audit records. Corrupt lines are skipped so
180
198
  * stale telemetry cannot break search, promotion, or manual recall.
@@ -292,5 +310,9 @@ export declare const _internals: {
292
310
  applyKnowledgeVerdictFeedback: typeof applyKnowledgeVerdictFeedback;
293
311
  newTraceId: typeof newTraceId;
294
312
  newEventId: typeof newEventId;
313
+ resolveHiveEventsPath: typeof resolveHiveEventsPath;
314
+ appendHiveKnowledgeEvent: typeof appendHiveKnowledgeEvent;
315
+ recordHiveKnowledgeEvent: typeof recordHiveKnowledgeEvent;
316
+ readHiveKnowledgeEvents: typeof readHiveKnowledgeEvents;
295
317
  };
296
318
  export {};
@@ -6,6 +6,7 @@ export declare function resolveSwarmRejectedPath(directory: string): string;
6
6
  export declare function resolveSwarmRetractionsPath(directory: string): string;
7
7
  export declare function resolveHiveKnowledgePath(): string;
8
8
  export declare function resolveHiveRejectedPath(): string;
9
+ export declare function resolveHiveEventsPath(): string;
9
10
  export declare function readKnowledge<T>(filePath: string): Promise<T[]>;
10
11
  export declare function normalizeEntry<T>(raw: T): T;
11
12
  export declare function readRejectedLessons(directory: string): Promise<RejectedLesson[]>;
@@ -73,6 +74,7 @@ export declare const _internals: {
73
74
  resolveSwarmRejectedPath: typeof resolveSwarmRejectedPath;
74
75
  resolveHiveKnowledgePath: typeof resolveHiveKnowledgePath;
75
76
  resolveHiveRejectedPath: typeof resolveHiveRejectedPath;
77
+ resolveHiveEventsPath: typeof resolveHiveEventsPath;
76
78
  readKnowledge: typeof readKnowledge;
77
79
  readRejectedLessons: typeof readRejectedLessons;
78
80
  appendKnowledge: typeof appendKnowledge;
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.77.7",
72
+ version: "7.78.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",
@@ -59678,6 +59678,7 @@ __export(exports_knowledge_store, {
59678
59678
  resolveSwarmKnowledgePath: () => resolveSwarmKnowledgePath,
59679
59679
  resolveHiveRejectedPath: () => resolveHiveRejectedPath,
59680
59680
  resolveHiveKnowledgePath: () => resolveHiveKnowledgePath,
59681
+ resolveHiveEventsPath: () => resolveHiveEventsPath,
59681
59682
  readRetractionRecords: () => readRetractionRecords,
59682
59683
  readRejectedLessons: () => readRejectedLessons,
59683
59684
  readKnowledge: () => readKnowledge,
@@ -59739,6 +59740,10 @@ function resolveHiveRejectedPath() {
59739
59740
  const hivePath = resolveHiveKnowledgePath();
59740
59741
  return path31.join(path31.dirname(hivePath), "shared-learnings-rejected.jsonl");
59741
59742
  }
59743
+ function resolveHiveEventsPath() {
59744
+ const hivePath = resolveHiveKnowledgePath();
59745
+ return path31.join(path31.dirname(hivePath), "shared-knowledge-events.jsonl");
59746
+ }
59742
59747
  async function readKnowledge(filePath) {
59743
59748
  if (!existsSync13(filePath))
59744
59749
  return [];
@@ -60181,6 +60186,7 @@ var init_knowledge_store = __esm(() => {
60181
60186
  resolveSwarmRejectedPath,
60182
60187
  resolveHiveKnowledgePath,
60183
60188
  resolveHiveRejectedPath,
60189
+ resolveHiveEventsPath,
60184
60190
  readKnowledge,
60185
60191
  readRejectedLessons,
60186
60192
  appendKnowledge,
@@ -60208,11 +60214,14 @@ __export(exports_knowledge_events, {
60208
60214
  resolveLegacyApplicationLogPath: () => resolveLegacyApplicationLogPath,
60209
60215
  resolveKnowledgeEventsPath: () => resolveKnowledgeEventsPath,
60210
60216
  resolveKnowledgeCounterBaselinePath: () => resolveKnowledgeCounterBaselinePath,
60217
+ resolveHiveEventsPath: () => resolveHiveEventsPath2,
60211
60218
  recordKnowledgeEvent: () => recordKnowledgeEvent,
60219
+ recordHiveKnowledgeEvent: () => recordHiveKnowledgeEvent,
60212
60220
  recomputeCounters: () => recomputeCounters,
60213
60221
  readLegacyApplicationRecords: () => readLegacyApplicationRecords,
60214
60222
  readKnowledgeEvents: () => readKnowledgeEvents,
60215
60223
  readKnowledgeCounterRollups: () => readKnowledgeCounterRollups,
60224
+ readHiveKnowledgeEvents: () => readHiveKnowledgeEvents,
60216
60225
  newTraceId: () => newTraceId,
60217
60226
  newEventId: () => newEventId,
60218
60227
  effectiveRetrievalOutcomes: () => effectiveRetrievalOutcomes,
@@ -60220,6 +60229,7 @@ __export(exports_knowledge_events, {
60220
60229
  countEntryViolationsInWindow: () => countEntryViolationsInWindow,
60221
60230
  applyKnowledgeVerdictFeedback: () => applyKnowledgeVerdictFeedback,
60222
60231
  appendKnowledgeEvent: () => appendKnowledgeEvent,
60232
+ appendHiveKnowledgeEvent: () => appendHiveKnowledgeEvent,
60223
60233
  _internals: () => _internals24,
60224
60234
  RECEIPT_EVENT_TYPES: () => RECEIPT_EVENT_TYPES,
60225
60235
  MAX_VIOLATION_TIMESTAMPS: () => MAX_VIOLATION_TIMESTAMPS,
@@ -60229,6 +60239,7 @@ __export(exports_knowledge_events, {
60229
60239
  import { randomUUID as randomUUID2 } from "node:crypto";
60230
60240
  import { existsSync as existsSync14 } from "node:fs";
60231
60241
  import { appendFile as appendFile4, mkdir as mkdir5, readFile as readFile5, stat as stat4 } from "node:fs/promises";
60242
+ import * as os10 from "node:os";
60232
60243
  import * as path32 from "node:path";
60233
60244
  function resolveKnowledgeEventsPath(directory) {
60234
60245
  return path32.join(directory, ".swarm", "knowledge-events.jsonl");
@@ -60236,6 +60247,19 @@ function resolveKnowledgeEventsPath(directory) {
60236
60247
  function resolveKnowledgeCounterBaselinePath(directory) {
60237
60248
  return path32.join(directory, ".swarm", "knowledge-counter-baseline.json");
60238
60249
  }
60250
+ function resolveHiveEventsPath2() {
60251
+ const platform = process.platform;
60252
+ const home = process.env.HOME || os10.homedir();
60253
+ let dir;
60254
+ if (platform === "win32") {
60255
+ dir = path32.join(process.env.LOCALAPPDATA || path32.join(home, "AppData", "Local"), "opencode-swarm", "Data");
60256
+ } else if (platform === "darwin") {
60257
+ dir = path32.join(home, "Library", "Application Support", "opencode-swarm");
60258
+ } else {
60259
+ dir = path32.join(process.env.XDG_DATA_HOME || path32.join(home, ".local", "share"), "opencode-swarm");
60260
+ }
60261
+ return path32.join(dir, "shared-knowledge-events.jsonl");
60262
+ }
60239
60263
  function resolveLegacyApplicationLogPath(directory) {
60240
60264
  return path32.join(directory, ".swarm", "knowledge-application.jsonl");
60241
60265
  }
@@ -60294,6 +60318,45 @@ async function recordKnowledgeEvent(directory, event) {
60294
60318
  return null;
60295
60319
  }
60296
60320
  }
60321
+ async function appendHiveKnowledgeEvent(event) {
60322
+ const populated = withDefaults(event);
60323
+ const filePath = resolveHiveEventsPath2();
60324
+ const dirPath = path32.dirname(filePath);
60325
+ await mkdir5(dirPath, { recursive: true });
60326
+ let release;
60327
+ try {
60328
+ release = await import_proper_lockfile4.default.lock(dirPath, {
60329
+ retries: { retries: 200, minTimeout: 10, maxTimeout: 100 }
60330
+ });
60331
+ await appendFile4(filePath, `${JSON.stringify(populated)}
60332
+ `, "utf-8");
60333
+ try {
60334
+ const content = await readFile5(filePath, "utf-8");
60335
+ const lines = content.split(`
60336
+ `).filter((line) => line.trim().length > 0);
60337
+ if (lines.length > MAX_EVENT_LOG_ENTRIES) {
60338
+ const trimmed = lines.slice(lines.length - MAX_EVENT_LOG_ENTRIES);
60339
+ await atomicWriteFile(filePath, `${trimmed.join(`
60340
+ `)}
60341
+ `);
60342
+ }
60343
+ } catch (err2) {
60344
+ warn(`[knowledge-events] hive cap trim failed (non-fatal): ${err2 instanceof Error ? err2.message : String(err2)}`);
60345
+ }
60346
+ } finally {
60347
+ if (release)
60348
+ await release().catch(() => {});
60349
+ }
60350
+ return populated;
60351
+ }
60352
+ async function recordHiveKnowledgeEvent(event) {
60353
+ try {
60354
+ return await appendHiveKnowledgeEvent(event);
60355
+ } catch (err2) {
60356
+ warn(`[knowledge-events] recordHiveKnowledgeEvent failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
60357
+ return null;
60358
+ }
60359
+ }
60297
60360
  async function readKnowledgeEvents(directory) {
60298
60361
  const filePath = resolveKnowledgeEventsPath(directory);
60299
60362
  if (!existsSync14(filePath))
@@ -60302,6 +60365,14 @@ async function readKnowledgeEvents(directory) {
60302
60365
  return parseEventLines(content.split(`
60303
60366
  `), filePath);
60304
60367
  }
60368
+ async function readHiveKnowledgeEvents() {
60369
+ const filePath = resolveHiveEventsPath2();
60370
+ if (!existsSync14(filePath))
60371
+ return [];
60372
+ const content = await readFile5(filePath, "utf-8");
60373
+ return parseEventLines(content.split(`
60374
+ `), filePath);
60375
+ }
60305
60376
  async function readLegacyApplicationRecords(directory) {
60306
60377
  const filePath = resolveLegacyApplicationLogPath(directory);
60307
60378
  if (!existsSync14(filePath))
@@ -60704,7 +60775,11 @@ var init_knowledge_events = __esm(() => {
60704
60775
  recomputeCounters,
60705
60776
  applyKnowledgeVerdictFeedback,
60706
60777
  newTraceId,
60707
- newEventId
60778
+ newEventId,
60779
+ resolveHiveEventsPath: resolveHiveEventsPath2,
60780
+ appendHiveKnowledgeEvent,
60781
+ recordHiveKnowledgeEvent,
60782
+ readHiveKnowledgeEvents
60708
60783
  };
60709
60784
  });
60710
60785
 
@@ -70219,10 +70294,10 @@ var init_concurrency = __esm(() => {
70219
70294
  });
70220
70295
 
70221
70296
  // src/commands/config.ts
70222
- import * as os10 from "node:os";
70297
+ import * as os11 from "node:os";
70223
70298
  import * as path50 from "node:path";
70224
70299
  function getUserConfigDir2() {
70225
- return process.env.XDG_CONFIG_HOME || path50.join(os10.homedir(), ".config");
70300
+ return process.env.XDG_CONFIG_HOME || path50.join(os11.homedir(), ".config");
70226
70301
  }
70227
70302
  async function handleConfigCommand(directory, _args) {
70228
70303
  const config3 = loadPluginConfig(directory);
@@ -71358,13 +71433,13 @@ var init_design_docs = __esm(() => {
71358
71433
  });
71359
71434
 
71360
71435
  // src/config/cache-paths.ts
71361
- import * as os11 from "node:os";
71436
+ import * as os12 from "node:os";
71362
71437
  import * as path54 from "node:path";
71363
71438
  function getPluginConfigDir() {
71364
- return path54.join(process.env.XDG_CONFIG_HOME || path54.join(os11.homedir(), ".config"), "opencode");
71439
+ return path54.join(process.env.XDG_CONFIG_HOME || path54.join(os12.homedir(), ".config"), "opencode");
71365
71440
  }
71366
71441
  function getPluginCachePaths() {
71367
- const cacheBase = process.env.XDG_CACHE_HOME || path54.join(os11.homedir(), ".cache");
71442
+ const cacheBase = process.env.XDG_CACHE_HOME || path54.join(os12.homedir(), ".cache");
71368
71443
  const configDir = getPluginConfigDir();
71369
71444
  const paths = [
71370
71445
  path54.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
@@ -71372,12 +71447,12 @@ function getPluginCachePaths() {
71372
71447
  path54.join(configDir, "node_modules", "opencode-swarm")
71373
71448
  ];
71374
71449
  if (process.platform === "darwin") {
71375
- const libCaches = path54.join(os11.homedir(), "Library", "Caches");
71450
+ const libCaches = path54.join(os12.homedir(), "Library", "Caches");
71376
71451
  paths.push(path54.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path54.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
71377
71452
  }
71378
71453
  if (process.platform === "win32") {
71379
- const localAppData = process.env.LOCALAPPDATA || path54.join(os11.homedir(), "AppData", "Local");
71380
- const appData = process.env.APPDATA || path54.join(os11.homedir(), "AppData", "Roaming");
71454
+ const localAppData = process.env.LOCALAPPDATA || path54.join(os12.homedir(), "AppData", "Local");
71455
+ const appData = process.env.APPDATA || path54.join(os12.homedir(), "AppData", "Roaming");
71381
71456
  paths.push(path54.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path54.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path54.join(appData, "opencode", "node_modules", "opencode-swarm"));
71382
71457
  }
71383
71458
  return paths;
@@ -71500,11 +71575,11 @@ var init_gate_bridge = __esm(() => {
71500
71575
 
71501
71576
  // src/services/version-check.ts
71502
71577
  import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
71503
- import { homedir as homedir6 } from "node:os";
71578
+ import { homedir as homedir7 } from "node:os";
71504
71579
  import { join as join43 } from "node:path";
71505
71580
  function cacheDir() {
71506
71581
  const xdg = process.env.XDG_CACHE_HOME;
71507
- const base = xdg && xdg.length > 0 ? xdg : join43(homedir6(), ".cache");
71582
+ const base = xdg && xdg.length > 0 ? xdg : join43(homedir7(), ".cache");
71508
71583
  return join43(base, "opencode-swarm");
71509
71584
  }
71510
71585
  function cacheFile() {
@@ -72660,7 +72735,7 @@ __export(exports_config_doctor, {
72660
72735
  });
72661
72736
  import * as crypto5 from "node:crypto";
72662
72737
  import * as fs24 from "node:fs";
72663
- import * as os12 from "node:os";
72738
+ import * as os13 from "node:os";
72664
72739
  import * as path56 from "node:path";
72665
72740
  function levenshteinDistance(a, b) {
72666
72741
  const al = a.length;
@@ -72694,7 +72769,7 @@ function emitObjectTypeMismatch(key, value, findings) {
72694
72769
  }
72695
72770
  }
72696
72771
  function getUserConfigDir3() {
72697
- return process.env.XDG_CONFIG_HOME || path56.join(os12.homedir(), ".config");
72772
+ return process.env.XDG_CONFIG_HOME || path56.join(os13.homedir(), ".config");
72698
72773
  }
72699
72774
  function getConfigPaths(directory) {
72700
72775
  const userConfigPath = path56.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
@@ -77779,7 +77854,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
77779
77854
  import { randomUUID as randomUUID6 } from "node:crypto";
77780
77855
  import { existsSync as existsSync34, readFileSync as readFileSync18 } from "node:fs";
77781
77856
  import { mkdir as mkdir16, readFile as readFile18, writeFile as writeFile14 } from "node:fs/promises";
77782
- import * as os13 from "node:os";
77857
+ import * as os14 from "node:os";
77783
77858
  import * as path60 from "node:path";
77784
77859
  async function migrateKnowledgeToExternal(_directory, _config) {
77785
77860
  return {
@@ -78131,7 +78206,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
78131
78206
  }
78132
78207
  function resolveLegacyHiveKnowledgePath() {
78133
78208
  const platform = process.platform;
78134
- const home = process.env.HOME || os13.homedir();
78209
+ const home = process.env.HOME || os14.homedir();
78135
78210
  let dataDir;
78136
78211
  if (platform === "win32") {
78137
78212
  dataDir = path60.join(process.env.LOCALAPPDATA || path60.join(home, "AppData", "Local"), "opencode-swarm", "Data");
@@ -81404,7 +81479,7 @@ var init_gateway = __esm(() => {
81404
81479
 
81405
81480
  // src/memory/evaluation.ts
81406
81481
  import * as fs27 from "node:fs/promises";
81407
- import * as os14 from "node:os";
81482
+ import * as os15 from "node:os";
81408
81483
  import * as path65 from "node:path";
81409
81484
  async function evaluateMemoryRecallFixtures(options) {
81410
81485
  const fixtureDirectory = path65.resolve(options.fixtureDirectory);
@@ -81416,7 +81491,7 @@ async function evaluateMemoryRecallFixtures(options) {
81416
81491
  for (const fixture of fixtures) {
81417
81492
  const materialized = materializeFixture(fixture);
81418
81493
  for (const providerName of providers) {
81419
- const tempRoot = await fs27.realpath(await fs27.mkdtemp(path65.join(os14.tmpdir(), "swarm-memory-eval-")));
81494
+ const tempRoot = await fs27.realpath(await fs27.mkdtemp(path65.join(os15.tmpdir(), "swarm-memory-eval-")));
81420
81495
  const provider = createEvaluationProvider(providerName, tempRoot);
81421
81496
  try {
81422
81497
  await provider.initialize?.();
@@ -108163,7 +108238,7 @@ init_path_security();
108163
108238
  import * as fsSync7 from "node:fs";
108164
108239
  import { existsSync as existsSync63, realpathSync as realpathSync13 } from "node:fs";
108165
108240
  import * as fsPromises5 from "node:fs/promises";
108166
- import * as os15 from "node:os";
108241
+ import * as os16 from "node:os";
108167
108242
  import * as path108 from "node:path";
108168
108243
 
108169
108244
  // src/tools/symbols.ts
@@ -109466,8 +109541,8 @@ function isRefusedWorkspaceRoot(target) {
109466
109541
  refused.add(path108.resolve(p));
109467
109542
  }
109468
109543
  };
109469
- add2(os15.homedir());
109470
- add2(os15.tmpdir());
109544
+ add2(os16.homedir());
109545
+ add2(os16.tmpdir());
109471
109546
  add2("/");
109472
109547
  add2("/Users");
109473
109548
  add2("/home");
@@ -129002,7 +129077,7 @@ var knowledge_archive = createSwarmTool({
129002
129077
  if (!found) {
129003
129078
  return JSON.stringify({ success: false, message: "entry not found" });
129004
129079
  }
129005
- await recordKnowledgeEvent(directory, {
129080
+ const tombstone = {
129006
129081
  type: "archived",
129007
129082
  entry_id: id,
129008
129083
  tier,
@@ -129011,7 +129086,12 @@ var knowledge_archive = createSwarmTool({
129011
129086
  mode,
129012
129087
  evidence,
129013
129088
  previous_status: previousStatus
129014
- });
129089
+ };
129090
+ if (tier === "hive") {
129091
+ await recordHiveKnowledgeEvent(tombstone);
129092
+ } else {
129093
+ await recordKnowledgeEvent(directory, tombstone);
129094
+ }
129015
129095
  return JSON.stringify({
129016
129096
  success: true,
129017
129097
  id,
@@ -10,6 +10,10 @@
10
10
  * - 'archive' (default): set status='archived' — TTL-exempt, hidden from recall.
11
11
  * - 'quarantine': set status='quarantined' — suspected-bad, hidden from recall.
12
12
  * - 'purge': hard-delete the JSONL line. Requires allow_purge:true.
13
+ *
14
+ * Tiers:
15
+ * - 'swarm' (default): archives a project-local swarm entry.
16
+ * - 'hive': archives a shared hive entry (cross-project knowledge).
13
17
  */
14
18
  import { createSwarmTool } from './create-tool.js';
15
19
  export declare const knowledge_archive: ReturnType<typeof createSwarmTool>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.77.7",
3
+ "version": "7.78.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",