opencode-swarm 7.99.6 → 7.99.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,10 @@ import {
6
6
  loadPlanJsonOnly,
7
7
  mergeDurableGateEntriesFromEvidence,
8
8
  readDurableGateEvidence
9
- } from "./index-9twtnjkv.js";
9
+ } from "./index-y3x3gvy6.js";
10
10
  import"./index-r8f89sm9.js";
11
11
  import"./index-9b7qp18e.js";
12
- import"./index-94qwbx11.js";
12
+ import"./index-7ztmmqpt.js";
13
13
  import"./index-jtqkh8jf.js";
14
14
  import"./index-5e4e2hvv.js";
15
15
  import"./index-p0arc26j.js";
@@ -1,21 +1,21 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-ksc4ftms.js";
5
- import"./index-1kcp4q4y.js";
4
+ } from "./index-zyhd4mnn.js";
5
+ import"./index-wpnam1jh.js";
6
6
  import"./index-xsswhy6k.js";
7
7
  import"./index-ydgy7vg5.js";
8
8
  import"./index-vwyjkzgs.js";
9
9
  import"./index-f7nma02k.js";
10
10
  import"./index-0d3pmjf9.js";
11
11
  import"./index-7hnwnw5g.js";
12
- import"./index-9twtnjkv.js";
12
+ import"./index-y3x3gvy6.js";
13
13
  import"./index-adz3nk9b.js";
14
14
  import"./index-v4fcn4tr.js";
15
15
  import"./index-r8f89sm9.js";
16
16
  import"./index-9b7qp18e.js";
17
- import"./index-s3esnz7m.js";
18
- import"./index-94qwbx11.js";
17
+ import"./index-e9n3xsk0.js";
18
+ import"./index-7ztmmqpt.js";
19
19
  import"./index-jtqkh8jf.js";
20
20
  import"./index-5e4e2hvv.js";
21
21
  import"./index-p0arc26j.js";
@@ -22,6 +22,9 @@ var _internals = {
22
22
  readSwarmFileAsync,
23
23
  readCachedTextFile
24
24
  };
25
+ function isFailClosedHandler(value) {
26
+ return typeof value === "function" && Object.hasOwn(value, "__failClosed") && value.__failClosed === true;
27
+ }
25
28
  function safeHook(fn) {
26
29
  return async (input, output) => {
27
30
  try {
@@ -43,6 +46,9 @@ function composeHandlers(...fns) {
43
46
  }
44
47
  return async (input, output) => {
45
48
  for (const fn of fns) {
49
+ if (isFailClosedHandler(fn)) {
50
+ throw new Error("composeHandlers cannot wrap fail-closed handlers; use composeBlockingHandlers or await them directly");
51
+ }
46
52
  const safeFn = _internals.safeHook(fn);
47
53
  await safeFn(input, output);
48
54
  }
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  validateSwarmPath
4
- } from "./index-94qwbx11.js";
4
+ } from "./index-7ztmmqpt.js";
5
5
  import {
6
6
  log
7
7
  } from "./index-zgwm4ryv.js";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-ksc4ftms.js";
4
+ } from "./index-zyhd4mnn.js";
5
5
  import {
6
6
  handleGuardrailLog
7
7
  } from "./index-h9ptj4b1.js";
@@ -79,7 +79,7 @@ import {
79
79
  handleWriteRetroCommand,
80
80
  normalizeSwarmCommandInput,
81
81
  resolveCommand
82
- } from "./index-1kcp4q4y.js";
82
+ } from "./index-wpnam1jh.js";
83
83
  import"./index-xsswhy6k.js";
84
84
  import"./index-ydgy7vg5.js";
85
85
  import"./index-vwyjkzgs.js";
@@ -90,13 +90,13 @@ import {
90
90
  ORCHESTRATOR_NAME,
91
91
  stripKnownSwarmPrefix
92
92
  } from "./index-7hnwnw5g.js";
93
- import"./index-9twtnjkv.js";
93
+ import"./index-y3x3gvy6.js";
94
94
  import"./index-adz3nk9b.js";
95
95
  import"./index-v4fcn4tr.js";
96
96
  import"./index-r8f89sm9.js";
97
97
  import"./index-9b7qp18e.js";
98
- import"./index-s3esnz7m.js";
99
- import"./index-94qwbx11.js";
98
+ import"./index-e9n3xsk0.js";
99
+ import"./index-7ztmmqpt.js";
100
100
  import"./index-jtqkh8jf.js";
101
101
  import"./index-5e4e2hvv.js";
102
102
  import"./index-p0arc26j.js";
@@ -114,7 +114,7 @@ import {
114
114
  transientBackoff,
115
115
  validateProjectRoot,
116
116
  writeProjectedSpecSync
117
- } from "./index-9twtnjkv.js";
117
+ } from "./index-y3x3gvy6.js";
118
118
  import {
119
119
  _internals as _internals2,
120
120
  _internals1 as _internals3,
@@ -138,12 +138,12 @@ import {
138
138
  listActive,
139
139
  subscribe,
140
140
  unsubscribe
141
- } from "./index-s3esnz7m.js";
141
+ } from "./index-e9n3xsk0.js";
142
142
  import {
143
143
  readSwarmFileAsync,
144
144
  safeHook,
145
145
  validateSwarmPath
146
- } from "./index-94qwbx11.js";
146
+ } from "./index-7ztmmqpt.js";
147
147
  import {
148
148
  deepMerge
149
149
  } from "./index-p0arc26j.js";
@@ -909,7 +909,7 @@ var init_executor = __esm(() => {
909
909
  // package.json
910
910
  var package_default = {
911
911
  name: "opencode-swarm",
912
- version: "7.99.6",
912
+ version: "7.99.7",
913
913
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
914
914
  main: "dist/index.js",
915
915
  types: "dist/index.d.ts",
@@ -6034,7 +6034,7 @@ function hasActiveEpicMode(sessionID) {
6034
6034
  async function rehydratePrSubscriptions(sessionID, directory) {
6035
6035
  const map = new Map;
6036
6036
  try {
6037
- const { listActive: listActive2 } = await import("./pr-subscriptions-d57tq0c0.js");
6037
+ const { listActive: listActive2 } = await import("./pr-subscriptions-zfxjtyzw.js");
6038
6038
  const records = await listActive2(directory);
6039
6039
  for (const record of records) {
6040
6040
  if (record.sessionID !== sessionID)
@@ -15889,6 +15889,7 @@ import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as re
15889
15889
  import { homedir as homedir4 } from "os";
15890
15890
  import { join as join27 } from "path";
15891
15891
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
15892
+ var SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
15892
15893
  var MAX_RESPONSE_BYTES = 256 * 1024;
15893
15894
  function cacheDir() {
15894
15895
  const xdg = process.env.XDG_CACHE_HOME;
@@ -15913,26 +15914,39 @@ function readVersionCache() {
15913
15914
  return null;
15914
15915
  }
15915
15916
  }
15917
+ function parseVersion(version) {
15918
+ const trimmed = version.trim();
15919
+ const match = SEMVER_REGEX.exec(trimmed);
15920
+ if (!match)
15921
+ return null;
15922
+ return {
15923
+ major: Number.parseInt(match[1], 10),
15924
+ minor: Number.parseInt(match[2], 10),
15925
+ patch: Number.parseInt(match[3], 10),
15926
+ prerelease: match[4] ?? null
15927
+ };
15928
+ }
15916
15929
  function compareVersions(a, b) {
15917
- const [aBase, aPre] = a.split("-", 2);
15918
- const [bBase, bPre] = b.split("-", 2);
15919
- const aParts = aBase.split(".").map((n) => Number.parseInt(n, 10) || 0);
15920
- const bParts = bBase.split(".").map((n) => Number.parseInt(n, 10) || 0);
15921
- const len = Math.max(aParts.length, bParts.length);
15922
- for (let i = 0;i < len; i++) {
15923
- const av = aParts[i] ?? 0;
15924
- const bv = bParts[i] ?? 0;
15925
- if (av > bv)
15926
- return 1;
15927
- if (av < bv)
15928
- return -1;
15930
+ const aParsed = parseVersion(a);
15931
+ const bParsed = parseVersion(b);
15932
+ if (!aParsed || !bParsed)
15933
+ return 0;
15934
+ if (aParsed.major !== bParsed.major) {
15935
+ return aParsed.major > bParsed.major ? 1 : -1;
15936
+ }
15937
+ if (aParsed.minor !== bParsed.minor) {
15938
+ return aParsed.minor > bParsed.minor ? 1 : -1;
15929
15939
  }
15930
- if (aPre && !bPre)
15940
+ if (aParsed.patch !== bParsed.patch) {
15941
+ return aParsed.patch > bParsed.patch ? 1 : -1;
15942
+ }
15943
+ if (aParsed.prerelease && !bParsed.prerelease)
15931
15944
  return -1;
15932
- if (!aPre && bPre)
15945
+ if (!aParsed.prerelease && bParsed.prerelease)
15933
15946
  return 1;
15934
- if (aPre && bPre)
15935
- return aPre < bPre ? -1 : aPre > bPre ? 1 : 0;
15947
+ if (aParsed.prerelease && bParsed.prerelease) {
15948
+ return aParsed.prerelease < bParsed.prerelease ? -1 : aParsed.prerelease > bParsed.prerelease ? 1 : 0;
15949
+ }
15936
15950
  return 0;
15937
15951
  }
15938
15952
 
@@ -17953,7 +17967,7 @@ async function handleEvidenceCommand(directory, args) {
17953
17967
  return formatTaskEvidenceMarkdown(evidenceData);
17954
17968
  }
17955
17969
  async function handleEvidenceSummaryCommand(directory) {
17956
- const { buildEvidenceSummary } = await import("./evidence-summary-service-5ww1npaa.js");
17970
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-ch74hb16.js");
17957
17971
  const artifact = await buildEvidenceSummary(directory);
17958
17972
  if (!artifact) {
17959
17973
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -32306,7 +32320,7 @@ function buildDetailedHelp(commandName, entry) {
32306
32320
  async function handleHelpCommand(ctx) {
32307
32321
  const targetCommand = ctx.args.join(" ");
32308
32322
  if (!targetCommand) {
32309
- const { buildHelpText } = await import("./index-etssqrff.js");
32323
+ const { buildHelpText } = await import("./index-sz3kw59p.js");
32310
32324
  return buildHelpText();
32311
32325
  }
32312
32326
  const tokens = targetCommand.split(/\s+/);
@@ -32315,7 +32329,7 @@ async function handleHelpCommand(ctx) {
32315
32329
  return _internals46.buildDetailedHelp(resolved.key, resolved.entry);
32316
32330
  }
32317
32331
  const similar = _internals46.findSimilarCommands(targetCommand);
32318
- const { buildHelpText: fullHelp } = await import("./index-etssqrff.js");
32332
+ const { buildHelpText: fullHelp } = await import("./index-sz3kw59p.js");
32319
32333
  if (similar.length > 0) {
32320
32334
  return `Command '/swarm ${targetCommand}' not found.
32321
32335
 
@@ -32448,7 +32462,7 @@ var COMMAND_REGISTRY = {
32448
32462
  },
32449
32463
  "guardrail explain": {
32450
32464
  handler: async (ctx) => {
32451
- const { handleGuardrailExplain } = await import("./guardrail-explain-s4c2h8mv.js");
32465
+ const { handleGuardrailExplain } = await import("./guardrail-explain-dkh5f7nf.js");
32452
32466
  return handleGuardrailExplain(ctx.directory, ctx.args);
32453
32467
  },
32454
32468
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  readSwarmFileAsync,
10
10
  validateSwarmPath
11
- } from "./index-94qwbx11.js";
11
+ } from "./index-7ztmmqpt.js";
12
12
  import {
13
13
  readCachedParsedFile
14
14
  } from "./index-jtqkh8jf.js";
@@ -12,7 +12,7 @@ import {
12
12
  detectPosixWrites,
13
13
  detectWindowsWrites,
14
14
  resolveWriteTargets
15
- } from "./index-1kcp4q4y.js";
15
+ } from "./index-wpnam1jh.js";
16
16
  import {
17
17
  checkFileAuthority,
18
18
  classifyFile,
package/dist/cli/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  getPluginLockFilePaths,
8
8
  package_default,
9
9
  resolveCommand
10
- } from "./index-1kcp4q4y.js";
10
+ } from "./index-wpnam1jh.js";
11
11
  import"./index-xsswhy6k.js";
12
12
  import"./index-ydgy7vg5.js";
13
13
  import"./index-vwyjkzgs.js";
@@ -16,13 +16,13 @@ import"./index-0d3pmjf9.js";
16
16
  import {
17
17
  DEFAULT_AGENT_CONFIGS
18
18
  } from "./index-7hnwnw5g.js";
19
- import"./index-9twtnjkv.js";
19
+ import"./index-y3x3gvy6.js";
20
20
  import"./index-adz3nk9b.js";
21
21
  import"./index-v4fcn4tr.js";
22
22
  import"./index-r8f89sm9.js";
23
23
  import"./index-9b7qp18e.js";
24
- import"./index-s3esnz7m.js";
25
- import"./index-94qwbx11.js";
24
+ import"./index-e9n3xsk0.js";
25
+ import"./index-7ztmmqpt.js";
26
26
  import"./index-jtqkh8jf.js";
27
27
  import"./index-5e4e2hvv.js";
28
28
  import"./index-p0arc26j.js";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  validateSwarmPath
4
- } from "./index-94qwbx11.js";
4
+ } from "./index-7ztmmqpt.js";
5
5
  import"./index-jtqkh8jf.js";
6
6
  import"./index-5e4e2hvv.js";
7
7
  import"./index-p0arc26j.js";
@@ -9,8 +9,8 @@ import {
9
9
  sweepStale,
10
10
  unsubscribe,
11
11
  updateSnapshot
12
- } from "./index-s3esnz7m.js";
13
- import"./index-94qwbx11.js";
12
+ } from "./index-e9n3xsk0.js";
13
+ import"./index-7ztmmqpt.js";
14
14
  import"./index-jtqkh8jf.js";
15
15
  import"./index-5e4e2hvv.js";
16
16
  import"./index-p0arc26j.js";
@@ -21,7 +21,11 @@ export declare const _internals: {
21
21
  readSwarmFileAsync: typeof readSwarmFileAsync;
22
22
  readCachedTextFile: typeof readCachedTextFile;
23
23
  };
24
- export declare function safeHook<I, O>(fn: (input: I, output: O) => Promise<void>): (input: I, output: O) => Promise<void>;
24
+ type HookHandler<I, O> = (input: I, output: O) => Promise<void>;
25
+ export declare function markFailClosed<I, O>(fn: HookHandler<I, O>): HookHandler<I, O> & {
26
+ __failClosed?: true;
27
+ };
28
+ export declare function safeHook<I, O>(fn: HookHandler<I, O>): HookHandler<I, O>;
25
29
  /**
26
30
  * `composeHandlers` runs handlers sequentially, wrapping EACH handler in
27
31
  * `safeHook` so any thrown error is downgraded to a warning. Use this for
@@ -37,7 +41,7 @@ export declare function safeHook<I, O>(fn: (input: I, output: O) => Promise<void
37
41
  *
38
42
  * Reference: AGENTS.md invariant 11 + Full-Auto v2 fail-closed contract.
39
43
  */
40
- export declare function composeHandlers<I, O>(...fns: Array<(input: I, output: O) => Promise<void>>): (input: I, output: O) => Promise<void>;
44
+ export declare function composeHandlers<I, O>(...fns: Array<HookHandler<I, O>>): HookHandler<I, O>;
41
45
  /**
42
46
  * `composeBlockingHandlers` runs handlers sequentially WITHOUT `safeHook`,
43
47
  * so any thrown error propagates to the caller and stops the chain.
@@ -62,7 +66,7 @@ export declare function composeHandlers<I, O>(...fns: Array<(input: I, output: O
62
66
  * place — silently swallowing a Full-Auto denial would be a runtime
63
67
  * fail-open and is a critical regression.
64
68
  */
65
- export declare function composeBlockingHandlers<I, O>(...fns: Array<(input: I, output: O) => Promise<void>>): (input: I, output: O) => Promise<void>;
69
+ export declare function composeBlockingHandlers<I, O>(...fns: Array<HookHandler<I, O>>): HookHandler<I, O>;
66
70
  /**
67
71
  * Validates that a filename is safe to use within the .swarm directory
68
72
  *
@@ -74,3 +78,4 @@ export declare function composeBlockingHandlers<I, O>(...fns: Array<(input: I, o
74
78
  export declare function validateSwarmPath(directory: string, filename: string): string;
75
79
  export declare function readSwarmFileAsync(directory: string, filename: string, cache?: Map<string, Promise<string | null>>): Promise<string | null>;
76
80
  export declare function estimateTokens(text: string): number;
81
+ export {};
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.99.6",
72
+ version: "7.99.7",
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",
@@ -18141,6 +18141,9 @@ var init_swarm_artifact_cache = __esm(() => {
18141
18141
  // src/hooks/utils.ts
18142
18142
  import * as fs4 from "node:fs";
18143
18143
  import * as path5 from "node:path";
18144
+ function isFailClosedHandler(value) {
18145
+ return typeof value === "function" && Object.hasOwn(value, "__failClosed") && value.__failClosed === true;
18146
+ }
18144
18147
  function safeHook(fn2) {
18145
18148
  return async (input, output) => {
18146
18149
  try {
@@ -18162,6 +18165,9 @@ function composeHandlers(...fns) {
18162
18165
  }
18163
18166
  return async (input, output) => {
18164
18167
  for (const fn2 of fns) {
18168
+ if (isFailClosedHandler(fn2)) {
18169
+ throw new Error("composeHandlers cannot wrap fail-closed handlers; use composeBlockingHandlers or await them directly");
18170
+ }
18165
18171
  const safeFn = _internals3.safeHook(fn2);
18166
18172
  await safeFn(input, output);
18167
18173
  }
@@ -43377,6 +43383,10 @@ function createToolBeforeHandler(ctx) {
43377
43383
  return;
43378
43384
  const executor = await getExecutor();
43379
43385
  if (!executor || !executor.isAvailable()) {
43386
+ if (!hasWarnedSandboxUnavailable) {
43387
+ hasWarnedSandboxUnavailable = true;
43388
+ warn("[guardrails] sandbox executor unavailable; shell commands will run unsandboxed");
43389
+ }
43380
43390
  appendGuardrailDecision({
43381
43391
  type: "sandbox_skip",
43382
43392
  ts: new Date().toISOString(),
@@ -43875,6 +43885,15 @@ function createToolBeforeHandler(ctx) {
43875
43885
  handleDelegatedWriteTracking(input.sessionID, input.tool, output.args);
43876
43886
  handleLoopDetection(input.sessionID, input.tool, output.args);
43877
43887
  handleTestSuiteBlocking(input.tool, output.args);
43888
+ const agentNameForSandbox = (() => {
43889
+ const rawAgent = swarmState.activeAgent.get(input.sessionID);
43890
+ return rawAgent ? stripKnownSwarmPrefix(rawAgent) : "unknown";
43891
+ })();
43892
+ const rawShellCommand = (() => {
43893
+ const bashArgs = output.args;
43894
+ return typeof bashArgs?.command === "string" ? bashArgs.command : "";
43895
+ })();
43896
+ await applySandboxExecution(input.sessionID, input.tool, output.args, agentNameForSandbox, rawShellCommand, shellAuditPath, shellAuditEnabled);
43878
43897
  const normalizedAuditTool = normalizeToolName(input.tool).toLowerCase();
43879
43898
  if (normalizedAuditTool === "bash" || normalizedAuditTool === "shell") {
43880
43899
  appendGuardrailDecision({
@@ -44221,17 +44240,10 @@ function createToolBeforeHandler(ctx) {
44221
44240
  elapsedMinutes,
44222
44241
  repetitionCount
44223
44242
  });
44224
- await applySandboxExecution(input.sessionID, input.tool, output.args, (() => {
44225
- const rawAgent = swarmState.activeAgent.get(input.sessionID);
44226
- return rawAgent ? stripKnownSwarmPrefix(rawAgent) : "unknown";
44227
- })(), (() => {
44228
- const bashArgs = output.args;
44229
- const rawCmd = typeof bashArgs?.command === "string" ? bashArgs.command : "";
44230
- return rawCmd;
44231
- })(), shellAuditPath, shellAuditEnabled);
44232
44243
  setStoredInputArgs(input.callID, output.args);
44233
44244
  };
44234
44245
  }
44246
+ var hasWarnedSandboxUnavailable = false;
44235
44247
  var init_tool_before = __esm(() => {
44236
44248
  init_tool_policy();
44237
44249
  init_constants();
@@ -76654,26 +76666,45 @@ function writeVersionCache(entry) {
76654
76666
  writeFileSync13(cacheFile(), JSON.stringify(entry, null, 2), "utf-8");
76655
76667
  } catch {}
76656
76668
  }
76669
+ function parseVersion(version3) {
76670
+ const trimmed = version3.trim();
76671
+ const match = SEMVER_REGEX.exec(trimmed);
76672
+ if (!match)
76673
+ return null;
76674
+ return {
76675
+ major: Number.parseInt(match[1], 10),
76676
+ minor: Number.parseInt(match[2], 10),
76677
+ patch: Number.parseInt(match[3], 10),
76678
+ prerelease: match[4] ?? null
76679
+ };
76680
+ }
76681
+ function normalizeVersionCandidate(version3) {
76682
+ if (typeof version3 !== "string")
76683
+ return null;
76684
+ const trimmed = version3.trim();
76685
+ return SEMVER_REGEX.test(trimmed) ? trimmed : null;
76686
+ }
76657
76687
  function compareVersions(a, b) {
76658
- const [aBase, aPre] = a.split("-", 2);
76659
- const [bBase, bPre] = b.split("-", 2);
76660
- const aParts = aBase.split(".").map((n) => Number.parseInt(n, 10) || 0);
76661
- const bParts = bBase.split(".").map((n) => Number.parseInt(n, 10) || 0);
76662
- const len = Math.max(aParts.length, bParts.length);
76663
- for (let i = 0;i < len; i++) {
76664
- const av = aParts[i] ?? 0;
76665
- const bv = bParts[i] ?? 0;
76666
- if (av > bv)
76667
- return 1;
76668
- if (av < bv)
76669
- return -1;
76688
+ const aParsed = parseVersion(a);
76689
+ const bParsed = parseVersion(b);
76690
+ if (!aParsed || !bParsed)
76691
+ return 0;
76692
+ if (aParsed.major !== bParsed.major) {
76693
+ return aParsed.major > bParsed.major ? 1 : -1;
76670
76694
  }
76671
- if (aPre && !bPre)
76695
+ if (aParsed.minor !== bParsed.minor) {
76696
+ return aParsed.minor > bParsed.minor ? 1 : -1;
76697
+ }
76698
+ if (aParsed.patch !== bParsed.patch) {
76699
+ return aParsed.patch > bParsed.patch ? 1 : -1;
76700
+ }
76701
+ if (aParsed.prerelease && !bParsed.prerelease)
76672
76702
  return -1;
76673
- if (!aPre && bPre)
76703
+ if (!aParsed.prerelease && bParsed.prerelease)
76674
76704
  return 1;
76675
- if (aPre && bPre)
76676
- return aPre < bPre ? -1 : aPre > bPre ? 1 : 0;
76705
+ if (aParsed.prerelease && bParsed.prerelease) {
76706
+ return aParsed.prerelease < bParsed.prerelease ? -1 : aParsed.prerelease > bParsed.prerelease ? 1 : 0;
76707
+ }
76677
76708
  return 0;
76678
76709
  }
76679
76710
  async function fetchLatestVersion(signal) {
@@ -76731,7 +76762,8 @@ async function runVersionCheck(runningVersion, emitWarning, now, fetchImpl) {
76731
76762
  const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
76732
76763
  let npmLatest = null;
76733
76764
  try {
76734
- npmLatest = await fetchImpl(controller.signal);
76765
+ const fetchedVersion = await fetchImpl(controller.signal);
76766
+ npmLatest = normalizeVersionCandidate(fetchedVersion);
76735
76767
  } finally {
76736
76768
  clearTimeout(timeout);
76737
76769
  }
@@ -76745,9 +76777,10 @@ function maybeWarn(runningVersion, npmLatest, emitWarning) {
76745
76777
  emitWarning(`[opencode-swarm] Update available: ${runningVersion} → ${npmLatest}. ` + "OpenCode caches plugins indefinitely. Run `bunx opencode-swarm update` to refresh.");
76746
76778
  }
76747
76779
  }
76748
- var NPM_REGISTRY_URL = "https://registry.npmjs.org/opencode-swarm/latest", CHECK_INTERVAL_MS, FETCH_TIMEOUT_MS = 5000, MAX_RESPONSE_BYTES, STRICT_SEMVER, _checkLatched = false, _internals43;
76780
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/opencode-swarm/latest", CHECK_INTERVAL_MS, FETCH_TIMEOUT_MS = 5000, SEMVER_REGEX, MAX_RESPONSE_BYTES, STRICT_SEMVER, _checkLatched = false, _internals43;
76749
76781
  var init_version_check = __esm(() => {
76750
76782
  CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
76783
+ SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
76751
76784
  MAX_RESPONSE_BYTES = 256 * 1024;
76752
76785
  STRICT_SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
76753
76786
  _internals43 = {
@@ -7,10 +7,6 @@ interface VersionCheckCache {
7
7
  npmLatest: string | null;
8
8
  }
9
9
  export declare function readVersionCache(): VersionCheckCache | null;
10
- /**
11
- * Compare two semver-ish version strings. Returns 1 if `a > b`, -1 if `a < b`,
12
- * 0 if equal. Treats prerelease tags as lower than the release. Pure function.
13
- */
14
10
  export declare function compareVersions(a: string, b: string): number;
15
11
  /**
16
12
  * Fetch the latest published version from the npm registry with strict,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.99.6",
3
+ "version": "7.99.7",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",