@wrongstack/core 0.77.0 → 0.84.1

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.
Files changed (80) hide show
  1. package/dist/{agent-bridge-EWdqs8v6.d.ts → agent-bridge-C9P_HPez.d.ts} +2 -2
  2. package/dist/{agent-subagent-runner-D8qW8OSC.d.ts → agent-subagent-runner-2Aq0jOSj.d.ts} +107 -102
  3. package/dist/{compactor-D_ExJajC.d.ts → compactor-CJq7LQev.d.ts} +3 -3
  4. package/dist/{config-Dy0CK_o6.d.ts → config-_DZ7dN-T.d.ts} +77 -75
  5. package/dist/{context-y87Jc5ei.d.ts → context-ToHAp4-U.d.ts} +119 -90
  6. package/dist/coordination/index.d.ts +16 -16
  7. package/dist/coordination/index.js +318 -37
  8. package/dist/coordination/index.js.map +1 -1
  9. package/dist/defaults/index.d.ts +32 -32
  10. package/dist/defaults/index.js +433 -81
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{director-state-BmYi3DGA.d.ts → director-state-CgIc30qi.d.ts} +19 -19
  13. package/dist/{events-CYaoLN5_.d.ts → events-DnRqXaZ3.d.ts} +43 -42
  14. package/dist/execution/index.d.ts +53 -53
  15. package/dist/execution/index.js +72 -29
  16. package/dist/execution/index.js.map +1 -1
  17. package/dist/extension/index.d.ts +9 -9
  18. package/dist/extension/index.js +8 -1
  19. package/dist/extension/index.js.map +1 -1
  20. package/dist/{goal-store-C7jcumEh.d.ts → goal-store-DvWLNu52.d.ts} +4 -4
  21. package/dist/{index-DIxjTOga.d.ts → index-BNOLadHw.d.ts} +28 -28
  22. package/dist/{index-Dsda0uCn.d.ts → index-N0_c4bHQ.d.ts} +45 -45
  23. package/dist/index.d.ts +167 -167
  24. package/dist/index.js +617 -155
  25. package/dist/index.js.map +1 -1
  26. package/dist/infrastructure/index.d.ts +9 -9
  27. package/dist/infrastructure/index.js +13 -5
  28. package/dist/infrastructure/index.js.map +1 -1
  29. package/dist/kernel/index.d.ts +14 -14
  30. package/dist/kernel/index.js +7 -0
  31. package/dist/kernel/index.js.map +1 -1
  32. package/dist/logger-B72yyPc6.d.ts +12 -0
  33. package/dist/{logger-BppKxDqZ.d.ts → logger-C_27pj9i.d.ts} +6 -7
  34. package/dist/{mcp-servers-T0O6UN_w.d.ts → mcp-servers-Dck3T85_.d.ts} +20 -20
  35. package/dist/{mode-BO4SEUIv.d.ts → mode-CHo2XtHs.d.ts} +4 -4
  36. package/dist/models/index.d.ts +10 -10
  37. package/dist/models/index.js +8 -2
  38. package/dist/models/index.js.map +1 -1
  39. package/dist/{models-registry-BcYJDKLm.d.ts → models-registry-Be3osGt5.d.ts} +28 -28
  40. package/dist/{models-registry-Cuq1C8V9.d.ts → models-registry-Boz639EI.d.ts} +12 -12
  41. package/dist/{multi-agent-coordinator-DpbG3wiy.d.ts → multi-agent-coordinator-DllpCVkF.d.ts} +12 -12
  42. package/dist/{null-fleet-bus-u5ys3lW_.d.ts → null-fleet-bus-BY0AN-sr.d.ts} +121 -121
  43. package/dist/observability/index.d.ts +41 -41
  44. package/dist/observability/index.js.map +1 -1
  45. package/dist/{observability-BhnVLBLS.d.ts → observability-CoSNZdhX.d.ts} +4 -4
  46. package/dist/{parallel-eternal-engine-Dn0P8Pbj.d.ts → parallel-eternal-engine-D402RASp.d.ts} +49 -49
  47. package/dist/{path-resolver-B32v2JIq.d.ts → path-resolver-UPFTsDyD.d.ts} +6 -6
  48. package/dist/{permission-V5BLOrY6.d.ts → permission-14CChMmO.d.ts} +10 -8
  49. package/dist/{permission-policy-CBVx-d-8.d.ts → permission-policy-gW5htOo1.d.ts} +7 -7
  50. package/dist/{plan-templates-BcUwLlMQ.d.ts → plan-templates-DRvPgkfZ.d.ts} +65 -32
  51. package/dist/{provider-runner-CSi_7l0h.d.ts → provider-runner-COAJM8tC.d.ts} +6 -6
  52. package/dist/{retry-policy-CG3qvH_e.d.ts → retry-policy-DSu6O6rD.d.ts} +4 -4
  53. package/dist/sdd/index.d.ts +47 -47
  54. package/dist/sdd/index.js +47 -22
  55. package/dist/sdd/index.js.map +1 -1
  56. package/dist/{secret-scrubber-7rSC_emZ.d.ts → secret-scrubber-yGBFQYju.d.ts} +10 -2
  57. package/dist/security/index.d.ts +7 -7
  58. package/dist/security/index.js +15 -8
  59. package/dist/security/index.js.map +1 -1
  60. package/dist/{selector-RvBR_YRW.d.ts → selector-11-fm95U.d.ts} +2 -2
  61. package/dist/{session-event-bridge-CDHxcmQU.d.ts → session-event-bridge-D0u-x576.d.ts} +7 -7
  62. package/dist/{session-reader-BIpwM60D.d.ts → session-reader-BQU-toaN.d.ts} +23 -23
  63. package/dist/{skill-CxuWrsKK.d.ts → skill-BJeF2DwY.d.ts} +1 -1
  64. package/dist/skills/index.d.ts +9 -9
  65. package/dist/skills/index.js +15 -3
  66. package/dist/skills/index.js.map +1 -1
  67. package/dist/storage/index.d.ts +15 -15
  68. package/dist/storage/index.js +378 -76
  69. package/dist/storage/index.js.map +1 -1
  70. package/dist/{system-prompt-CA11g6Jo.d.ts → system-prompt-C0rLCeyn.d.ts} +16 -11
  71. package/dist/{task-graph-D1YQbpxF.d.ts → task-graph-CikNdRTG.d.ts} +22 -22
  72. package/dist/types/index.d.ts +26 -26
  73. package/dist/types/index.js +53 -17
  74. package/dist/types/index.js.map +1 -1
  75. package/dist/utils/index.d.ts +57 -45
  76. package/dist/utils/index.js +66 -12
  77. package/dist/utils/index.js.map +1 -1
  78. package/dist/{wstack-paths-D7evAFWM.d.ts → wstack-paths-BQMvEllz.d.ts} +2 -2
  79. package/package.json +1 -1
  80. package/dist/logger-DDd5C--Z.d.ts +0 -12
@@ -7,6 +7,12 @@ import * as os from 'os';
7
7
  import { EventEmitter } from 'events';
8
8
 
9
9
  // src/utils/token-estimate.ts
10
+ function expectDefined(value) {
11
+ if (value === null || value === void 0) {
12
+ throw new Error("Expected value to be defined");
13
+ }
14
+ return value;
15
+ }
10
16
  var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
11
17
  var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
12
18
  var ESTIMATE_CACHE_MAX_SIZE = 1e4;
@@ -16,7 +22,7 @@ function getCachedEstimate(key, compute) {
16
22
  if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
17
23
  const keys = [...ESTIMATE_CACHE.keys()];
18
24
  for (let i = 0; i < Math.floor(ESTIMATE_CACHE_MAX_SIZE / 4); i++) {
19
- ESTIMATE_CACHE.delete(keys[i]);
25
+ ESTIMATE_CACHE.delete(expectDefined(keys[i]));
20
26
  }
21
27
  }
22
28
  const estimate = compute();
@@ -94,6 +100,12 @@ function estimateRequestTokensCalibrated(messages, systemPrompt, tools) {
94
100
  }
95
101
 
96
102
  // src/utils/message-invariants.ts
103
+ function expectDefined2(value) {
104
+ if (value === null || value === void 0) {
105
+ throw new Error("Expected value to be defined");
106
+ }
107
+ return value;
108
+ }
97
109
  function repairToolUseAdjacency(messages) {
98
110
  const removedToolUses = [];
99
111
  const removedToolResults = [];
@@ -101,7 +113,7 @@ function repairToolUseAdjacency(messages) {
101
113
  let changed = false;
102
114
  const out = [];
103
115
  for (let i = 0; i < messages.length; i++) {
104
- const original = messages[i];
116
+ const original = expectDefined2(messages[i]);
105
117
  let msg = original;
106
118
  if (hasToolUse(msg)) {
107
119
  const nextIds = toolResultIds(messages[i + 1]);
@@ -498,7 +510,7 @@ var IntelligentCompactor = class {
498
510
  maxTokens: 1024
499
511
  };
500
512
  const ac = ctx.signal ? void 0 : new AbortController();
501
- const signal = ctx.signal ?? ac.signal;
513
+ const signal = ctx.signal ?? ac?.signal;
502
514
  const res = await this.provider.complete(req, { signal });
503
515
  const textBlocks = res.content.filter(isTextBlock);
504
516
  return textBlocks.map((b) => b.text).join("\n").trim() || "(empty summary)";
@@ -601,6 +613,12 @@ var IntelligentCompactor = class {
601
613
  };
602
614
 
603
615
  // src/models/llm-selector.ts
616
+ function expectDefined3(value) {
617
+ if (value === null || value === void 0) {
618
+ throw new Error("Expected value to be defined");
619
+ }
620
+ return value;
621
+ }
604
622
  var DEFAULT_SYSTEM_PROMPT = `You are a context pruning assistant. Given a conversation history and a token budget, decide which message ranges are worth keeping verbatim and which should be collapsed into summaries.
605
623
 
606
624
  Output a JSON object with this structure:
@@ -641,7 +659,7 @@ function formatMessages(messages, maxChars = 8e3) {
641
659
  const lines = [];
642
660
  let used = 0;
643
661
  for (let i = 0; i < messages.length; i++) {
644
- const m = messages[i];
662
+ const m = expectDefined3(messages[i]);
645
663
  const role = m.role.padEnd(10, " ");
646
664
  let text;
647
665
  if (typeof m.content === "string") {
@@ -706,7 +724,7 @@ IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiv
706
724
  let tokenCount = 0;
707
725
  let startIdx = 0;
708
726
  for (let i = messages.length - 1; i >= 0; i--) {
709
- const m = messages[i];
727
+ const m = expectDefined3(messages[i]);
710
728
  const cost = typeof m.content === "string" ? Math.ceil(m.content.length / 4) : m.content.reduce(
711
729
  (acc, b) => acc + (b.type === "text" ? Math.ceil(b.text.length / 4) : Math.ceil(JSON.stringify(b).length / 4)),
712
730
  0
@@ -917,6 +935,7 @@ Summarize the following message range:`;
917
935
  let boundary = preserveIdx;
918
936
  for (let i = preserveIdx; i < messages.length && i < preserveIdx + 6; i++) {
919
937
  const m = messages[i];
938
+ if (!m) continue;
920
939
  if (m.role === "user" && this.hasTextContent(m)) {
921
940
  boundary = i;
922
941
  break;
@@ -1438,6 +1457,12 @@ function createToolOutputSerializer(opts = {}) {
1438
1457
  }
1439
1458
 
1440
1459
  // src/execution/tool-executor.ts
1460
+ function expectDefined4(value) {
1461
+ if (value === null || value === void 0) {
1462
+ throw new Error("Expected value to be defined");
1463
+ }
1464
+ return value;
1465
+ }
1441
1466
  var ToolExecutor = class {
1442
1467
  constructor(registry, opts) {
1443
1468
  this.registry = registry;
@@ -1726,6 +1751,9 @@ ${post.additionalContext}` };
1726
1751
  async runStreamedTool(tool, input, ctx, signal, toolUseId) {
1727
1752
  let finalOutput;
1728
1753
  let sawFinal = false;
1754
+ if (!tool.executeStream) {
1755
+ throw new Error(`Tool "${tool.name}" does not support streaming execution`);
1756
+ }
1729
1757
  const stream = tool.executeStream(input, ctx, { signal });
1730
1758
  for await (const ev of stream) {
1731
1759
  if (ev.type === "final") {
@@ -1830,7 +1858,7 @@ function hasMalformedArguments(input) {
1830
1858
  function extractMalformedRaw(input) {
1831
1859
  if (!hasMalformedArguments(input)) return void 0;
1832
1860
  const obj = input;
1833
- const value = obj[Object.keys(obj)[0]];
1861
+ const value = obj[expectDefined4(Object.keys(obj)[0])];
1834
1862
  if (value === void 0 || value === null) return void 0;
1835
1863
  if (typeof value === "string") return value;
1836
1864
  try {
@@ -2151,6 +2179,11 @@ function appendJournal(goal, entry) {
2151
2179
  };
2152
2180
  }
2153
2181
 
2182
+ // src/utils/sleep.ts
2183
+ function sleep(ms) {
2184
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
2185
+ }
2186
+
2154
2187
  // src/execution/eternal-autonomy.ts
2155
2188
  var execFileP = promisify(execFile);
2156
2189
  var BRAINSTORM_DONE = /* @__PURE__ */ Symbol("brainstorm-done");
@@ -2721,9 +2754,6 @@ ${recentJournal}` : "No prior iterations.",
2721
2754
  await saveGoal(this.goalPath, { ...current, engineState: state });
2722
2755
  }
2723
2756
  };
2724
- function sleep(ms) {
2725
- return new Promise((resolve2) => setTimeout(resolve2, ms));
2726
- }
2727
2757
 
2728
2758
  // src/coordination/subagent-budget.ts
2729
2759
  var BudgetExceededError = class extends Error {
@@ -2887,16 +2917,16 @@ var SubagentBudget = class _SubagentBudget {
2887
2917
  }
2888
2918
  if (exceeded.length === 0) return [];
2889
2919
  if (!this._onThreshold) {
2890
- const first2 = exceeded[0];
2920
+ const first2 = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
2891
2921
  throw new BudgetExceededError(first2.kind, first2.limit, first2.used);
2892
2922
  }
2893
2923
  if (this._mode === "sync") {
2894
- const first2 = exceeded[0];
2924
+ const first2 = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
2895
2925
  throw new BudgetExceededError(first2.kind, first2.limit, first2.used);
2896
2926
  }
2897
2927
  const bus = this._events;
2898
2928
  if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
2899
- const first2 = exceeded[0];
2929
+ const first2 = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
2900
2930
  throw new BudgetExceededError(first2.kind, first2.limit, first2.used);
2901
2931
  }
2902
2932
  for (const entry of exceeded) {
@@ -2904,8 +2934,9 @@ var SubagentBudget = class _SubagentBudget {
2904
2934
  const decision2 = this._negotiateExtension(entry.kind, exceeded);
2905
2935
  this._pendingNegotiations.set(entry.kind, decision2);
2906
2936
  }
2907
- const first = exceeded[0];
2937
+ const first = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
2908
2938
  const decision = this._pendingNegotiations.get(first.kind);
2939
+ if (!decision) throw new Error(`No pending negotiation for ${first.kind}`);
2909
2940
  throw new BudgetThresholdSignal(first.kind, first.limit, first.used, decision);
2910
2941
  }
2911
2942
  /**
@@ -2927,8 +2958,11 @@ var SubagentBudget = class _SubagentBudget {
2927
2958
  * a fresh signal.
2928
2959
  */
2929
2960
  async _negotiateExtension(kind, exceeded) {
2961
+ if (!this._onThreshold) {
2962
+ return "stop";
2963
+ }
2930
2964
  try {
2931
- const first = exceeded[0];
2965
+ const first = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
2932
2966
  const result = this._onThreshold({
2933
2967
  kind: first.kind,
2934
2968
  used: first.used,
@@ -5397,6 +5431,11 @@ var AGENT_CATALOG = (() => {
5397
5431
 
5398
5432
  // src/coordination/dispatcher.ts
5399
5433
  var DEFAULT_DISPATCH_ROLE = "executor";
5434
+ var FALLBACK_DEFINITION = {
5435
+ config: { role: "unknown", name: "Unknown Agent" },
5436
+ budget: {},
5437
+ capability: { phase: "meta", summary: "", keywords: [] }
5438
+ };
5400
5439
  function normalize(text) {
5401
5440
  return ` ${text.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim()} `;
5402
5441
  }
@@ -5424,7 +5463,7 @@ function scoreAgents(task, catalog = AGENT_CATALOG) {
5424
5463
  }
5425
5464
  function heuristicConfidence(candidates) {
5426
5465
  if (candidates.length === 0) return 0;
5427
- const top = candidates[0].score;
5466
+ const top = candidates[0]?.score ?? 0;
5428
5467
  const second = candidates[1]?.score ?? 0;
5429
5468
  const strength = Math.min(1, top / 3);
5430
5469
  const margin = (top - second + 1) / (top + 1);
@@ -5440,7 +5479,7 @@ async function dispatchAgent(task, opts = {}) {
5440
5479
  if (top && confidence >= threshold) {
5441
5480
  return {
5442
5481
  role: top.role,
5443
- definition: catalog[top.role],
5482
+ definition: catalog[top.role] ?? FALLBACK_DEFINITION,
5444
5483
  confidence,
5445
5484
  method: "heuristic",
5446
5485
  reason: `Matched keywords: ${top.matched.slice(0, 4).join(", ")}`,
@@ -5448,7 +5487,7 @@ async function dispatchAgent(task, opts = {}) {
5448
5487
  };
5449
5488
  }
5450
5489
  if (opts.classifier) {
5451
- const pool = (candidates.length > 0 ? candidates.slice(0, maxCandidates).map((c) => catalog[c.role]) : ALL_AGENT_DEFINITIONS).map((d) => ({
5490
+ const pool = (candidates.length > 0 ? candidates.slice(0, maxCandidates).map((c) => catalog[c.role] ?? FALLBACK_DEFINITION) : ALL_AGENT_DEFINITIONS).map((d) => ({
5452
5491
  role: d.config.role,
5453
5492
  name: d.config.name,
5454
5493
  summary: d.capability.summary
@@ -5458,7 +5497,7 @@ async function dispatchAgent(task, opts = {}) {
5458
5497
  if (choice && catalog[choice.role]) {
5459
5498
  return {
5460
5499
  role: choice.role,
5461
- definition: catalog[choice.role],
5500
+ definition: catalog[choice.role] ?? FALLBACK_DEFINITION,
5462
5501
  confidence: 1,
5463
5502
  method: "llm",
5464
5503
  reason: choice.reason ?? "Selected by LLM classifier",
@@ -5471,17 +5510,17 @@ async function dispatchAgent(task, opts = {}) {
5471
5510
  if (top) {
5472
5511
  return {
5473
5512
  role: top.role,
5474
- definition: catalog[top.role],
5513
+ definition: catalog[top.role] ?? FALLBACK_DEFINITION,
5475
5514
  confidence,
5476
5515
  method: "heuristic",
5477
5516
  reason: `Weak match (${top.matched.slice(0, 3).join(", ") || "low signal"})`,
5478
5517
  alternatives: candidates.slice(1, maxCandidates)
5479
5518
  };
5480
5519
  }
5481
- const fallbackRole = catalog[DEFAULT_DISPATCH_ROLE] ? DEFAULT_DISPATCH_ROLE : Object.keys(catalog)[0];
5520
+ const fallbackRole = catalog[DEFAULT_DISPATCH_ROLE] ? DEFAULT_DISPATCH_ROLE : Object.keys(catalog)[0] ?? DEFAULT_DISPATCH_ROLE;
5482
5521
  return {
5483
5522
  role: fallbackRole,
5484
- definition: catalog[fallbackRole],
5523
+ definition: catalog[fallbackRole] ?? FALLBACK_DEFINITION,
5485
5524
  confidence: 0,
5486
5525
  method: "fallback",
5487
5526
  reason: "No keyword signal; defaulting to the generalist Executor",
@@ -6123,6 +6162,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6123
6162
  takeNextDispatchableTask() {
6124
6163
  for (let i = 0; i < this.pendingTasks.length; i++) {
6125
6164
  const task = this.pendingTasks[i];
6165
+ if (!task) continue;
6126
6166
  const subagentId = task.subagentId ? this.isIdleSubagent(task.subagentId) ? task.subagentId : null : this.findIdleSubagent();
6127
6167
  if (!subagentId) continue;
6128
6168
  this.pendingTasks.splice(i, 1);
@@ -6314,14 +6354,14 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6314
6354
  const idleExceeded = idleLimit !== void 0 && budget.idleMs() >= idleLimit;
6315
6355
  if (idleExceeded && !wallExceeded) {
6316
6356
  this.subagents.get(ctx.subagentId)?.abortController.abort();
6317
- reject(new BudgetExceededError("timeout", idleLimit, budget.idleMs()));
6357
+ reject(new BudgetExceededError("timeout", idleLimit ?? 0, budget.idleMs()));
6318
6358
  return;
6319
6359
  }
6320
6360
  if (!wallExceeded) {
6321
6361
  scheduleNext();
6322
6362
  return;
6323
6363
  }
6324
- const limit = wallLimit;
6364
+ const limit = wallLimit ?? 0;
6325
6365
  if (!budget.onThreshold) {
6326
6366
  this.subagents.get(ctx.subagentId)?.abortController.abort();
6327
6367
  reject(new BudgetExceededError("timeout", limit, elapsed));
@@ -6480,8 +6520,11 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6480
6520
  };
6481
6521
 
6482
6522
  // src/execution/parallel-eternal-engine.ts
6483
- function sleep2(ms) {
6484
- return new Promise((resolve2) => setTimeout(resolve2, ms));
6523
+ function expectDefined5(value) {
6524
+ if (value === null || value === void 0) {
6525
+ throw new Error("Expected value to be defined");
6526
+ }
6527
+ return value;
6485
6528
  }
6486
6529
  var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
6487
6530
  var ParallelEternalEngine = class {
@@ -6557,7 +6600,7 @@ var ParallelEternalEngine = class {
6557
6600
  );
6558
6601
  }
6559
6602
  if (this.stopRequested) break;
6560
- await sleep2(2e3);
6603
+ await sleep(2e3);
6561
6604
  }
6562
6605
  } finally {
6563
6606
  this.state = "stopped";
@@ -6638,7 +6681,7 @@ var ParallelEternalEngine = class {
6638
6681
  // Fan-out
6639
6682
  // -------------------------------------------------------------------------
6640
6683
  async fanOut(goal, tasks) {
6641
- const coordinator = this.coordinator;
6684
+ const coordinator = expectDefined5(this.coordinator);
6642
6685
  const slotCount = Math.min(this.slots, tasks.length);
6643
6686
  const routes = this.dispatchEnabled ? await Promise.all(
6644
6687
  tasks.slice(0, slotCount).map(
@@ -6670,7 +6713,7 @@ ${recentJournal}` : "No prior iterations.",
6670
6713
  const routeInfo = [];
6671
6714
  const spawnPromises = [];
6672
6715
  for (let i = 0; i < slotCount; i++) {
6673
- const task = tasks[i];
6716
+ const task = expectDefined5(tasks[i]);
6674
6717
  const route = routes[i] ?? null;
6675
6718
  const subagentId = `parallel-${this.iterations}-${i}`;
6676
6719
  const taskId = randomUUID();
@@ -7256,7 +7299,7 @@ function parseDescription(raw) {
7256
7299
  const scope = [];
7257
7300
  const coversMatch = /(?:covers|for|including)\s+([^.]+)/i.exec(desc);
7258
7301
  if (coversMatch) {
7259
- const items = coversMatch[1].replace(/[·•]/g, ",").split(",").map((s) => s.trim()).filter(Boolean);
7302
+ const items = coversMatch[1] ?? "".replace(/[·•]/g, ",").split(",").map((s) => s.trim()).filter(Boolean);
7260
7303
  scope.push(...items);
7261
7304
  }
7262
7305
  return { trigger, scope };