opencode-swarm 6.22.17 → 6.22.18

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
@@ -14200,6 +14200,15 @@ var init_logger = __esm(() => {
14200
14200
  DEBUG = process.env.OPENCODE_SWARM_DEBUG === "1";
14201
14201
  });
14202
14202
 
14203
+ // src/utils/regex.ts
14204
+ function escapeRegex2(s) {
14205
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14206
+ }
14207
+ function simpleGlobToRegex(pattern, flags = "i") {
14208
+ const escaped = pattern.split("*").map((starSegment) => starSegment.split("?").map(escapeRegex2).join(".")).join(".*");
14209
+ return new RegExp(`^${escaped}$`, flags);
14210
+ }
14211
+
14203
14212
  // src/utils/index.ts
14204
14213
  var init_utils = __esm(() => {
14205
14214
  init_errors3();
@@ -18522,7 +18531,7 @@ __export(exports_util2, {
18522
18531
  floatSafeRemainder: () => floatSafeRemainder2,
18523
18532
  finalizeIssue: () => finalizeIssue2,
18524
18533
  extend: () => extend2,
18525
- escapeRegex: () => escapeRegex2,
18534
+ escapeRegex: () => escapeRegex3,
18526
18535
  esc: () => esc2,
18527
18536
  defineLazy: () => defineLazy2,
18528
18537
  createTransparentProxy: () => createTransparentProxy2,
@@ -18769,7 +18778,7 @@ var getParsedType2 = (data) => {
18769
18778
  };
18770
18779
  var propertyKeyTypes2 = new Set(["string", "number", "symbol"]);
18771
18780
  var primitiveTypes2 = new Set(["string", "number", "bigint", "boolean", "symbol", "undefined"]);
18772
- function escapeRegex2(str) {
18781
+ function escapeRegex3(str) {
18773
18782
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18774
18783
  }
18775
18784
  function clone2(inst, def, params) {
@@ -19922,7 +19931,7 @@ var $ZodCheckUpperCase2 = /* @__PURE__ */ $constructor2("$ZodCheckUpperCase", (i
19922
19931
  });
19923
19932
  var $ZodCheckIncludes2 = /* @__PURE__ */ $constructor2("$ZodCheckIncludes", (inst, def) => {
19924
19933
  $ZodCheck2.init(inst, def);
19925
- const escapedRegex = escapeRegex2(def.includes);
19934
+ const escapedRegex = escapeRegex3(def.includes);
19926
19935
  const pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);
19927
19936
  def.pattern = pattern;
19928
19937
  inst._zod.onattach.push((inst2) => {
@@ -19946,7 +19955,7 @@ var $ZodCheckIncludes2 = /* @__PURE__ */ $constructor2("$ZodCheckIncludes", (ins
19946
19955
  });
19947
19956
  var $ZodCheckStartsWith2 = /* @__PURE__ */ $constructor2("$ZodCheckStartsWith", (inst, def) => {
19948
19957
  $ZodCheck2.init(inst, def);
19949
- const pattern = new RegExp(`^${escapeRegex2(def.prefix)}.*`);
19958
+ const pattern = new RegExp(`^${escapeRegex3(def.prefix)}.*`);
19950
19959
  def.pattern ?? (def.pattern = pattern);
19951
19960
  inst._zod.onattach.push((inst2) => {
19952
19961
  const bag = inst2._zod.bag;
@@ -19969,7 +19978,7 @@ var $ZodCheckStartsWith2 = /* @__PURE__ */ $constructor2("$ZodCheckStartsWith",
19969
19978
  });
19970
19979
  var $ZodCheckEndsWith2 = /* @__PURE__ */ $constructor2("$ZodCheckEndsWith", (inst, def) => {
19971
19980
  $ZodCheck2.init(inst, def);
19972
- const pattern = new RegExp(`.*${escapeRegex2(def.suffix)}$`);
19981
+ const pattern = new RegExp(`.*${escapeRegex3(def.suffix)}$`);
19973
19982
  def.pattern ?? (def.pattern = pattern);
19974
19983
  inst._zod.onattach.push((inst2) => {
19975
19984
  const bag = inst2._zod.bag;
@@ -21378,7 +21387,7 @@ var $ZodEnum2 = /* @__PURE__ */ $constructor2("$ZodEnum", (inst, def) => {
21378
21387
  const values = getEnumValues2(def.entries);
21379
21388
  const valuesSet = new Set(values);
21380
21389
  inst._zod.values = valuesSet;
21381
- inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes2.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex2(o) : o.toString()).join("|")})$`);
21390
+ inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes2.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex3(o) : o.toString()).join("|")})$`);
21382
21391
  inst._zod.parse = (payload, _ctx) => {
21383
21392
  const input = payload.value;
21384
21393
  if (valuesSet.has(input)) {
@@ -21399,7 +21408,7 @@ var $ZodLiteral2 = /* @__PURE__ */ $constructor2("$ZodLiteral", (inst, def) => {
21399
21408
  throw new Error("Cannot create literal schema with no valid values");
21400
21409
  }
21401
21410
  inst._zod.values = new Set(def.values);
21402
- inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex2(o) : o ? escapeRegex2(o.toString()) : String(o)).join("|")})$`);
21411
+ inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex3(o) : o ? escapeRegex3(o.toString()) : String(o)).join("|")})$`);
21403
21412
  inst._zod.parse = (payload, _ctx) => {
21404
21413
  const input = payload.value;
21405
21414
  if (inst._zod.values.has(input)) {
@@ -21747,7 +21756,7 @@ var $ZodTemplateLiteral2 = /* @__PURE__ */ $constructor2("$ZodTemplateLiteral",
21747
21756
  const end = source.endsWith("$") ? source.length - 1 : source.length;
21748
21757
  regexParts.push(source.slice(start, end));
21749
21758
  } else if (part === null || primitiveTypes2.has(typeof part)) {
21750
- regexParts.push(escapeRegex2(`${part}`));
21759
+ regexParts.push(escapeRegex3(`${part}`));
21751
21760
  } else {
21752
21761
  throw new Error(`Invalid template literal part: ${part}`);
21753
21762
  }
@@ -32567,10 +32576,8 @@ function findBuildFiles(workingDir, patterns) {
32567
32576
  const dir = workingDir;
32568
32577
  try {
32569
32578
  const files = fs2.readdirSync(dir);
32570
- const matches = files.filter((f) => {
32571
- const regex = new RegExp(`^${pattern.replace(/\*/g, ".*")}$`);
32572
- return regex.test(f);
32573
- });
32579
+ const regex = simpleGlobToRegex(pattern);
32580
+ const matches = files.filter((f) => regex.test(f));
32574
32581
  if (matches.length > 0) {
32575
32582
  return path10.join(dir, matches[0]);
32576
32583
  }
@@ -32623,7 +32630,7 @@ function findAllBuildFiles(workingDir) {
32623
32630
  for (const ecosystem of ECOSYSTEMS) {
32624
32631
  for (const pattern of ecosystem.buildFiles) {
32625
32632
  if (pattern.includes("*")) {
32626
- const regex = new RegExp(`^${pattern.replace(/\*/g, ".*")}$`);
32633
+ const regex = simpleGlobToRegex(pattern);
32627
32634
  findFilesRecursive(workingDir, regex, allBuildFiles);
32628
32635
  } else {
32629
32636
  const filePath = path10.join(workingDir, pattern);
package/dist/index.js CHANGED
@@ -15186,6 +15186,15 @@ var init_logger = __esm(() => {
15186
15186
  DEBUG = process.env.OPENCODE_SWARM_DEBUG === "1";
15187
15187
  });
15188
15188
 
15189
+ // src/utils/regex.ts
15190
+ function escapeRegex2(s) {
15191
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
15192
+ }
15193
+ function simpleGlobToRegex(pattern, flags2 = "i") {
15194
+ const escaped = pattern.split("*").map((starSegment) => starSegment.split("?").map(escapeRegex2).join(".")).join(".*");
15195
+ return new RegExp(`^${escaped}$`, flags2);
15196
+ }
15197
+
15189
15198
  // src/utils/index.ts
15190
15199
  var init_utils = __esm(() => {
15191
15200
  init_errors3();
@@ -18711,7 +18720,7 @@ __export(exports_util2, {
18711
18720
  floatSafeRemainder: () => floatSafeRemainder2,
18712
18721
  finalizeIssue: () => finalizeIssue2,
18713
18722
  extend: () => extend2,
18714
- escapeRegex: () => escapeRegex2,
18723
+ escapeRegex: () => escapeRegex3,
18715
18724
  esc: () => esc2,
18716
18725
  defineLazy: () => defineLazy2,
18717
18726
  createTransparentProxy: () => createTransparentProxy2,
@@ -18898,7 +18907,7 @@ function numKeys2(data) {
18898
18907
  }
18899
18908
  return keyCount;
18900
18909
  }
18901
- function escapeRegex2(str) {
18910
+ function escapeRegex3(str) {
18902
18911
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18903
18912
  }
18904
18913
  function clone2(inst, def, params) {
@@ -20121,7 +20130,7 @@ var init_checks3 = __esm(() => {
20121
20130
  });
20122
20131
  $ZodCheckIncludes2 = /* @__PURE__ */ $constructor2("$ZodCheckIncludes", (inst, def) => {
20123
20132
  $ZodCheck2.init(inst, def);
20124
- const escapedRegex = escapeRegex2(def.includes);
20133
+ const escapedRegex = escapeRegex3(def.includes);
20125
20134
  const pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);
20126
20135
  def.pattern = pattern;
20127
20136
  inst._zod.onattach.push((inst2) => {
@@ -20145,7 +20154,7 @@ var init_checks3 = __esm(() => {
20145
20154
  });
20146
20155
  $ZodCheckStartsWith2 = /* @__PURE__ */ $constructor2("$ZodCheckStartsWith", (inst, def) => {
20147
20156
  $ZodCheck2.init(inst, def);
20148
- const pattern = new RegExp(`^${escapeRegex2(def.prefix)}.*`);
20157
+ const pattern = new RegExp(`^${escapeRegex3(def.prefix)}.*`);
20149
20158
  def.pattern ?? (def.pattern = pattern);
20150
20159
  inst._zod.onattach.push((inst2) => {
20151
20160
  const bag = inst2._zod.bag;
@@ -20168,7 +20177,7 @@ var init_checks3 = __esm(() => {
20168
20177
  });
20169
20178
  $ZodCheckEndsWith2 = /* @__PURE__ */ $constructor2("$ZodCheckEndsWith", (inst, def) => {
20170
20179
  $ZodCheck2.init(inst, def);
20171
- const pattern = new RegExp(`.*${escapeRegex2(def.suffix)}$`);
20180
+ const pattern = new RegExp(`.*${escapeRegex3(def.suffix)}$`);
20172
20181
  def.pattern ?? (def.pattern = pattern);
20173
20182
  inst._zod.onattach.push((inst2) => {
20174
20183
  const bag = inst2._zod.bag;
@@ -21660,7 +21669,7 @@ var init_schemas3 = __esm(() => {
21660
21669
  const values = getEnumValues2(def.entries);
21661
21670
  const valuesSet = new Set(values);
21662
21671
  inst._zod.values = valuesSet;
21663
- inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes2.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex2(o) : o.toString()).join("|")})$`);
21672
+ inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes2.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex3(o) : o.toString()).join("|")})$`);
21664
21673
  inst._zod.parse = (payload, _ctx) => {
21665
21674
  const input = payload.value;
21666
21675
  if (valuesSet.has(input)) {
@@ -21681,7 +21690,7 @@ var init_schemas3 = __esm(() => {
21681
21690
  throw new Error("Cannot create literal schema with no valid values");
21682
21691
  }
21683
21692
  inst._zod.values = new Set(def.values);
21684
- inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex2(o) : o ? escapeRegex2(o.toString()) : String(o)).join("|")})$`);
21693
+ inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex3(o) : o ? escapeRegex3(o.toString()) : String(o)).join("|")})$`);
21685
21694
  inst._zod.parse = (payload, _ctx) => {
21686
21695
  const input = payload.value;
21687
21696
  if (inst._zod.values.has(input)) {
@@ -21968,7 +21977,7 @@ var init_schemas3 = __esm(() => {
21968
21977
  const end = source.endsWith("$") ? source.length - 1 : source.length;
21969
21978
  regexParts.push(source.slice(start2, end));
21970
21979
  } else if (part === null || primitiveTypes2.has(typeof part)) {
21971
- regexParts.push(escapeRegex2(`${part}`));
21980
+ regexParts.push(escapeRegex3(`${part}`));
21972
21981
  } else {
21973
21982
  throw new Error(`Invalid template literal part: ${part}`);
21974
21983
  }
@@ -32859,10 +32868,8 @@ function findBuildFiles(workingDir, patterns) {
32859
32868
  const dir = workingDir;
32860
32869
  try {
32861
32870
  const files = fs7.readdirSync(dir);
32862
- const matches = files.filter((f) => {
32863
- const regex = new RegExp(`^${pattern.replace(/\*/g, ".*")}$`);
32864
- return regex.test(f);
32865
- });
32871
+ const regex = simpleGlobToRegex(pattern);
32872
+ const matches = files.filter((f) => regex.test(f));
32866
32873
  if (matches.length > 0) {
32867
32874
  return path19.join(dir, matches[0]);
32868
32875
  }
@@ -32915,7 +32922,7 @@ function findAllBuildFiles(workingDir) {
32915
32922
  for (const ecosystem of ECOSYSTEMS) {
32916
32923
  for (const pattern of ecosystem.buildFiles) {
32917
32924
  if (pattern.includes("*")) {
32918
- const regex = new RegExp(`^${pattern.replace(/\*/g, ".*")}$`);
32925
+ const regex = simpleGlobToRegex(pattern);
32919
32926
  findFilesRecursive(workingDir, regex, allBuildFiles);
32920
32927
  } else {
32921
32928
  const filePath = path19.join(workingDir, pattern);
@@ -54835,7 +54842,7 @@ async function executePhaseComplete(args2, workingDirectory) {
54835
54842
  const phaseObj = plan.phases.find((p) => p.id === phase);
54836
54843
  if (phaseObj) {
54837
54844
  phaseObj.status = "completed";
54838
- fs25.writeFileSync(planPath, JSON.stringify(plan, null, 2) + `
54845
+ fs25.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
54839
54846
  `, "utf-8");
54840
54847
  }
54841
54848
  } catch (error93) {
@@ -55966,6 +55973,7 @@ function getLanguageForExtension(extension) {
55966
55973
  }
55967
55974
 
55968
55975
  // src/tools/placeholder-scan.ts
55976
+ init_utils();
55969
55977
  var MAX_FILE_SIZE = 1024 * 1024;
55970
55978
  var SUPPORTED_PARSER_EXTENSIONS = new Set([
55971
55979
  ".js",
@@ -56524,7 +56532,7 @@ function matchesGlobSegment(path40, glob) {
56524
56532
  }
56525
56533
  return matchGlobSegment(globSegments, pathSegments);
56526
56534
  }
56527
- function simpleGlobToRegex(glob) {
56535
+ function simpleGlobToRegex2(glob) {
56528
56536
  if (!glob) {
56529
56537
  return /.*/;
56530
56538
  }
@@ -56552,7 +56560,7 @@ function globMatches(path40, glob) {
56552
56560
  if (hasGlobstar(normalizedGlob)) {
56553
56561
  return matchesGlobSegment(normalizedPath, normalizedGlob);
56554
56562
  }
56555
- const regex = simpleGlobToRegex(normalizedGlob);
56563
+ const regex = simpleGlobToRegex2(normalizedGlob);
56556
56564
  return regex.test(normalizedPath);
56557
56565
  }
56558
56566
  function shouldExcludeFile(filePath, excludeGlobs) {
@@ -58862,6 +58870,9 @@ init_manager();
58862
58870
  import * as fs31 from "fs";
58863
58871
  import * as path43 from "path";
58864
58872
 
58873
+ // src/sbom/detectors/index.ts
58874
+ init_utils();
58875
+
58865
58876
  // src/sbom/detectors/dart.ts
58866
58877
  function parsePubspecLock(content) {
58867
58878
  const components = [];
@@ -59628,10 +59639,7 @@ var allDetectors = [
59628
59639
  ];
59629
59640
  function findDetectorsForFile(filePath) {
59630
59641
  const fileName = filePath.split(/[/\\]/).pop() || "";
59631
- return allDetectors.filter((detector) => detector.patterns.some((pattern) => {
59632
- const regex = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".");
59633
- return new RegExp(regex, "i").test(fileName);
59634
- }));
59642
+ return allDetectors.filter((detector) => detector.patterns.some((pattern) => simpleGlobToRegex(pattern).test(fileName)));
59635
59643
  }
59636
59644
  function detectComponents(filePath, content) {
59637
59645
  const detectors = findDetectorsForFile(filePath);
@@ -59698,6 +59706,7 @@ function serializeCycloneDX(bom) {
59698
59706
  }
59699
59707
 
59700
59708
  // src/tools/sbom-generate.ts
59709
+ init_utils();
59701
59710
  init_create_tool();
59702
59711
  var DEFAULT_OUTPUT_DIR = ".swarm/evidence/sbom";
59703
59712
  function findManifestFiles(rootDir) {
@@ -59715,8 +59724,7 @@ function findManifestFiles(rootDir) {
59715
59724
  searchDir(fullPath);
59716
59725
  } else if (entry.isFile()) {
59717
59726
  for (const pattern of patterns) {
59718
- const regex = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".");
59719
- if (new RegExp(regex, "i").test(entry.name)) {
59727
+ if (simpleGlobToRegex(pattern).test(entry.name)) {
59720
59728
  manifestFiles.push(path43.relative(rootDir, fullPath));
59721
59729
  break;
59722
59730
  }
@@ -59738,8 +59746,7 @@ function findManifestFilesInDirs(directories, workingDir) {
59738
59746
  const fullPath = path43.join(dir, entry.name);
59739
59747
  if (entry.isFile()) {
59740
59748
  for (const pattern of patterns) {
59741
- const regex = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".");
59742
- if (new RegExp(regex, "i").test(entry.name)) {
59749
+ if (simpleGlobToRegex(pattern).test(entry.name)) {
59743
59750
  found.push(path43.relative(workingDir, fullPath));
59744
59751
  break;
59745
59752
  }
@@ -60593,6 +60600,7 @@ init_test_runner();
60593
60600
 
60594
60601
  // src/tools/todo-extract.ts
60595
60602
  init_dist();
60603
+ init_utils();
60596
60604
  init_create_tool();
60597
60605
  import * as fs34 from "fs";
60598
60606
  import * as path46 from "path";
@@ -60720,7 +60728,7 @@ function parseTodoComments(content, filePath, tagsSet) {
60720
60728
  const entries = [];
60721
60729
  const lines = content.split(`
60722
60730
  `);
60723
- const tagPattern = Array.from(tagsSet).join("|");
60731
+ const tagPattern = Array.from(tagsSet).map(escapeRegex2).join("|");
60724
60732
  const regex = new RegExp(`\\b(${tagPattern})\\b[:\\s]?`, "i");
60725
60733
  for (let i2 = 0;i2 < lines.length; i2++) {
60726
60734
  const line = lines[i2];
@@ -1,3 +1,4 @@
1
1
  export { CLIError, ConfigError, HookError, SwarmError, ToolError, } from './errors';
2
2
  export { error, log, warn } from './logger';
3
3
  export { deepMerge, MAX_MERGE_DEPTH } from './merge';
4
+ export { escapeRegex, simpleGlobToRegex } from './regex';
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Centralized regex safety utilities.
3
+ *
4
+ * Every call-site that builds a RegExp from runtime strings
5
+ * (user config, glob patterns, tool input) MUST go through one of
6
+ * these helpers to prevent ReDoS and broken matching.
7
+ */
8
+ /**
9
+ * Escape all regex metacharacters in a string so it can be
10
+ * safely interpolated into a `new RegExp(...)` call.
11
+ *
12
+ * Covers the full set: . * + ? ^ $ { } ( ) | [ ] \
13
+ */
14
+ export declare function escapeRegex(s: string): string;
15
+ /**
16
+ * Convert a simple glob pattern (supports `*` and `?` wildcards)
17
+ * into an anchored, case-insensitive RegExp.
18
+ *
19
+ * All other regex metacharacters in the pattern are escaped first,
20
+ * so filenames containing `.`, `(`, `[`, etc. match literally.
21
+ *
22
+ * Semantics:
23
+ * `*` → `.*` (zero or more of any character)
24
+ * `?` → `.` (exactly one character)
25
+ *
26
+ * This is intentionally simple — it does NOT handle `**` / globstar.
27
+ * For globstar support see `quality/metrics.ts` which has its own
28
+ * path-aware implementation.
29
+ */
30
+ export declare function simpleGlobToRegex(pattern: string, flags?: string): RegExp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.22.17",
3
+ "version": "6.22.18",
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",