robrain 2.4.10 → 2.5.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.
Files changed (60) hide show
  1. package/dist/commands/capture.d.ts +96 -0
  2. package/dist/commands/capture.d.ts.map +1 -0
  3. package/dist/commands/capture.js +356 -0
  4. package/dist/commands/capture.js.map +1 -0
  5. package/dist/commands/capture.test.d.ts +2 -0
  6. package/dist/commands/capture.test.d.ts.map +1 -0
  7. package/dist/commands/capture.test.js +102 -0
  8. package/dist/commands/capture.test.js.map +1 -0
  9. package/dist/commands/check.js +2 -2
  10. package/dist/commands/check.js.map +1 -1
  11. package/dist/commands/explain.js +2 -2
  12. package/dist/commands/explain.js.map +1 -1
  13. package/dist/commands/export-memory.js +2 -2
  14. package/dist/commands/export-memory.js.map +1 -1
  15. package/dist/commands/init-project.js +4 -4
  16. package/dist/commands/init-project.js.map +1 -1
  17. package/dist/commands/inject.d.ts +10 -0
  18. package/dist/commands/inject.d.ts.map +1 -1
  19. package/dist/commands/inject.js +52 -6
  20. package/dist/commands/inject.js.map +1 -1
  21. package/dist/commands/inject.test.d.ts +2 -0
  22. package/dist/commands/inject.test.d.ts.map +1 -0
  23. package/dist/commands/inject.test.js +170 -0
  24. package/dist/commands/inject.test.js.map +1 -0
  25. package/dist/commands/install.js +5 -5
  26. package/dist/commands/install.js.map +1 -1
  27. package/dist/commands/outcomes.js +4 -4
  28. package/dist/commands/outcomes.js.map +1 -1
  29. package/dist/commands/projects.d.ts +5 -0
  30. package/dist/commands/projects.d.ts.map +1 -1
  31. package/dist/commands/projects.js +2 -2
  32. package/dist/commands/projects.js.map +1 -1
  33. package/dist/commands/review.js +7 -7
  34. package/dist/commands/review.js.map +1 -1
  35. package/dist/commands/status.d.ts.map +1 -1
  36. package/dist/commands/status.js +13 -3
  37. package/dist/commands/status.js.map +1 -1
  38. package/dist/index.js +41 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/config.d.ts +17 -0
  41. package/dist/lib/config.d.ts.map +1 -1
  42. package/dist/lib/config.js +45 -0
  43. package/dist/lib/config.js.map +1 -1
  44. package/dist/lib/config.test.d.ts +2 -0
  45. package/dist/lib/config.test.d.ts.map +1 -0
  46. package/dist/lib/config.test.js +75 -0
  47. package/dist/lib/config.test.js.map +1 -0
  48. package/dist/lib/spinner.d.ts +27 -0
  49. package/dist/lib/spinner.d.ts.map +1 -0
  50. package/dist/lib/spinner.js +41 -0
  51. package/dist/lib/spinner.js.map +1 -0
  52. package/dist/lib/spinner.test.d.ts +2 -0
  53. package/dist/lib/spinner.test.d.ts.map +1 -0
  54. package/dist/lib/spinner.test.js +39 -0
  55. package/dist/lib/spinner.test.js.map +1 -0
  56. package/package.json +2 -2
  57. package/vendor/sensing-mcp/dist/index.js +347 -84
  58. package/vendor/sensing-mcp/package.json +1 -1
  59. package/vendor/synthesis/dist/index.js +274 -7
  60. package/vendor/synthesis/package.json +1 -1
@@ -12454,16 +12454,179 @@ var require_trust = __commonJS({
12454
12454
  }
12455
12455
  });
12456
12456
 
12457
+ // ../shared/dist/capture-settings.js
12458
+ var require_capture_settings = __commonJS({
12459
+ "../shared/dist/capture-settings.js"(exports) {
12460
+ "use strict";
12461
+ Object.defineProperty(exports, "__esModule", { value: true });
12462
+ exports.DEFAULT_CAPTURE_SETTINGS = exports.DEFAULT_CAPTURE_KIND = exports.CAPTURE_MODES = exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS = exports.CAPTURE_KIND_NAME_MAX_CHARS = exports.CAPTURE_KINDS_MAX = exports.CAPTURE_INSTRUCTIONS_MAX_CHARS = void 0;
12463
+ exports.isDefaultCaptureSettings = isDefaultCaptureSettings;
12464
+ exports.normalizeKindName = normalizeKindName;
12465
+ exports.applyCaptureSettingsPatch = applyCaptureSettingsPatch;
12466
+ exports.coerceCaptureSettings = coerceCaptureSettings;
12467
+ exports.subjectTokens = subjectTokens;
12468
+ exports.subjectsMatch = subjectsMatch;
12469
+ exports.effectiveConfidenceMin = effectiveConfidenceMin;
12470
+ exports.allowedKindNames = allowedKindNames;
12471
+ exports.CAPTURE_INSTRUCTIONS_MAX_CHARS = 2e3;
12472
+ exports.CAPTURE_KINDS_MAX = 8;
12473
+ exports.CAPTURE_KIND_NAME_MAX_CHARS = 32;
12474
+ exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS = 300;
12475
+ exports.CAPTURE_MODES = ["strict", "broad"];
12476
+ exports.DEFAULT_CAPTURE_KIND = "decision";
12477
+ exports.DEFAULT_CAPTURE_SETTINGS = {
12478
+ instructions: null,
12479
+ mode: "strict",
12480
+ confidence_min: null,
12481
+ kinds: []
12482
+ };
12483
+ function isDefaultCaptureSettings(s2) {
12484
+ return s2.instructions === null && s2.mode === "strict" && s2.confidence_min === null && s2.kinds.length === 0;
12485
+ }
12486
+ function normalizeKindName(name) {
12487
+ return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
12488
+ }
12489
+ function applyCaptureSettingsPatch(current, patch) {
12490
+ const errors = [];
12491
+ const next = { ...current, kinds: [...current.kinds] };
12492
+ if (patch.instructions !== void 0) {
12493
+ if (patch.instructions === null || patch.instructions.trim() === "") {
12494
+ next.instructions = null;
12495
+ } else if (typeof patch.instructions !== "string") {
12496
+ errors.push("instructions must be text");
12497
+ } else if (patch.instructions.length > exports.CAPTURE_INSTRUCTIONS_MAX_CHARS) {
12498
+ errors.push(`instructions must be at most ${exports.CAPTURE_INSTRUCTIONS_MAX_CHARS} characters (got ${patch.instructions.length})`);
12499
+ } else {
12500
+ next.instructions = patch.instructions.trim();
12501
+ }
12502
+ }
12503
+ if (patch.mode !== void 0) {
12504
+ const mode = String(patch.mode).trim().toLowerCase();
12505
+ if (exports.CAPTURE_MODES.includes(mode)) {
12506
+ next.mode = mode;
12507
+ } else {
12508
+ errors.push(`mode must be one of: ${exports.CAPTURE_MODES.join(", ")}`);
12509
+ }
12510
+ }
12511
+ if (patch.confidence_min !== void 0) {
12512
+ if (patch.confidence_min === null) {
12513
+ next.confidence_min = null;
12514
+ } else if (typeof patch.confidence_min !== "number" || !Number.isFinite(patch.confidence_min)) {
12515
+ errors.push("confidence_min must be a number between 0 and 1");
12516
+ } else if (patch.confidence_min < 0 || patch.confidence_min > 1) {
12517
+ errors.push("confidence_min must be between 0 and 1");
12518
+ } else {
12519
+ next.confidence_min = Math.round(patch.confidence_min * 100) / 100;
12520
+ }
12521
+ }
12522
+ if (patch.kinds !== void 0) {
12523
+ if (patch.kinds === null) {
12524
+ next.kinds = [];
12525
+ } else if (!Array.isArray(patch.kinds)) {
12526
+ errors.push("kinds must be a list");
12527
+ } else if (patch.kinds.length > exports.CAPTURE_KINDS_MAX) {
12528
+ errors.push(`at most ${exports.CAPTURE_KINDS_MAX} kinds`);
12529
+ } else {
12530
+ const seen = /* @__PURE__ */ new Set();
12531
+ const kinds = [];
12532
+ for (const raw of patch.kinds) {
12533
+ const name = typeof raw?.name === "string" ? normalizeKindName(raw.name) : "";
12534
+ const description = typeof raw?.description === "string" ? raw.description.trim() : "";
12535
+ if (!name) {
12536
+ errors.push("each kind needs a name (letters, digits, - or _)");
12537
+ continue;
12538
+ }
12539
+ if (name.length > exports.CAPTURE_KIND_NAME_MAX_CHARS) {
12540
+ errors.push(`kind name "${name}" is longer than ${exports.CAPTURE_KIND_NAME_MAX_CHARS} characters`);
12541
+ continue;
12542
+ }
12543
+ if (name === exports.DEFAULT_CAPTURE_KIND) {
12544
+ errors.push(`"${exports.DEFAULT_CAPTURE_KIND}" is the built-in kind and cannot be redefined`);
12545
+ continue;
12546
+ }
12547
+ if (!description) {
12548
+ errors.push(`kind "${name}" needs a description so the model knows what to store`);
12549
+ continue;
12550
+ }
12551
+ if (description.length > exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS) {
12552
+ errors.push(`description for kind "${name}" is longer than ${exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS} characters`);
12553
+ continue;
12554
+ }
12555
+ if (seen.has(name)) {
12556
+ errors.push(`kind "${name}" is listed twice`);
12557
+ continue;
12558
+ }
12559
+ seen.add(name);
12560
+ kinds.push({ name, description });
12561
+ }
12562
+ next.kinds = kinds;
12563
+ }
12564
+ }
12565
+ return errors.length ? { ok: false, errors } : { ok: true, settings: next };
12566
+ }
12567
+ function coerceCaptureSettings(raw) {
12568
+ if (!raw || typeof raw !== "object")
12569
+ return { ...exports.DEFAULT_CAPTURE_SETTINGS };
12570
+ const r2 = raw;
12571
+ const result = applyCaptureSettingsPatch(exports.DEFAULT_CAPTURE_SETTINGS, {
12572
+ instructions: typeof r2.instructions === "string" ? r2.instructions : null,
12573
+ mode: typeof r2.mode === "string" ? r2.mode : "strict",
12574
+ confidence_min: typeof r2.confidence_min === "number" ? r2.confidence_min : null,
12575
+ kinds: Array.isArray(r2.kinds) ? r2.kinds : []
12576
+ });
12577
+ if (result.ok)
12578
+ return result.settings;
12579
+ const safe = { ...exports.DEFAULT_CAPTURE_SETTINGS };
12580
+ const instructions = applyCaptureSettingsPatch(safe, { instructions: typeof r2.instructions === "string" ? r2.instructions : null });
12581
+ if (instructions.ok)
12582
+ safe.instructions = instructions.settings.instructions;
12583
+ const mode = applyCaptureSettingsPatch(safe, { mode: typeof r2.mode === "string" ? r2.mode : "strict" });
12584
+ if (mode.ok)
12585
+ safe.mode = mode.settings.mode;
12586
+ const conf = applyCaptureSettingsPatch(safe, { confidence_min: typeof r2.confidence_min === "number" ? r2.confidence_min : null });
12587
+ if (conf.ok)
12588
+ safe.confidence_min = conf.settings.confidence_min;
12589
+ const kinds = applyCaptureSettingsPatch(safe, { kinds: Array.isArray(r2.kinds) ? r2.kinds : [] });
12590
+ if (kinds.ok)
12591
+ safe.kinds = kinds.settings.kinds;
12592
+ return safe;
12593
+ }
12594
+ var SUBJECT_STOPWORDS = /* @__PURE__ */ new Set(["the", "a", "an", "of", "for", "on", "in", "at", "to", "and", "this", "that", "our", "my", "its", "last", "latest", "current"]);
12595
+ function subjectTokens(subject) {
12596
+ return subject.toLowerCase().replace(/[^a-z0-9\s_-]+/g, " ").split(/[\s_-]+/).filter((t2) => t2.length > 1 && !SUBJECT_STOPWORDS.has(t2));
12597
+ }
12598
+ function subjectsMatch(a2, b2) {
12599
+ const ta = new Set(subjectTokens(a2));
12600
+ const tb = new Set(subjectTokens(b2));
12601
+ if (ta.size === 0 || tb.size === 0)
12602
+ return false;
12603
+ const [small, large] = ta.size <= tb.size ? [ta, tb] : [tb, ta];
12604
+ for (const t2 of small)
12605
+ if (!large.has(t2))
12606
+ return false;
12607
+ return true;
12608
+ }
12609
+ function effectiveConfidenceMin(settings, stock) {
12610
+ return settings?.confidence_min ?? stock;
12611
+ }
12612
+ function allowedKindNames(settings) {
12613
+ return [exports.DEFAULT_CAPTURE_KIND, ...(settings?.kinds ?? []).map((k2) => k2.name)];
12614
+ }
12615
+ }
12616
+ });
12617
+
12457
12618
  // ../shared/dist/extract-decision.js
12458
12619
  var require_extract_decision = __commonJS({
12459
12620
  "../shared/dist/extract-decision.js"(exports) {
12460
12621
  "use strict";
12461
12622
  Object.defineProperty(exports, "__esModule", { value: true });
12462
12623
  exports.LlmKeyMissingError = exports.SELF_HOSTED_USER_RULE_OVERRIDE = exports.DECISION_EXTRACTION_SYSTEM_PROMPT = void 0;
12624
+ exports.buildCaptureRules = buildCaptureRules;
12463
12625
  exports.stripMarkdownJsonFence = stripMarkdownJsonFence2;
12464
12626
  exports.parseExtractedDecision = parseExtractedDecision;
12465
12627
  exports.extractDecisionLlm = extractDecisionLlm;
12466
12628
  var llm_js_1 = require_llm();
12629
+ var capture_settings_js_1 = require_capture_settings();
12467
12630
  exports.DECISION_EXTRACTION_SYSTEM_PROMPT = `You extract technical decisions from software development conversations.
12468
12631
 
12469
12632
  A decision includes ANY of the following (not only formal deliberation):
@@ -12489,6 +12652,23 @@ Fields:
12489
12652
  Output ONLY valid JSON. If no decision: {"decision": null, "rationale": null, "rejected": [], "confidence": 0}.
12490
12653
  Never add explanation outside the JSON.
12491
12654
  Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"option": string, "reason": string}], "confidence": number}`;
12655
+ function buildCaptureRules(capture) {
12656
+ if (!capture)
12657
+ return "";
12658
+ const sections = [];
12659
+ if (capture.kinds.length > 0) {
12660
+ const kindLines = capture.kinds.map((k2) => `- "${k2.name}": ${k2.description}`).join("\n");
12661
+ sections.push(`Besides decisions, this project also stores these kinds of memory:
12662
+ ${kindLines}
12663
+ The rules above about what is NOT a decision apply only to kind "${capture_settings_js_1.DEFAULT_CAPTURE_KIND}". A turn that contains an entry of one of the listed kinds must be returned even though it contains no decision and nothing durable was committed: set "kind" to that kind's name, put the entry in "entry" as one short factual sentence (what happened, when, with what result), set "subject" to a short stable label for the thing it is about (max 6 words, the same words each time so a newer entry about the same subject replaces the older one), set "confidence" to how sure you are that the turn contains such an entry, and leave "decision" null. When the turn contains a decision, return it as usual with "kind": "${capture_settings_js_1.DEFAULT_CAPTURE_KIND}", "entry": null and "subject": null. Never invent a kind that is not listed.
12664
+ Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"option": string, "reason": string}], "confidence": number, "kind": string, "entry": string|null, "subject": string|null}`);
12665
+ }
12666
+ if (capture.instructions) {
12667
+ sections.push(`Project instructions for what to store (they refine the rules above; the output must stay valid JSON in the schema given):
12668
+ ${capture.instructions}`);
12669
+ }
12670
+ return sections.join("\n\n");
12671
+ }
12492
12672
  exports.SELF_HOSTED_USER_RULE_OVERRIDE = `User-stated rule wins:
12493
12673
  - A durable rule is a standing instruction for future work in this repo or team (e.g. "from now on", "always", "never", "we no longer"). An instruction scoped to the current task, file, or step (e.g. "don't use that file", "stop logging here", "don't add tests for this one") is not durable; apply the rules above to it.
12494
12674
  - If the user states a durable rule in this turn, extract that rule even when the assistant refuses it, cites an older rule, or says it will not follow the new one. In that case do not return null, and do not extract the older rule the assistant restates.`;
@@ -12503,24 +12683,28 @@ Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"optio
12503
12683
  function stripMarkdownJsonFence2(raw) {
12504
12684
  return raw.trim().replace(/^```[a-z]*\s*/i, "").replace(/\s*```\s*$/, "").trim();
12505
12685
  }
12506
- function parseExtractedDecision(rawText) {
12686
+ function parseExtractedDecision(rawText, allowedKinds = [capture_settings_js_1.DEFAULT_CAPTURE_KIND]) {
12507
12687
  const raw = JSON.parse(stripMarkdownJsonFence2(rawText));
12508
12688
  const rejected = Array.isArray(raw.rejected) ? raw.rejected.filter((x2) => x2 !== null && typeof x2 === "object" && typeof x2.option === "string" && typeof x2.reason === "string") : [];
12509
12689
  const confidence = typeof raw.confidence === "number" && Number.isFinite(raw.confidence) ? raw.confidence : 0;
12690
+ const requestedKind = typeof raw.kind === "string" ? (0, capture_settings_js_1.normalizeKindName)(raw.kind) : capture_settings_js_1.DEFAULT_CAPTURE_KIND;
12691
+ const kind2 = allowedKinds.includes(requestedKind) ? requestedKind : capture_settings_js_1.DEFAULT_CAPTURE_KIND;
12692
+ const subject = kind2 !== capture_settings_js_1.DEFAULT_CAPTURE_KIND && typeof raw.subject === "string" && raw.subject.trim() ? raw.subject.trim().slice(0, 120) : null;
12693
+ const entry = kind2 !== capture_settings_js_1.DEFAULT_CAPTURE_KIND && typeof raw.entry === "string" && raw.entry.trim() ? raw.entry.trim() : null;
12510
12694
  return {
12511
- decision: typeof raw.decision === "string" ? raw.decision : null,
12695
+ decision: entry ?? (typeof raw.decision === "string" ? raw.decision : null),
12512
12696
  rationale: typeof raw.rationale === "string" ? raw.rationale : null,
12513
12697
  rejected,
12514
- confidence
12698
+ confidence,
12699
+ kind: kind2,
12700
+ subject
12515
12701
  };
12516
12702
  }
12517
12703
  async function extractDecisionLlm(userMessage, claudeReply, cfg) {
12518
12704
  const userPrompt = `Session turn:
12519
12705
  User: ${userMessage}
12520
12706
  Claude: ${claudeReply}`;
12521
- const systemPrompt = cfg.extraSystemRules ? `${exports.DECISION_EXTRACTION_SYSTEM_PROMPT}
12522
-
12523
- ${cfg.extraSystemRules}` : exports.DECISION_EXTRACTION_SYSTEM_PROMPT;
12707
+ const systemPrompt = [exports.DECISION_EXTRACTION_SYSTEM_PROMPT, cfg.extraSystemRules, buildCaptureRules(cfg.capture)].filter((section) => Boolean(section)).join("\n\n");
12524
12708
  let rawText;
12525
12709
  if (cfg.provider === "openai") {
12526
12710
  const baseUrl = cfg.openaiBaseUrl ?? (0, llm_js_1.resolveOpenAiBaseUrl)();
@@ -12552,7 +12736,88 @@ ${cfg.extraSystemRules}` : exports.DECISION_EXTRACTION_SYSTEM_PROMPT;
12552
12736
  temperature: 0
12553
12737
  });
12554
12738
  }
12555
- return parseExtractedDecision(rawText);
12739
+ return parseExtractedDecision(rawText, (0, capture_settings_js_1.allowedKindNames)(cfg.capture));
12740
+ }
12741
+ }
12742
+ });
12743
+
12744
+ // ../shared/dist/capture-gate.js
12745
+ var require_capture_gate = __commonJS({
12746
+ "../shared/dist/capture-gate.js"(exports) {
12747
+ "use strict";
12748
+ Object.defineProperty(exports, "__esModule", { value: true });
12749
+ exports.BROAD_MODE_MIN_USER_CHARS = exports.DECISION_KEYWORDS = void 0;
12750
+ exports.captureGate = captureGate;
12751
+ exports.DECISION_KEYWORDS = [
12752
+ "decided",
12753
+ "decision",
12754
+ "going with",
12755
+ "we'll use",
12756
+ "let's use",
12757
+ "instead of",
12758
+ "switched to",
12759
+ "switching to",
12760
+ "rejected",
12761
+ "won't use",
12762
+ "we tried",
12763
+ "too slow",
12764
+ "doesn't work",
12765
+ "went with",
12766
+ "chosen",
12767
+ "settled on",
12768
+ "ruling out",
12769
+ "dropping",
12770
+ "replacing",
12771
+ // Casual commitments / conventions (often no spelled-out alternatives)
12772
+ "standardize",
12773
+ "standardise",
12774
+ "standardizing",
12775
+ "moving to ",
12776
+ "migrate to",
12777
+ "migrate from",
12778
+ "defaults to",
12779
+ "default to",
12780
+ "stick with",
12781
+ "locking in",
12782
+ "lock in"
12783
+ ];
12784
+ var AFFIRMATION_PATTERNS = [
12785
+ /\b(yes|yep|yeah|yup|sure)\b/i,
12786
+ /\b(agreed|agree|approved?)\b/i,
12787
+ /\blet['’]s\s+(do|go|use|try|ship|stick|adopt|switch|move|migrate)\b/i,
12788
+ /\b(go|going)\s+with\b/i,
12789
+ /\bsounds\s+good\b/i,
12790
+ /\bdo\s+it\b/i,
12791
+ /\bship\s+it\b/i
12792
+ ];
12793
+ var IMPLICIT_ACTION_PATTERNS = [
12794
+ /import .+ from ['"][^'"]+['"]/,
12795
+ /require\(['"][^'"]+['"]\)/,
12796
+ /npm install|pnpm add|yarn add/
12797
+ ];
12798
+ var IMPLICIT_USER_COMMITMENT_PATTERNS = [
12799
+ /\blet['’]s\s+(standardize|standardise|use|go with|stick with|adopt)\b/i,
12800
+ /\b(from now on|going forward)\b/i,
12801
+ /\b(always|never)\s+(use|write|add|call|prefer|put|name|run|import|suggest|commit|push|merge|install|mock)\b/i,
12802
+ /\b(don['’]t|do not|stop|no longer)\s+(use|using|write|writing|add|adding|call|calling|suggest|suggesting|import|importing)\b/i
12803
+ ];
12804
+ exports.BROAD_MODE_MIN_USER_CHARS = 24;
12805
+ function captureGate(turn, settings) {
12806
+ const userText = turn.user_message.toLowerCase();
12807
+ const assistantText = turn.claude_reply.toLowerCase();
12808
+ const userAffirmed = AFFIRMATION_PATTERNS.some((p2) => p2.test(turn.user_message));
12809
+ const keywordInUser = exports.DECISION_KEYWORDS.some((kw) => userText.includes(kw));
12810
+ const keywordInAssistant = !keywordInUser && exports.DECISION_KEYWORDS.some((kw) => assistantText.includes(kw));
12811
+ if (keywordInUser || keywordInAssistant && userAffirmed) {
12812
+ return { reachesModel: true, reason: "keyword" };
12813
+ }
12814
+ const implicitHit = IMPLICIT_ACTION_PATTERNS.some((p2) => p2.test(`${turn.user_message} ${turn.claude_reply}`)) || IMPLICIT_USER_COMMITMENT_PATTERNS.some((p2) => p2.test(turn.user_message));
12815
+ if (implicitHit)
12816
+ return { reachesModel: true, reason: "implicit" };
12817
+ if (settings?.mode === "broad" && turn.user_message.trim().length >= exports.BROAD_MODE_MIN_USER_CHARS) {
12818
+ return { reachesModel: true, reason: "broad" };
12819
+ }
12820
+ return { reachesModel: false, reason: "none" };
12556
12821
  }
12557
12822
  }
12558
12823
  });
@@ -12600,6 +12865,8 @@ var require_dist2 = __commonJS({
12600
12865
  __exportStar(require_veto_match(), exports);
12601
12866
  __exportStar(require_trust(), exports);
12602
12867
  __exportStar(require_extract_decision(), exports);
12868
+ __exportStar(require_capture_settings(), exports);
12869
+ __exportStar(require_capture_gate(), exports);
12603
12870
  __exportStar(require_db(), exports);
12604
12871
  }
12605
12872
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robrain/synthesis",
3
- "version": "2.4.10",
3
+ "version": "2.5.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js"