@graphrefly/graphrefly 0.13.0 → 0.14.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 (42) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-HA6QMDKQ.js → chunk-2ZICUAUJ.js} +4 -4
  3. package/dist/{chunk-H4UFM6WD.js → chunk-4APC3AFN.js} +3 -3
  4. package/dist/{chunk-UQI4GAHD.js → chunk-CRACCCJY.js} +3 -3
  5. package/dist/{chunk-UPC5OEB5.js → chunk-GKRKDYNT.js} +3 -3
  6. package/dist/{chunk-6B2ZCCNN.js → chunk-H243FWYP.js} +12 -13
  7. package/dist/chunk-H243FWYP.js.map +1 -0
  8. package/dist/{chunk-KNGOJEYP.js → chunk-QVYZD65U.js} +2 -2
  9. package/dist/{chunk-PFMXKG4Y.js → chunk-XQ4UMAU7.js} +2 -2
  10. package/dist/{chunk-5RN7NBNG.js → chunk-YW6LFCFS.js} +3 -3
  11. package/dist/{chunk-QOGWU5K7.js → chunk-ZHTHUX5D.js} +3 -3
  12. package/dist/compat/nestjs/index.cjs +11 -12
  13. package/dist/compat/nestjs/index.cjs.map +1 -1
  14. package/dist/compat/nestjs/index.js +7 -7
  15. package/dist/core/index.cjs +11 -12
  16. package/dist/core/index.cjs.map +1 -1
  17. package/dist/core/index.js +3 -3
  18. package/dist/extra/index.cjs +11 -12
  19. package/dist/extra/index.cjs.map +1 -1
  20. package/dist/extra/index.js +3 -3
  21. package/dist/graph/index.cjs +3 -0
  22. package/dist/graph/index.cjs.map +1 -1
  23. package/dist/graph/index.js +4 -4
  24. package/dist/index.cjs +390 -15
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +359 -56
  27. package/dist/index.d.ts +359 -56
  28. package/dist/index.js +395 -20
  29. package/dist/index.js.map +1 -1
  30. package/dist/patterns/reactive-layout/index.cjs +3 -0
  31. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  32. package/dist/patterns/reactive-layout/index.js +4 -4
  33. package/package.json +3 -1
  34. package/dist/chunk-6B2ZCCNN.js.map +0 -1
  35. /package/dist/{chunk-HA6QMDKQ.js.map → chunk-2ZICUAUJ.js.map} +0 -0
  36. /package/dist/{chunk-H4UFM6WD.js.map → chunk-4APC3AFN.js.map} +0 -0
  37. /package/dist/{chunk-UQI4GAHD.js.map → chunk-CRACCCJY.js.map} +0 -0
  38. /package/dist/{chunk-UPC5OEB5.js.map → chunk-GKRKDYNT.js.map} +0 -0
  39. /package/dist/{chunk-KNGOJEYP.js.map → chunk-QVYZD65U.js.map} +0 -0
  40. /package/dist/{chunk-PFMXKG4Y.js.map → chunk-XQ4UMAU7.js.map} +0 -0
  41. /package/dist/{chunk-5RN7NBNG.js.map → chunk-YW6LFCFS.js.map} +0 -0
  42. /package/dist/{chunk-QOGWU5K7.js.map → chunk-ZHTHUX5D.js.map} +0 -0
@@ -4,14 +4,14 @@ import {
4
4
  createDagCborZstdCodec,
5
5
  negotiateCodec,
6
6
  replayWAL
7
- } from "../chunk-QOGWU5K7.js";
7
+ } from "../chunk-ZHTHUX5D.js";
8
8
  import {
9
9
  GRAPH_META_SEGMENT,
10
10
  Graph,
11
11
  reachable
12
- } from "../chunk-UQI4GAHD.js";
13
- import "../chunk-PFMXKG4Y.js";
14
- import "../chunk-6B2ZCCNN.js";
12
+ } from "../chunk-CRACCCJY.js";
13
+ import "../chunk-XQ4UMAU7.js";
14
+ import "../chunk-H243FWYP.js";
15
15
  export {
16
16
  GRAPH_META_SEGMENT,
17
17
  Graph,
package/dist/index.cjs CHANGED
@@ -185,6 +185,7 @@ __export(index_exports, {
185
185
  globToRegExp: () => globToRegExp,
186
186
  graph: () => graph_exports,
187
187
  graphspec: () => graphspec_exports,
188
+ harness: () => harness_exports,
188
189
  interval: () => interval,
189
190
  isBatching: () => isBatching,
190
191
  isKnownMessageType: () => isKnownMessageType,
@@ -427,8 +428,7 @@ function drainPending() {
427
428
  if (ownsFlush) {
428
429
  flushInProgress = true;
429
430
  }
430
- let firstError;
431
- let hasError = false;
431
+ const errors = [];
432
432
  try {
433
433
  let iterations = 0;
434
434
  while (pendingPhase2.length > 0 || pendingPhase3.length > 0) {
@@ -446,10 +446,7 @@ function drainPending() {
446
446
  try {
447
447
  run();
448
448
  } catch (e) {
449
- if (!hasError) {
450
- firstError = e;
451
- hasError = true;
452
- }
449
+ errors.push(e);
453
450
  }
454
451
  }
455
452
  }
@@ -467,10 +464,7 @@ function drainPending() {
467
464
  try {
468
465
  run();
469
466
  } catch (e) {
470
- if (!hasError) {
471
- firstError = e;
472
- hasError = true;
473
- }
467
+ errors.push(e);
474
468
  }
475
469
  }
476
470
  }
@@ -480,8 +474,11 @@ function drainPending() {
480
474
  flushInProgress = false;
481
475
  }
482
476
  }
483
- if (hasError) {
484
- throw firstError;
477
+ if (errors.length === 1) {
478
+ throw errors[0];
479
+ }
480
+ if (errors.length > 1) {
481
+ throw new AggregateError(errors, "batch drain: multiple callbacks threw");
485
482
  }
486
483
  }
487
484
  function partitionForBatch(messages) {
@@ -1122,6 +1119,9 @@ var NodeImpl = class {
1122
1119
  for (const m of messages) {
1123
1120
  const t = m[0];
1124
1121
  if (t === DATA) {
1122
+ if (m.length < 2) {
1123
+ continue;
1124
+ }
1125
1125
  this._cached = m[1];
1126
1126
  if (this._versioning != null) {
1127
1127
  advanceVersion(this._versioning, m[1], this._hashFn);
@@ -4645,7 +4645,7 @@ var Graph = class _Graph {
4645
4645
  _createObserveResult(path, target, options) {
4646
4646
  const timeline = options.timeline === true;
4647
4647
  const causal = options.causal === true;
4648
- const derived2 = options.derived === true;
4648
+ const derived3 = options.derived === true;
4649
4649
  const minimal = options.detail === "minimal";
4650
4650
  const result = {
4651
4651
  values: {},
@@ -4658,14 +4658,14 @@ var Graph = class _Graph {
4658
4658
  let lastTriggerDepIndex;
4659
4659
  let lastRunDepValues;
4660
4660
  let detachInspectorHook;
4661
- if ((causal || derived2) && target instanceof NodeImpl) {
4661
+ if ((causal || derived3) && target instanceof NodeImpl) {
4662
4662
  detachInspectorHook = target._setInspectorHook((event) => {
4663
4663
  if (event.kind === "dep_message") {
4664
4664
  lastTriggerDepIndex = event.depIndex;
4665
4665
  return;
4666
4666
  }
4667
4667
  lastRunDepValues = [...event.depValues];
4668
- if (derived2) {
4668
+ if (derived3) {
4669
4669
  result.events.push({
4670
4670
  type: "derived",
4671
4671
  path,
@@ -12967,6 +12967,7 @@ __export(patterns_exports, {
12967
12967
  demoShell: () => demo_shell_exports,
12968
12968
  domainTemplates: () => domain_templates_exports,
12969
12969
  graphspec: () => graphspec_exports,
12970
+ harness: () => harness_exports,
12970
12971
  layout: () => reactive_layout_exports,
12971
12972
  memory: () => memory_exports,
12972
12973
  messaging: () => messaging_exports,
@@ -17383,6 +17384,59 @@ ${validation.errors.join("\n")}`);
17383
17384
  return parsed;
17384
17385
  }
17385
17386
 
17387
+ // src/patterns/harness/index.ts
17388
+ var harness_exports = {};
17389
+ __export(harness_exports, {
17390
+ DEFAULT_DECAY_RATE: () => DEFAULT_DECAY_RATE2,
17391
+ DEFAULT_QUEUE_CONFIGS: () => DEFAULT_QUEUE_CONFIGS,
17392
+ DEFAULT_SEVERITY_WEIGHTS: () => DEFAULT_SEVERITY_WEIGHTS,
17393
+ HarnessGraph: () => HarnessGraph,
17394
+ defaultErrorClassifier: () => defaultErrorClassifier,
17395
+ evalIntakeBridge: () => evalIntakeBridge,
17396
+ harnessLoop: () => harnessLoop,
17397
+ priorityScore: () => priorityScore,
17398
+ strategyKey: () => strategyKey,
17399
+ strategyModel: () => strategyModel
17400
+ });
17401
+
17402
+ // src/patterns/harness/bridge.ts
17403
+ function evalIntakeBridge(evalSource, intakeTopic, opts) {
17404
+ const defaultSeverity = opts?.defaultSeverity ?? "medium";
17405
+ return effect([evalSource], ([results]) => {
17406
+ if (results == null) return;
17407
+ const runs = Array.isArray(results) ? results : [results];
17408
+ for (const run of runs) {
17409
+ for (const task2 of run.tasks) {
17410
+ if (task2.valid && task2.judge_scores?.every((s) => s.pass)) continue;
17411
+ if (!task2.valid && (!task2.judge_scores || task2.judge_scores.length === 0)) {
17412
+ intakeTopic.publish({
17413
+ source: "eval",
17414
+ summary: `Task ${task2.task_id} invalid (model: ${run.model})`,
17415
+ evidence: `Run ${run.run_id}: task produced invalid output`,
17416
+ affectsAreas: ["graphspec"],
17417
+ affectsEvalTasks: [task2.task_id],
17418
+ severity: defaultSeverity
17419
+ });
17420
+ continue;
17421
+ }
17422
+ if (task2.judge_scores) {
17423
+ for (const score of task2.judge_scores) {
17424
+ if (score.pass) continue;
17425
+ intakeTopic.publish({
17426
+ source: "eval",
17427
+ summary: `${task2.task_id}: ${score.claim} (model: ${run.model})`,
17428
+ evidence: score.reasoning,
17429
+ affectsAreas: ["graphspec"],
17430
+ affectsEvalTasks: [task2.task_id],
17431
+ severity: defaultSeverity
17432
+ });
17433
+ }
17434
+ }
17435
+ }
17436
+ }
17437
+ });
17438
+ }
17439
+
17386
17440
  // src/patterns/messaging.ts
17387
17441
  var messaging_exports = {};
17388
17442
  __export(messaging_exports, {
@@ -18276,6 +18330,326 @@ function onFailure(graph, name, source, recover, opts) {
18276
18330
  return step;
18277
18331
  }
18278
18332
 
18333
+ // src/patterns/harness/types.ts
18334
+ function strategyKey(rootCause, intervention) {
18335
+ return `${rootCause}\u2192${intervention}`;
18336
+ }
18337
+ function defaultErrorClassifier(result) {
18338
+ const d = result.detail.toLowerCase();
18339
+ if (d.includes("parse") || d.includes("json") || d.includes("config") || d.includes("validation") || d.includes("syntax")) {
18340
+ return "self-correctable";
18341
+ }
18342
+ return "structural";
18343
+ }
18344
+ var DEFAULT_SEVERITY_WEIGHTS = {
18345
+ critical: 100,
18346
+ high: 70,
18347
+ medium: 40,
18348
+ low: 10
18349
+ };
18350
+ var DEFAULT_DECAY_RATE2 = Math.LN2 / (7 * 24 * 3600);
18351
+ var DEFAULT_QUEUE_CONFIGS = {
18352
+ "auto-fix": { gated: false },
18353
+ "needs-decision": { gated: true },
18354
+ investigation: { gated: true },
18355
+ backlog: { gated: false, startOpen: false }
18356
+ };
18357
+
18358
+ // src/patterns/harness/strategy.ts
18359
+ function strategyModel() {
18360
+ const _map = reactiveMap({ name: "strategy-entries" });
18361
+ const snapshot = derived(
18362
+ [_map.node],
18363
+ ([mapSnap]) => {
18364
+ const raw = mapSnap.value.map;
18365
+ return new Map(raw);
18366
+ },
18367
+ {
18368
+ name: "strategy-model",
18369
+ equals: (a, b) => {
18370
+ const am = a;
18371
+ const bm = b;
18372
+ if (am.size !== bm.size) return false;
18373
+ for (const [k, v] of am) {
18374
+ const bv = bm.get(k);
18375
+ if (!bv || v.attempts !== bv.attempts || v.successes !== bv.successes) return false;
18376
+ }
18377
+ return true;
18378
+ }
18379
+ }
18380
+ );
18381
+ function record(rootCause, intervention, success) {
18382
+ const key = strategyKey(rootCause, intervention);
18383
+ const existing = _map.get(key);
18384
+ const attempts = (existing?.attempts ?? 0) + 1;
18385
+ const successes = (existing?.successes ?? 0) + (success ? 1 : 0);
18386
+ _map.set(key, {
18387
+ rootCause,
18388
+ intervention,
18389
+ attempts,
18390
+ successes,
18391
+ successRate: successes / attempts
18392
+ });
18393
+ }
18394
+ function lookup(rootCause, intervention) {
18395
+ return _map.get(strategyKey(rootCause, intervention));
18396
+ }
18397
+ const _unsub = snapshot.subscribe(() => {
18398
+ });
18399
+ return { node: snapshot, record, lookup };
18400
+ }
18401
+ function priorityScore(item, strategy, lastInteractionNs, urgency, signals) {
18402
+ const severityWeights = { ...DEFAULT_SEVERITY_WEIGHTS, ...signals?.severityWeights };
18403
+ const decayRate = signals?.decayRate ?? DEFAULT_DECAY_RATE2;
18404
+ const effectivenessThreshold = signals?.effectivenessThreshold ?? 0.7;
18405
+ const effectivenessBoost = signals?.effectivenessBoost ?? 15;
18406
+ const deps = [item, strategy, lastInteractionNs];
18407
+ if (urgency) deps.push(urgency);
18408
+ return derived(
18409
+ deps,
18410
+ (values) => {
18411
+ const itm = values[0];
18412
+ const strat = values[1];
18413
+ const lastNs = values[2];
18414
+ const urg = urgency ? values[3] : 0;
18415
+ const baseWeight = severityWeights[itm.severity ?? "medium"];
18416
+ const ageSeconds = (monotonicNs() - lastNs) / 1e9;
18417
+ let score = decay(baseWeight, ageSeconds, decayRate, 0);
18418
+ const key = strategyKey(itm.rootCause, itm.intervention);
18419
+ const entry = strat.get(key);
18420
+ if (entry && entry.successRate >= effectivenessThreshold) {
18421
+ score += effectivenessBoost;
18422
+ }
18423
+ score += urg * 20;
18424
+ return score;
18425
+ },
18426
+ { name: "priority-score" }
18427
+ );
18428
+ }
18429
+
18430
+ // src/patterns/harness/loop.ts
18431
+ var DEFAULT_TRIAGE_PROMPT = `You are a triage classifier for a reactive collaboration harness.
18432
+
18433
+ Given an intake item, classify it and output JSON:
18434
+ {
18435
+ "rootCause": "composition" | "missing-fn" | "bad-docs" | "schema-gap" | "regression" | "unknown",
18436
+ "intervention": "template" | "catalog-fn" | "docs" | "wrapper" | "schema-change" | "investigate",
18437
+ "route": "auto-fix" | "needs-decision" | "investigation" | "backlog",
18438
+ "priority": <number 0-100>,
18439
+ "triageReasoning": "<one sentence>"
18440
+ }
18441
+
18442
+ Strategy model (past effectiveness):
18443
+ {{strategy}}
18444
+
18445
+ Intake item:
18446
+ {{item}}`;
18447
+ var DEFAULT_EXECUTE_PROMPT = `You are an implementation agent.
18448
+
18449
+ Given a triaged issue with root cause and intervention type, produce a fix.
18450
+
18451
+ Issue:
18452
+ {{item}}
18453
+
18454
+ Output JSON:
18455
+ {
18456
+ "outcome": "success" | "failure" | "partial",
18457
+ "detail": "<description of what was done or what failed>"
18458
+ }`;
18459
+ var DEFAULT_VERIFY_PROMPT = `You are a QA reviewer.
18460
+
18461
+ Given an execution result, verify whether the fix is correct.
18462
+
18463
+ Execution:
18464
+ {{execution}}
18465
+
18466
+ Original issue:
18467
+ {{item}}
18468
+
18469
+ Output JSON:
18470
+ {
18471
+ "verified": true/false,
18472
+ "findings": ["<finding1>", ...],
18473
+ "errorClass": "self-correctable" | "structural" // only if verified=false
18474
+ }`;
18475
+ var QUEUE_NAMES = [
18476
+ "auto-fix",
18477
+ "needs-decision",
18478
+ "investigation",
18479
+ "backlog"
18480
+ ];
18481
+ var HarnessGraph = class extends Graph {
18482
+ /** Intake topic — publish items here to enter the loop. */
18483
+ intake;
18484
+ /** Per-route queue topics. */
18485
+ queues;
18486
+ /** Per-route gate controllers (only for gated queues). */
18487
+ gates;
18488
+ /** Strategy model bundle — record outcomes, lookup effectiveness. */
18489
+ strategy;
18490
+ /** Verify results topic — subscribe to see verification outcomes. */
18491
+ verifyResults;
18492
+ constructor(name, intake, queues, gates, strategy, verifyResults) {
18493
+ super(name);
18494
+ this.intake = intake;
18495
+ this.queues = queues;
18496
+ this.gates = gates;
18497
+ this.strategy = strategy;
18498
+ this.verifyResults = verifyResults;
18499
+ }
18500
+ };
18501
+ function harnessLoop(name, opts) {
18502
+ const adapter = opts.adapter;
18503
+ const maxRetries = opts.maxRetries ?? 2;
18504
+ const retainedLimit = opts.retainedLimit ?? 1e3;
18505
+ const errorClassifier = opts.errorClassifier ?? defaultErrorClassifier;
18506
+ const queueConfigs = /* @__PURE__ */ new Map();
18507
+ for (const route of QUEUE_NAMES) {
18508
+ queueConfigs.set(route, {
18509
+ ...DEFAULT_QUEUE_CONFIGS[route],
18510
+ ...opts.queues?.[route]
18511
+ });
18512
+ }
18513
+ const intake = new TopicGraph("intake", { retainedLimit });
18514
+ const strategy = strategyModel();
18515
+ const triageNode = promptNode(
18516
+ adapter,
18517
+ [intake.latest, strategy.node],
18518
+ opts.triagePrompt ?? ((item, strat) => {
18519
+ return DEFAULT_TRIAGE_PROMPT.replace("{{strategy}}", JSON.stringify(strat)).replace(
18520
+ "{{item}}",
18521
+ JSON.stringify(item)
18522
+ );
18523
+ }),
18524
+ {
18525
+ name: "triage",
18526
+ format: "json",
18527
+ retries: 1
18528
+ }
18529
+ );
18530
+ const queueTopics = /* @__PURE__ */ new Map();
18531
+ for (const route of QUEUE_NAMES) {
18532
+ queueTopics.set(route, new TopicGraph(`queue/${route}`, { retainedLimit }));
18533
+ }
18534
+ const _router = effect([triageNode], ([triaged]) => {
18535
+ const item = triaged;
18536
+ if (!item || !item.route) return;
18537
+ const topic2 = queueTopics.get(item.route);
18538
+ if (topic2) topic2.publish(item);
18539
+ });
18540
+ const gateGraph = new Graph("gates");
18541
+ const gateControllers = /* @__PURE__ */ new Map();
18542
+ for (const route of QUEUE_NAMES) {
18543
+ const config = queueConfigs.get(route);
18544
+ const topic2 = queueTopics.get(route);
18545
+ if (config.gated) {
18546
+ gateGraph.add(`${route}/source`, topic2.latest);
18547
+ const ctrl = gate(gateGraph, `${route}/gate`, `${route}/source`, {
18548
+ maxPending: config.maxPending,
18549
+ startOpen: config.startOpen
18550
+ });
18551
+ gateControllers.set(route, ctrl);
18552
+ }
18553
+ }
18554
+ const retryTopic = new TopicGraph("retry-input", { retainedLimit });
18555
+ const queueOutputs = [];
18556
+ for (const route of QUEUE_NAMES) {
18557
+ const config = queueConfigs.get(route);
18558
+ if (config.gated && gateControllers.has(route)) {
18559
+ queueOutputs.push(gateControllers.get(route).node);
18560
+ } else {
18561
+ queueOutputs.push(queueTopics.get(route).latest);
18562
+ }
18563
+ }
18564
+ queueOutputs.push(retryTopic.latest);
18565
+ const executeInput = merge(...queueOutputs);
18566
+ const executeNode = promptNode(
18567
+ adapter,
18568
+ [executeInput],
18569
+ opts.executePrompt ?? ((item) => {
18570
+ return DEFAULT_EXECUTE_PROMPT.replace("{{item}}", JSON.stringify(item));
18571
+ }),
18572
+ {
18573
+ name: "execute",
18574
+ format: "json",
18575
+ retries: 1
18576
+ }
18577
+ );
18578
+ const verifyResults = new TopicGraph("verify-results", { retainedLimit });
18579
+ const verifyNode = promptNode(
18580
+ adapter,
18581
+ [executeNode, executeInput],
18582
+ opts.verifyPrompt ?? ((execution, item) => {
18583
+ return DEFAULT_VERIFY_PROMPT.replace("{{execution}}", JSON.stringify(execution)).replace(
18584
+ "{{item}}",
18585
+ JSON.stringify(item)
18586
+ );
18587
+ }),
18588
+ {
18589
+ name: "verify",
18590
+ format: "json",
18591
+ retries: 1
18592
+ }
18593
+ );
18594
+ const maxReingestions = opts.maxReingestions ?? 1;
18595
+ let reingestionCount = 0;
18596
+ const _fastRetry = effect([verifyNode], ([result]) => {
18597
+ const vr = result;
18598
+ if (!vr) return;
18599
+ if (vr.verified) {
18600
+ strategy.record(vr.item.rootCause, vr.item.intervention, true);
18601
+ verifyResults.publish(vr);
18602
+ return;
18603
+ }
18604
+ const errClass = vr.errorClass ?? errorClassifier({
18605
+ item: vr.item,
18606
+ outcome: "failure",
18607
+ detail: vr.findings.join("; "),
18608
+ retryCount: 0
18609
+ });
18610
+ const exec = vr.execution;
18611
+ const retryCount = exec?.retryCount ?? 0;
18612
+ if (errClass === "self-correctable" && retryCount < maxRetries) {
18613
+ const retryItem = {
18614
+ ...vr.item,
18615
+ summary: `[RETRY ${retryCount + 1}/${maxRetries}] ${vr.item.summary} \u2014 Previous attempt failed: ${vr.findings.join("; ")}`
18616
+ };
18617
+ retryTopic.publish(retryItem);
18618
+ } else {
18619
+ strategy.record(vr.item.rootCause, vr.item.intervention, false);
18620
+ verifyResults.publish(vr);
18621
+ if (reingestionCount < maxReingestions) {
18622
+ reingestionCount++;
18623
+ intake.publish({
18624
+ source: "eval",
18625
+ summary: `Verification failed for: ${vr.item.summary}`,
18626
+ evidence: vr.findings.join("\n"),
18627
+ affectsAreas: vr.item.affectsAreas,
18628
+ affectsEvalTasks: vr.item.affectsEvalTasks,
18629
+ severity: "high",
18630
+ relatedTo: [vr.item.summary]
18631
+ });
18632
+ }
18633
+ }
18634
+ });
18635
+ const harness = new HarnessGraph(
18636
+ name,
18637
+ intake,
18638
+ queueTopics,
18639
+ gateControllers,
18640
+ strategy,
18641
+ verifyResults
18642
+ );
18643
+ harness.mount("intake", intake);
18644
+ for (const [route, topic2] of queueTopics) {
18645
+ harness.mount(`queue/${route}`, topic2);
18646
+ }
18647
+ harness.mount("gates", gateGraph);
18648
+ harness.mount("retry-input", retryTopic);
18649
+ harness.mount("verify-results", verifyResults);
18650
+ return harness;
18651
+ }
18652
+
18279
18653
  // src/patterns/reactive-layout/index.ts
18280
18654
  var reactive_layout_exports = {};
18281
18655
  __export(reactive_layout_exports, {
@@ -18890,6 +19264,7 @@ var version = "0.0.0";
18890
19264
  globToRegExp,
18891
19265
  graph,
18892
19266
  graphspec,
19267
+ harness,
18893
19268
  interval,
18894
19269
  isBatching,
18895
19270
  isKnownMessageType,