@fdcn/sourcefed 0.3.6 → 0.3.8

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 (52) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-X3BZSHKZ.js → chunk-5JL3UV72.js} +1328 -399
  3. package/dist/cli.js +9888 -8063
  4. package/dist/daemon.js +1194 -263
  5. package/dist/data/core/SKILL.md +9 -4
  6. package/dist/data/core/references/commands.md +6 -1
  7. package/dist/data/sourcefed/SKILL.md +3 -2
  8. package/dist/guidance.md +6 -2
  9. package/dist/mcp.js +6 -2
  10. package/dist/opencode.js +263 -122
  11. package/dist/pi.js +161 -39
  12. package/dist/tui-compiled.mjs +306 -166
  13. package/dist.dts/adapters/opencode/bridge.d.ts +66 -22
  14. package/dist.dts/adapters/opencode/subscriptions.d.ts +46 -0
  15. package/dist.dts/adapters/opencode/tool-result.d.ts +2 -1
  16. package/dist.dts/adapters/opencode/tools/monitor_create.d.ts +19 -2
  17. package/dist.dts/adapters/opencode/tools/monitor_list.d.ts +3 -2
  18. package/dist.dts/adapters/opencode/tools/monitor_start.d.ts +3 -2
  19. package/dist.dts/adapters/opencode/tools/monitor_status.d.ts +3 -2
  20. package/dist.dts/adapters/opencode/tools/monitor_stop.d.ts +3 -2
  21. package/dist.dts/adapters/pi/src/dialog.d.ts +1 -2
  22. package/dist.dts/adapters/pi/src/monitors-dialog.d.ts +32 -0
  23. package/dist.dts/packages/core/src/types/monitor-create-input.d.ts +4 -0
  24. package/dist.dts/packages/daemon/src/event-stream.d.ts +26 -0
  25. package/dist.dts/packages/daemon/src/registry.d.ts +2 -0
  26. package/dist.dts/packages/daemon/src/stream-lifecycle.test.d.ts +1 -0
  27. package/dist.dts/packages/daemon/src/types/client.d.ts +3 -1
  28. package/dist.dts/packages/daemon/src/types/daemon.d.ts +4 -0
  29. package/dist.dts/packages/daemon/src/utils/index.d.ts +0 -1
  30. package/dist.dts/providers/yab/src/index.d.ts +2 -0
  31. package/dist.dts/providers/yab/src/monitor.d.ts +14 -0
  32. package/dist.dts/providers/yab/src/poll/index.d.ts +2 -0
  33. package/dist.dts/providers/yab/src/poll/monitor.d.ts +3 -0
  34. package/dist.dts/providers/yab/src/poll/utils/feed-events.d.ts +5 -0
  35. package/dist.dts/providers/yab/src/poll/utils/index.d.ts +4 -0
  36. package/dist.dts/providers/yab/src/poll/utils/parse-feed.d.ts +3 -0
  37. package/dist.dts/providers/yab/src/poll/utils/poll-yab.d.ts +7 -0
  38. package/dist.dts/providers/yab/src/poll/utils/yab-mcp.d.ts +10 -0
  39. package/dist.dts/providers/yab/src/schema.d.ts +12 -0
  40. package/dist.dts/providers/yab/src/types/cursor.d.ts +4 -0
  41. package/dist.dts/providers/yab/src/types/event.d.ts +8 -0
  42. package/dist.dts/providers/yab/src/types/feed-entry.d.ts +8 -0
  43. package/dist.dts/providers/yab/src/types/index.d.ts +5 -0
  44. package/dist.dts/providers/yab/src/types/page.d.ts +6 -0
  45. package/dist.dts/providers/yab/src/types/source-record.d.ts +7 -0
  46. package/dist.dts/providers/yab/src/yab.test.d.ts +1 -0
  47. package/package.json +1 -1
  48. package/dist.dts/packages/daemon/src/utils/forward.d.ts +0 -32
  49. package/dist.dts/packages/daemon/src/utils/gate.d.ts +0 -33
  50. package/dist.dts/packages/daemon/src/utils/request-router.d.ts +0 -11
  51. /package/dist.dts/{packages/daemon/src/forward.test.d.ts → adapters/opencode/lifecycle.test.d.ts} +0 -0
  52. /package/dist.dts/{packages/daemon/src/gate.test.d.ts → adapters/pi/src/monitors-dialog.test.d.ts} +0 -0
@@ -15,12 +15,16 @@ import os4 from "node:os";
15
15
  import path4 from "node:path";
16
16
  import { createHmac as createHmac2 } from "node:crypto";
17
17
  import { timingSafeEqual as timingSafeEqual2 } from "node:crypto";
18
+ import { link as link5, mkdir as mkdir5, open as open5, readFile as readFile5, rename as rename5, rm as rm5, writeFile as writeFile5 } from "node:fs/promises";
18
19
  import os5 from "node:os";
19
20
  import path5 from "node:path";
20
- import { createServer } from "node:http";
21
- import { Readable } from "node:stream";
22
21
  import { spawn } from "node:child_process";
22
+ import os6 from "node:os";
23
23
  import path6 from "node:path";
24
+ import { createServer } from "node:http";
25
+ import { Readable } from "node:stream";
26
+ import { spawn as spawn2 } from "node:child_process";
27
+ import path7 from "node:path";
24
28
  var store$4;
25
29
  var DEFAULT_CONFIG = {
26
30
  lang: void 0,
@@ -1324,8 +1328,8 @@ var require_node = __commonJS({
1324
1328
  var _this = this;
1325
1329
  if (this.parentNode) {
1326
1330
  var children = this.parentNode.childNodes;
1327
- this.parentNode.childNodes = children.filter(function(child) {
1328
- return _this !== child;
1331
+ this.parentNode.childNodes = children.filter(function(child2) {
1332
+ return _this !== child2;
1329
1333
  });
1330
1334
  this.parentNode = null;
1331
1335
  }
@@ -1838,8 +1842,8 @@ var require_node2 = __commonJS({
1838
1842
  } else if (isTag(node)) {
1839
1843
  var children = recursive ? cloneChildren(node.children) : [];
1840
1844
  var clone_1 = new Element(node.name, __assign({}, node.attribs), children);
1841
- children.forEach(function(child) {
1842
- return child.parent = clone_1;
1845
+ children.forEach(function(child2) {
1846
+ return child2.parent = clone_1;
1843
1847
  });
1844
1848
  if (node.namespace != null) {
1845
1849
  clone_1.namespace = node.namespace;
@@ -1854,15 +1858,15 @@ var require_node2 = __commonJS({
1854
1858
  } else if (isCDATA(node)) {
1855
1859
  var children = recursive ? cloneChildren(node.children) : [];
1856
1860
  var clone_2 = new CDATA(children);
1857
- children.forEach(function(child) {
1858
- return child.parent = clone_2;
1861
+ children.forEach(function(child2) {
1862
+ return child2.parent = clone_2;
1859
1863
  });
1860
1864
  result = clone_2;
1861
1865
  } else if (isDocument(node)) {
1862
1866
  var children = recursive ? cloneChildren(node.children) : [];
1863
1867
  var clone_3 = new Document(children);
1864
- children.forEach(function(child) {
1865
- return child.parent = clone_3;
1868
+ children.forEach(function(child2) {
1869
+ return child2.parent = clone_3;
1866
1870
  });
1867
1871
  if (node["x-mode"]) {
1868
1872
  clone_3["x-mode"] = node["x-mode"];
@@ -1888,8 +1892,8 @@ var require_node2 = __commonJS({
1888
1892
  }
1889
1893
  exports.cloneNode = cloneNode;
1890
1894
  function cloneChildren(childs) {
1891
- var children = childs.map(function(child) {
1892
- return cloneNode(child, true);
1895
+ var children = childs.map(function(child2) {
1896
+ return cloneNode(child2, true);
1893
1897
  });
1894
1898
  for (var i = 1; i < children.length; i++) {
1895
1899
  children[i].prev = children[i - 1];
@@ -3233,16 +3237,16 @@ var require_manipulation = __commonJS({
3233
3237
  elem.parent = null;
3234
3238
  }
3235
3239
  }
3236
- function appendChild(parent, child) {
3237
- removeElement(child);
3238
- child.next = null;
3239
- child.parent = parent;
3240
- if (parent.children.push(child) > 1) {
3240
+ function appendChild(parent, child2) {
3241
+ removeElement(child2);
3242
+ child2.next = null;
3243
+ child2.parent = parent;
3244
+ if (parent.children.push(child2) > 1) {
3241
3245
  var sibling = parent.children[parent.children.length - 2];
3242
- sibling.next = child;
3243
- child.prev = sibling;
3246
+ sibling.next = child2;
3247
+ child2.prev = sibling;
3244
3248
  } else {
3245
- child.prev = null;
3249
+ child2.prev = null;
3246
3250
  }
3247
3251
  }
3248
3252
  function append(elem, next) {
@@ -3263,16 +3267,16 @@ var require_manipulation = __commonJS({
3263
3267
  parent.children.push(next);
3264
3268
  }
3265
3269
  }
3266
- function prependChild(parent, child) {
3267
- removeElement(child);
3268
- child.parent = parent;
3269
- child.prev = null;
3270
- if (parent.children.unshift(child) !== 1) {
3270
+ function prependChild(parent, child2) {
3271
+ removeElement(child2);
3272
+ child2.parent = parent;
3273
+ child2.prev = null;
3274
+ if (parent.children.unshift(child2) !== 1) {
3271
3275
  var sibling = parent.children[1];
3272
- sibling.prev = child;
3273
- child.next = sibling;
3276
+ sibling.prev = child2;
3277
+ child2.next = sibling;
3274
3278
  } else {
3275
- child.next = null;
3279
+ child2.next = null;
3276
3280
  }
3277
3281
  }
3278
3282
  function prepend(elem, prev) {
@@ -5292,7 +5296,7 @@ var require_general = __commonJS({
5292
5296
  };
5293
5297
  }
5294
5298
  case css_what_1.SelectorType.Child: {
5295
- return function child(elem) {
5299
+ return function child2(elem) {
5296
5300
  var parent = adapter.getParent(elem);
5297
5301
  return parent != null && adapter.isTag(parent) && next(parent);
5298
5302
  };
@@ -5536,12 +5540,12 @@ var require_lib7 = __commonJS({
5536
5540
  exports._compileUnsafe = wrapCompile(compile_js_1.compileUnsafe);
5537
5541
  exports._compileToken = wrapCompile(compile_js_1.compileToken);
5538
5542
  function getSelectorFunc(searchFunc) {
5539
- return function select(query, elements, options) {
5543
+ return function select(query, elements2, options) {
5540
5544
  var opts = convertOptionFormats(options);
5541
5545
  if (typeof query !== "function") {
5542
- query = (0, compile_js_1.compileUnsafe)(query, opts, elements);
5546
+ query = (0, compile_js_1.compileUnsafe)(query, opts, elements2);
5543
5547
  }
5544
- var filteredElements = prepareContext(elements, opts.adapter, query.shouldTestNextSiblings);
5548
+ var filteredElements = prepareContext(elements2, opts.adapter, query.shouldTestNextSiblings);
5545
5549
  return searchFunc(query, filteredElements, opts);
5546
5550
  };
5547
5551
  }
@@ -6093,18 +6097,18 @@ var require_html = __commonJS({
6093
6097
  return JSON.stringify(attr.replace(/"/g, "&quot;")).replace(/\\t/g, " ").replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\/g, "");
6094
6098
  };
6095
6099
  HTMLElement2.prototype.removeChild = function(node) {
6096
- this.childNodes = this.childNodes.filter(function(child) {
6097
- return child !== node;
6100
+ this.childNodes = this.childNodes.filter(function(child2) {
6101
+ return child2 !== node;
6098
6102
  });
6099
6103
  return this;
6100
6104
  };
6101
6105
  HTMLElement2.prototype.exchangeChild = function(oldNode, newNode) {
6102
6106
  var children = this.childNodes;
6103
- this.childNodes = children.map(function(child) {
6104
- if (child === oldNode) {
6107
+ this.childNodes = children.map(function(child2) {
6108
+ if (child2 === oldNode) {
6105
6109
  return newNode;
6106
6110
  }
6107
- return child;
6111
+ return child2;
6108
6112
  });
6109
6113
  return this;
6110
6114
  };
@@ -6222,8 +6226,8 @@ var require_html = __commonJS({
6222
6226
  };
6223
6227
  Object.defineProperty(HTMLElement2.prototype, "innerHTML", {
6224
6228
  get: function() {
6225
- return this.childNodes.map(function(child) {
6226
- return child.toString();
6229
+ return this.childNodes.map(function(child2) {
6230
+ return child2.toString();
6227
6231
  }).join("");
6228
6232
  },
6229
6233
  set: function(content) {
@@ -6268,8 +6272,8 @@ var require_html = __commonJS({
6268
6272
  }
6269
6273
  return [];
6270
6274
  }).flat();
6271
- var idx = parent.childNodes.findIndex(function(child) {
6272
- return child === _this;
6275
+ var idx = parent.childNodes.findIndex(function(child2) {
6276
+ return child2 === _this;
6273
6277
  });
6274
6278
  resetParent([this], null);
6275
6279
  parent.childNodes = __spreadArray(__spreadArray(__spreadArray([], parent.childNodes.slice(0, idx), true), resetParent(content, parent), true), parent.childNodes.slice(idx + 1), true);
@@ -6366,21 +6370,21 @@ var require_html = __commonJS({
6366
6370
  var currentNodeReference = this;
6367
6371
  var index = 0;
6368
6372
  while (index !== void 0) {
6369
- var child = void 0;
6373
+ var child2 = void 0;
6370
6374
  do {
6371
- child = currentNodeReference.childNodes[index++];
6372
- } while (index < currentNodeReference.childNodes.length && child === void 0);
6373
- if (child === void 0) {
6375
+ child2 = currentNodeReference.childNodes[index++];
6376
+ } while (index < currentNodeReference.childNodes.length && child2 === void 0);
6377
+ if (child2 === void 0) {
6374
6378
  currentNodeReference = currentNodeReference.parentNode;
6375
6379
  index = stack.pop();
6376
6380
  continue;
6377
6381
  }
6378
- if (child.nodeType === type_1.default.ELEMENT_NODE) {
6379
- if (tagName === "*" || child.tagName === upperCasedTagName)
6380
- re.push(child);
6381
- if (child.childNodes.length > 0) {
6382
+ if (child2.nodeType === type_1.default.ELEMENT_NODE) {
6383
+ if (tagName === "*" || child2.tagName === upperCasedTagName)
6384
+ re.push(child2);
6385
+ if (child2.childNodes.length > 0) {
6382
6386
  stack.push(index);
6383
- currentNodeReference = child;
6387
+ currentNodeReference = child2;
6384
6388
  index = 0;
6385
6389
  }
6386
6390
  }
@@ -6392,23 +6396,23 @@ var require_html = __commonJS({
6392
6396
  var currentNodeReference = this;
6393
6397
  var index = 0;
6394
6398
  while (index !== void 0) {
6395
- var child = void 0;
6399
+ var child2 = void 0;
6396
6400
  do {
6397
- child = currentNodeReference.childNodes[index++];
6398
- } while (index < currentNodeReference.childNodes.length && child === void 0);
6399
- if (child === void 0) {
6401
+ child2 = currentNodeReference.childNodes[index++];
6402
+ } while (index < currentNodeReference.childNodes.length && child2 === void 0);
6403
+ if (child2 === void 0) {
6400
6404
  currentNodeReference = currentNodeReference.parentNode;
6401
6405
  index = stack.pop();
6402
6406
  continue;
6403
6407
  }
6404
- if (child.nodeType === type_1.default.ELEMENT_NODE) {
6405
- if (child.id === id) {
6406
- return child;
6408
+ if (child2.nodeType === type_1.default.ELEMENT_NODE) {
6409
+ if (child2.id === id) {
6410
+ return child2;
6407
6411
  }
6408
6412
  ;
6409
- if (child.childNodes.length > 0) {
6413
+ if (child2.childNodes.length > 0) {
6410
6414
  stack.push(index);
6411
- currentNodeReference = child;
6415
+ currentNodeReference = child2;
6412
6416
  index = 0;
6413
6417
  }
6414
6418
  }
@@ -6426,9 +6430,9 @@ var require_html = __commonJS({
6426
6430
  if (test(el_1)) {
6427
6431
  elem = el_1;
6428
6432
  } else {
6429
- var child = mapChild.get(el_1);
6430
- if (child) {
6431
- elem = findOne(test, [child]);
6433
+ var child2 = mapChild.get(el_1);
6434
+ if (child2) {
6435
+ elem = findOne(test, [child2]);
6432
6436
  }
6433
6437
  }
6434
6438
  }
@@ -6444,8 +6448,8 @@ var require_html = __commonJS({
6444
6448
  var e = (0, css_select_1.selectOne)(selector, el, {
6445
6449
  xmlMode: true,
6446
6450
  adapter: __assign(__assign({}, matcher_1.default), { getChildren: function(node) {
6447
- var child = mapChild.get(node);
6448
- return child && [child];
6451
+ var child2 = mapChild.get(node);
6452
+ return child2 && [child2];
6449
6453
  }, getSiblings: function(node) {
6450
6454
  return [node];
6451
6455
  }, findOne, findAll: function() {
@@ -6624,8 +6628,8 @@ var require_html = __commonJS({
6624
6628
  }
6625
6629
  var p = parse(html, this._parseOptions);
6626
6630
  if (where === "afterend") {
6627
- var idx = this.parentNode.childNodes.findIndex(function(child) {
6628
- return child === _this;
6631
+ var idx = this.parentNode.childNodes.findIndex(function(child2) {
6632
+ return child2 === _this;
6629
6633
  });
6630
6634
  resetParent(p.childNodes, this.parentNode);
6631
6635
  (_a = this.parentNode.childNodes).splice.apply(_a, __spreadArray([idx + 1, 0], p.childNodes, false));
@@ -6637,8 +6641,8 @@ var require_html = __commonJS({
6637
6641
  _this.appendChild(n);
6638
6642
  });
6639
6643
  } else if (where === "beforebegin") {
6640
- var idx = this.parentNode.childNodes.findIndex(function(child) {
6641
- return child === _this;
6644
+ var idx = this.parentNode.childNodes.findIndex(function(child2) {
6645
+ return child2 === _this;
6642
6646
  });
6643
6647
  resetParent(p.childNodes, this.parentNode);
6644
6648
  (_c = this.parentNode.childNodes).splice.apply(_c, __spreadArray([idx, 0], p.childNodes, false));
@@ -6653,8 +6657,8 @@ var require_html = __commonJS({
6653
6657
  var children = this.parentNode.childNodes;
6654
6658
  var i = 0;
6655
6659
  while (i < children.length) {
6656
- var child = children[i++];
6657
- if (this === child)
6660
+ var child2 = children[i++];
6661
+ if (this === child2)
6658
6662
  return children[i] || null;
6659
6663
  }
6660
6664
  return null;
@@ -6670,12 +6674,12 @@ var require_html = __commonJS({
6670
6674
  var i = 0;
6671
6675
  var find = false;
6672
6676
  while (i < children.length) {
6673
- var child = children[i++];
6677
+ var child2 = children[i++];
6674
6678
  if (find) {
6675
- if (child instanceof HTMLElement2) {
6676
- return child || null;
6679
+ if (child2 instanceof HTMLElement2) {
6680
+ return child2 || null;
6677
6681
  }
6678
- } else if (this === child) {
6682
+ } else if (this === child2) {
6679
6683
  find = true;
6680
6684
  }
6681
6685
  }
@@ -6691,8 +6695,8 @@ var require_html = __commonJS({
6691
6695
  var children = this.parentNode.childNodes;
6692
6696
  var i = children.length;
6693
6697
  while (i > 0) {
6694
- var child = children[--i];
6695
- if (this === child)
6698
+ var child2 = children[--i];
6699
+ if (this === child2)
6696
6700
  return children[i - 1] || null;
6697
6701
  }
6698
6702
  return null;
@@ -6708,12 +6712,12 @@ var require_html = __commonJS({
6708
6712
  var i = children.length;
6709
6713
  var find = false;
6710
6714
  while (i > 0) {
6711
- var child = children[--i];
6715
+ var child2 = children[--i];
6712
6716
  if (find) {
6713
- if (child instanceof HTMLElement2) {
6714
- return child || null;
6717
+ if (child2 instanceof HTMLElement2) {
6718
+ return child2 || null;
6715
6719
  }
6716
- } else if (this === child) {
6720
+ } else if (this === child2) {
6717
6721
  find = true;
6718
6722
  }
6719
6723
  }
@@ -6786,18 +6790,18 @@ var require_html = __commonJS({
6786
6790
  options = {};
6787
6791
  }
6788
6792
  var voidTag = new void_tag_1.default((_a = options === null || options === void 0 ? void 0 : options.voidTag) === null || _a === void 0 ? void 0 : _a.closingSlash, (_b = options === null || options === void 0 ? void 0 : options.voidTag) === null || _b === void 0 ? void 0 : _b.tags);
6789
- var elements = options.blockTextElements || {
6793
+ var elements2 = options.blockTextElements || {
6790
6794
  script: true,
6791
6795
  noscript: true,
6792
6796
  style: true,
6793
6797
  pre: true
6794
6798
  };
6795
- var element_names = Object.keys(elements);
6799
+ var element_names = Object.keys(elements2);
6796
6800
  var kBlockTextElements = element_names.map(function(it) {
6797
6801
  return new RegExp("^".concat(it, "$"), "i");
6798
6802
  });
6799
6803
  var kIgnoreElements = element_names.filter(function(it) {
6800
- return Boolean(elements[it]);
6804
+ return Boolean(elements2[it]);
6801
6805
  }).map(function(it) {
6802
6806
  return new RegExp("^".concat(it, "$"), "i");
6803
6807
  });
@@ -6932,16 +6936,16 @@ var require_html = __commonJS({
6932
6936
  if (last.parentNode === oneBefore && last.tagName === oneBefore.tagName) {
6933
6937
  if (options.parseNoneClosedTags !== true) {
6934
6938
  oneBefore.removeChild(last);
6935
- last.childNodes.forEach(function(child) {
6936
- oneBefore.parentNode.appendChild(child);
6939
+ last.childNodes.forEach(function(child2) {
6940
+ oneBefore.parentNode.appendChild(child2);
6937
6941
  });
6938
6942
  stack.pop();
6939
6943
  }
6940
6944
  } else {
6941
6945
  if (options.parseNoneClosedTags !== true) {
6942
6946
  oneBefore.removeChild(last);
6943
- last.childNodes.forEach(function(child) {
6944
- oneBefore.appendChild(child);
6947
+ last.childNodes.forEach(function(child2) {
6948
+ oneBefore.appendChild(child2);
6945
6949
  });
6946
6950
  }
6947
6951
  }
@@ -7634,11 +7638,11 @@ var require_visitor = __commonJS({
7634
7638
  if ((translator === null || translator === void 0 ? void 0 : translator.preserveIfEmpty) || typeof translator === "function")
7635
7639
  res = true;
7636
7640
  } else
7637
- for (const child of childNodes) {
7641
+ for (const child2 of childNodes) {
7638
7642
  if (!res)
7639
- res = visit(child);
7643
+ res = visit(child2);
7640
7644
  else
7641
- visit(child);
7645
+ visit(child2);
7642
7646
  }
7643
7647
  }
7644
7648
  return node2.preserve = res;
@@ -7697,8 +7701,8 @@ var require_visitor = __commonJS({
7697
7701
  if (metadata)
7698
7702
  this.nodeMetadata.set(node, metadata);
7699
7703
  if (!translatorCfgOrFactory) {
7700
- for (const child of (0, utilities_1.getChildNodes)(node))
7701
- this.visitNode(child, textOnly, metadata);
7704
+ for (const child2 of (0, utilities_1.getChildNodes)(node))
7705
+ this.visitNode(child2, textOnly, metadata);
7702
7706
  return;
7703
7707
  }
7704
7708
  let cfg;
@@ -7727,8 +7731,8 @@ var require_visitor = __commonJS({
7727
7731
  this.appendResult(cfg.content, void 0, cfg.spaceIfRepeatingChar);
7728
7732
  else {
7729
7733
  const startPos = result.text.length;
7730
- for (const child of (0, utilities_1.getChildNodes)(node))
7731
- this.visitNode(child, cfg.recurse === false, metadata);
7734
+ for (const child2 of (0, utilities_1.getChildNodes)(node))
7735
+ this.visitNode(child2, cfg.recurse === false, metadata);
7732
7736
  if (cfg.postprocess) {
7733
7737
  const postRes = cfg.postprocess(Object.assign(Object.assign({}, ctx || (0, translator_1.createTranslatorContext)(this, node, metadata)), { content: result.text.substr(startPos) }));
7734
7738
  if (postRes === translator_1.PostProcessResult.RemoveNode) {
@@ -11243,194 +11247,1058 @@ var SlackMonitor = class extends Monitor3 {
11243
11247
  return { error: "threadUrl does not contain a Slack channel and thread timestamp" };
11244
11248
  }
11245
11249
  };
11246
- var SOURCE_MAP = {
11247
- jira: new JiraMonitor(),
11248
- github: new GithubMonitor(),
11249
- slack: new SlackMonitor()
11250
+ var store$45;
11251
+ var DEFAULT_CONFIG5 = {
11252
+ lang: void 0,
11253
+ message: void 0,
11254
+ abortEarly: void 0,
11255
+ abortPipeEarly: void 0
11250
11256
  };
11251
- var SOURCE_TYPES = Object.keys(SOURCE_MAP);
11252
- function sourceDefinition(source) {
11253
- return SOURCE_MAP[source.type];
11257
+ // @__NO_SIDE_EFFECTS__
11258
+ function getGlobalConfig5(config$1) {
11259
+ if (!config$1 && !store$45) return DEFAULT_CONFIG5;
11260
+ return {
11261
+ lang: config$1?.lang ?? store$45?.lang,
11262
+ message: config$1?.message,
11263
+ abortEarly: config$1?.abortEarly ?? store$45?.abortEarly,
11264
+ abortPipeEarly: config$1?.abortPipeEarly ?? store$45?.abortPipeEarly
11265
+ };
11254
11266
  }
11255
- function isSource(input) {
11256
- return typeof input.type === "string";
11267
+ var store$35;
11268
+ // @__NO_SIDE_EFFECTS__
11269
+ function getGlobalMessage5(lang) {
11270
+ return store$35?.get(lang);
11257
11271
  }
11258
- function sourceForInput(type, input) {
11259
- const source = SOURCE_MAP[type];
11260
- return source.build(input);
11272
+ var store$25;
11273
+ // @__NO_SIDE_EFFECTS__
11274
+ function getSchemaMessage5(lang) {
11275
+ return store$25?.get(lang);
11261
11276
  }
11262
- function sourceForWebhookPath(pathname) {
11263
- const sources = Object.values(SOURCE_MAP);
11264
- for (const source of sources) {
11265
- if (source.webhook?.path === pathname) return source;
11266
- }
11267
- return void 0;
11277
+ var store$15;
11278
+ // @__NO_SIDE_EFFECTS__
11279
+ function getSpecificMessage5(reference, lang) {
11280
+ return store$15?.get(reference)?.get(lang);
11268
11281
  }
11269
- var DAEMON_ENVIRONMENT = [
11270
- "PATH",
11271
- "HOME",
11272
- "USER",
11273
- "TMPDIR",
11274
- "LANG",
11275
- "XDG_CONFIG_HOME",
11276
- "XDG_STATE_HOME",
11277
- "ATLASSIAN_EMAIL",
11278
- "ATLASSIAN_API_KEY",
11279
- "GH_TOKEN",
11280
- "GITHUB_TOKEN",
11281
- "SOURCEFED_JIRA_BASE_URL",
11282
- "SOURCEFED_JIRA_TERMINAL_STATUS",
11283
- "SOURCEFED_STATE_DIR",
11284
- "SOURCEFED_DAEMON_TOKEN",
11285
- "SOURCEFED_SLACK_TOKEN",
11286
- "SOURCEFED_GITHUB_WEBHOOK_SECRET",
11287
- "SOURCEFED_SLACK_SIGNING_SECRET",
11288
- "SOURCEFED_ENABLE_WEBHOOKS",
11289
- "SOURCEFED_WEBHOOK_HOST",
11290
- "SOURCEFED_WEBHOOK_PORT"
11291
- ];
11292
- function daemonEnvironment(host) {
11293
- const environment = Object.fromEntries(
11294
- DAEMON_ENVIRONMENT.flatMap((name) => process.env[name] === void 0 ? [] : [[name, process.env[name]]])
11295
- );
11296
- if (host) environment.SOURCEFED_STATE_DIR ??= path5.join(process.env.XDG_STATE_HOME ?? path5.join(os5.homedir(), ".local", "state"), "sourcefed", host);
11297
- return environment;
11282
+ // @__NO_SIDE_EFFECTS__
11283
+ function _stringify5(input) {
11284
+ const type = typeof input;
11285
+ if (type === "string") return `"${input}"`;
11286
+ if (type === "number" || type === "bigint" || type === "boolean") return `${input}`;
11287
+ if (type === "object" || type === "function") return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null";
11288
+ return type;
11298
11289
  }
11299
- async function serveHttp(options) {
11300
- const active = /* @__PURE__ */ new Set();
11301
- const server = createServer((incoming, outgoing) => {
11302
- active.add(outgoing);
11303
- outgoing.on("close", () => active.delete(outgoing));
11304
- void handle(incoming, outgoing, options.handler);
11305
- });
11306
- server.requestTimeout = 0;
11307
- server.on("error", (error) => {
11308
- console.error(`[sourcefed] http server error: ${error instanceof Error ? error.message : String(error)}`);
11309
- });
11310
- server.on("clientError", (_error, socket) => {
11311
- socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
11312
- });
11313
- await new Promise((resolve, reject) => {
11314
- server.once("error", reject);
11315
- server.listen(options.port, options.hostname, () => resolve());
11316
- });
11317
- const address = server.address();
11318
- const port = typeof address === "object" && address ? address.port : options.port;
11319
- return {
11320
- port,
11321
- async stop() {
11322
- for (const outgoing of active) {
11323
- outgoing.destroy();
11324
- }
11325
- active.clear();
11326
- server.closeIdleConnections?.();
11327
- await new Promise((resolve) => {
11328
- server.close(() => resolve());
11329
- });
11330
- }
11290
+ function _addIssue5(context, label, dataset, config$1, other) {
11291
+ const input = other && "input" in other ? other.input : dataset.value;
11292
+ const expected = other?.expected ?? context.expects ?? null;
11293
+ const received = other?.received ?? /* @__PURE__ */ _stringify5(input);
11294
+ const issue = {
11295
+ kind: context.kind,
11296
+ type: context.type,
11297
+ input,
11298
+ expected,
11299
+ received,
11300
+ message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`,
11301
+ requirement: context.requirement,
11302
+ path: other?.path,
11303
+ issues: other?.issues,
11304
+ lang: config$1.lang,
11305
+ abortEarly: config$1.abortEarly,
11306
+ abortPipeEarly: config$1.abortPipeEarly
11331
11307
  };
11308
+ const isSchema = context.kind === "schema";
11309
+ const message$1 = other?.message ?? context.message ?? /* @__PURE__ */ getSpecificMessage5(context.reference, issue.lang) ?? (isSchema ? /* @__PURE__ */ getSchemaMessage5(issue.lang) : null) ?? config$1.message ?? /* @__PURE__ */ getGlobalMessage5(issue.lang);
11310
+ if (message$1 !== void 0) issue.message = typeof message$1 === "function" ? message$1(issue) : message$1;
11311
+ if (isSchema) dataset.typed = false;
11312
+ if (dataset.issues) dataset.issues.push(issue);
11313
+ else dataset.issues = [issue];
11332
11314
  }
11333
- async function handle(incoming, outgoing, handler) {
11334
- try {
11335
- const response = await handler(toRequest(incoming));
11336
- await writeResponse(outgoing, response);
11337
- } catch (error) {
11338
- console.error(`[sourcefed] request failed: ${error instanceof Error ? error.message : String(error)}`);
11339
- if (!outgoing.headersSent) outgoing.writeHead(500, { "content-type": "text/plain" });
11340
- outgoing.end("internal error");
11315
+ var _standardCache5 = /* @__PURE__ */ new WeakMap();
11316
+ // @__NO_SIDE_EFFECTS__
11317
+ function _getStandardProps5(context) {
11318
+ let cached = _standardCache5.get(context);
11319
+ if (!cached) {
11320
+ cached = {
11321
+ version: 1,
11322
+ vendor: "valibot",
11323
+ validate(value$1) {
11324
+ return context["~run"]({ value: value$1 }, /* @__PURE__ */ getGlobalConfig5());
11325
+ }
11326
+ };
11327
+ _standardCache5.set(context, cached);
11341
11328
  }
11329
+ return cached;
11342
11330
  }
11343
- function toRequest(incoming) {
11344
- const url = new URL(incoming.url ?? "/", `http://${incoming.headers.host ?? "localhost"}`);
11345
- const method = incoming.method ?? "GET";
11346
- const hasBody = method !== "GET" && method !== "HEAD";
11347
- const headers = new Headers();
11348
- for (const [name, value] of Object.entries(incoming.headers)) {
11349
- if (value === void 0) continue;
11350
- if (Array.isArray(value)) {
11351
- for (const item of value) headers.append(name, item);
11352
- } else {
11353
- headers.set(name, value);
11331
+ var EMOJI_REGEX5 = new RegExp("^(?:[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation}))*)+$", "u");
11332
+ // @__NO_SIDE_EFFECTS__
11333
+ function array5(item, message$1) {
11334
+ return {
11335
+ kind: "schema",
11336
+ type: "array",
11337
+ reference: array5,
11338
+ expects: "Array",
11339
+ async: false,
11340
+ item,
11341
+ message: message$1,
11342
+ get "~standard"() {
11343
+ return /* @__PURE__ */ _getStandardProps5(this);
11344
+ },
11345
+ "~run"(dataset, config$1) {
11346
+ const input = dataset.value;
11347
+ if (Array.isArray(input)) {
11348
+ dataset.typed = true;
11349
+ dataset.value = [];
11350
+ for (let key = 0; key < input.length; key++) {
11351
+ const value$1 = input[key];
11352
+ const itemDataset = this.item["~run"]({ value: value$1 }, config$1);
11353
+ if (itemDataset.issues) {
11354
+ const pathItem = {
11355
+ type: "array",
11356
+ origin: "value",
11357
+ input,
11358
+ key,
11359
+ value: value$1
11360
+ };
11361
+ for (const issue of itemDataset.issues) {
11362
+ if (issue.path) issue.path.unshift(pathItem);
11363
+ else issue.path = [pathItem];
11364
+ dataset.issues?.push(issue);
11365
+ }
11366
+ if (!dataset.issues) dataset.issues = itemDataset.issues;
11367
+ if (config$1.abortEarly) {
11368
+ dataset.typed = false;
11369
+ break;
11370
+ }
11371
+ }
11372
+ if (!itemDataset.typed) dataset.typed = false;
11373
+ dataset.value.push(itemDataset.value);
11374
+ }
11375
+ } else _addIssue5(this, "type", dataset, config$1);
11376
+ return dataset;
11354
11377
  }
11355
- }
11356
- const init = {
11357
- method,
11358
- headers,
11359
- body: hasBody ? Readable.toWeb(incoming) : void 0,
11360
- duplex: "half"
11361
11378
  };
11362
- return new Request(url, init);
11363
- }
11364
- async function writeResponse(outgoing, response) {
11365
- outgoing.writeHead(response.status, Object.fromEntries(response.headers.entries()));
11366
- if (!response.body) {
11367
- outgoing.end();
11368
- return;
11369
- }
11370
- const stream = Readable.fromWeb(response.body);
11371
- stream.on("error", (error) => {
11372
- console.error(`[sourcefed] response stream error: ${error instanceof Error ? error.message : String(error)}`);
11373
- });
11374
- await new Promise((resolve) => {
11375
- let finished = false;
11376
- const done = () => {
11377
- if (finished) return;
11378
- finished = true;
11379
- resolve();
11380
- };
11381
- outgoing.on("finish", done);
11382
- outgoing.on("close", () => {
11383
- stream.unpipe(outgoing);
11384
- stream.destroy();
11385
- done();
11386
- });
11387
- stream.pipe(outgoing);
11388
- });
11389
- }
11390
- var RequestRouter = class {
11391
- pending = /* @__PURE__ */ new Map();
11392
- cursor = 1;
11393
- nextID() {
11394
- return this.cursor++;
11395
- }
11396
- register(id) {
11397
- return new Promise((resolve, reject) => {
11398
- this.pending.set(id, { resolve, reject });
11399
- });
11400
- }
11401
- settle(id, frame) {
11402
- const pending = this.pending.get(id);
11403
- if (!pending) return;
11404
- this.pending.delete(id);
11405
- if (frame.error) pending.reject(new Error(frame.error));
11406
- else pending.resolve(frame.result);
11407
- }
11408
- rejectAll(error) {
11409
- for (const { reject } of this.pending.values()) reject(error);
11410
- this.pending.clear();
11411
- }
11412
- };
11413
- function defaultDaemonUrl() {
11414
- const port = process.env.SOURCEFED_DAEMON_PORT ?? 18787;
11415
- return `http://127.0.0.1:${port}`;
11416
11379
  }
11417
- function daemonCommand(cliEntryPath) {
11380
+ // @__NO_SIDE_EFFECTS__
11381
+ function string5(message$1) {
11418
11382
  return {
11419
- command: nodeExecutable(),
11420
- args: [cliEntryPath, "daemon"]
11383
+ kind: "schema",
11384
+ type: "string",
11385
+ reference: string5,
11386
+ expects: "string",
11387
+ async: false,
11388
+ message: message$1,
11389
+ get "~standard"() {
11390
+ return /* @__PURE__ */ _getStandardProps5(this);
11391
+ },
11392
+ "~run"(dataset, config$1) {
11393
+ if (typeof dataset.value === "string") dataset.typed = true;
11394
+ else _addIssue5(this, "type", dataset, config$1);
11395
+ return dataset;
11396
+ }
11421
11397
  };
11422
11398
  }
11423
- function nodeExecutable() {
11424
- const base = path6.basename(process.execPath);
11425
- if (base.includes("node") || base.includes("bun")) return process.execPath;
11426
- return "node";
11399
+ // @__NO_SIDE_EFFECTS__
11400
+ function safeParse5(schema, input, config$1) {
11401
+ const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig5(config$1));
11402
+ return {
11403
+ typed: dataset.typed,
11404
+ success: !dataset.issues,
11405
+ output: dataset.value,
11406
+ issues: dataset.issues
11407
+ };
11427
11408
  }
11428
- async function spawnLocalDaemon(options) {
11409
+ var Monitor4 = class {
11410
+ type;
11411
+ schema;
11412
+ poll;
11413
+ webhook;
11414
+ constructor(options) {
11415
+ this.type = options.type;
11416
+ this.schema = options.schema;
11417
+ }
11418
+ validateSource(source) {
11419
+ const result = /* @__PURE__ */ safeParse5(this.schema, source);
11420
+ if (result.success) return result.output;
11421
+ throw new Error(`invalid ${this.type} monitor source`);
11422
+ }
11423
+ initialDelivery(source) {
11424
+ this.validateSource(source);
11425
+ if (this.webhook && this.webhook.preferred && this.webhook.configured()) return "webhook";
11426
+ if (this.poll) return "poll";
11427
+ if (this.webhook) return "webhook";
11428
+ throw new Error(`source ${this.type} has no configured transport`);
11429
+ }
11430
+ resolveDelivery(monitor) {
11431
+ let webhookHealthy = false;
11432
+ if (this.webhook) webhookHealthy = this.webhook.isHealthy(monitor);
11433
+ if (monitor.delivery === "webhook") {
11434
+ if (this.webhook && webhookHealthy) return "webhook";
11435
+ if (this.poll) return "poll";
11436
+ if (this.webhook) return "webhook";
11437
+ return void 0;
11438
+ }
11439
+ if (this.webhook && webhookHealthy) return "webhook";
11440
+ if (this.poll) return "poll";
11441
+ if (this.webhook) return "webhook";
11442
+ return void 0;
11443
+ }
11444
+ async tick(context, record2) {
11445
+ const fresh = await context.service.get(record2.id);
11446
+ if (!fresh || !fresh.enabled) return 0;
11447
+ if (this.webhook) await this.webhook.retryPending(context, this, fresh);
11448
+ const current = await context.service.get(record2.id);
11449
+ if (!current || !current.enabled) return 0;
11450
+ const nextDelivery = this.resolveDelivery(current);
11451
+ if (!nextDelivery) return 0;
11452
+ if (nextDelivery !== current.delivery) {
11453
+ await context.service.setDelivery(current.id, nextDelivery);
11454
+ current.delivery = nextDelivery;
11455
+ }
11456
+ if (current.delivery !== "poll" || !this.poll) return 0;
11457
+ const lastAttemptAt = Number(current.cursors.__lastAttemptAt ?? current.cursors.__lastPolledAt ?? 0);
11458
+ const pollIntervalSec = current.pollIntervalSec || 60;
11459
+ if (lastAttemptAt && Date.now() - lastAttemptAt < pollIntervalSec * 1e3) return 0;
11460
+ return this.poll.run(context, this, current);
11461
+ }
11462
+ async deliver(context, record2, event, deliveryId) {
11463
+ if (!this.webhook) return 0;
11464
+ return this.webhook.deliver(context, this, record2, event, deliveryId);
11465
+ }
11466
+ unresponsive(record2, now = Date.now()) {
11467
+ if (!record2.enabled) return false;
11468
+ if (record2.delivery === "poll") {
11469
+ if (!this.poll) return true;
11470
+ return this.poll.isUnresponsive(record2, now);
11471
+ }
11472
+ if (!this.webhook) return true;
11473
+ return this.webhook.isUnresponsive(record2, now);
11474
+ }
11475
+ };
11476
+ var RoutedEventCursorSchema4 = /* @__PURE__ */ array5(/* @__PURE__ */ string5());
11477
+ function eventDeliveryId4(event) {
11478
+ if (event.id) return event.id;
11479
+ return `${event.kind}:${event.at}:${event.summary}`;
11480
+ }
11481
+ var activePolls4 = /* @__PURE__ */ new Set();
11482
+ var PollMonitor4 = class {
11483
+ constructor(options) {
11484
+ this.options = options;
11485
+ }
11486
+ async run(context, source, record2) {
11487
+ if (activePolls4.has(record2.id)) return 0;
11488
+ activePolls4.add(record2.id);
11489
+ try {
11490
+ const fresh = await context.service.get(record2.id);
11491
+ if (!fresh) return 0;
11492
+ const sourceRecord = source.validateSource(fresh.source);
11493
+ const cursorKey = source.key(sourceRecord);
11494
+ const result = await this.options.run(sourceRecord, fresh.cursors[cursorKey]);
11495
+ const current = await context.service.get(record2.id);
11496
+ if (!current || !current.enabled) return 0;
11497
+ const parsedRoutedIds = /* @__PURE__ */ safeParse5(RoutedEventCursorSchema4, fresh.cursors.__routedEventIds);
11498
+ let routedIds = [];
11499
+ if (parsedRoutedIds.success) routedIds = parsedRoutedIds.output;
11500
+ let routeFailed = false;
11501
+ for (const event of result.events) {
11502
+ const eventId = eventDeliveryId4(event);
11503
+ if (routedIds.includes(eventId)) continue;
11504
+ const routed = await context.sink.deliver({ monitor: fresh, event });
11505
+ if (!routed.ok) {
11506
+ routeFailed = true;
11507
+ console.error(`[sourcefed] route failed for ${fresh.id}: ${routed.error}`);
11508
+ continue;
11509
+ }
11510
+ if (!routedIds.includes(eventId)) routedIds.push(eventId);
11511
+ }
11512
+ if (routeFailed) {
11513
+ await context.service.updateCursor(fresh, "__routedEventIds", routedIds);
11514
+ return 0;
11515
+ }
11516
+ await context.service.updateCursorValue(fresh, cursorKey, (current2) => {
11517
+ if (this.options.mergeCursor) return this.options.mergeCursor(current2, result.cursor);
11518
+ return result.cursor;
11519
+ });
11520
+ await context.service.updateCursor(fresh, "__routedEventIds", []);
11521
+ if (result.terminal) await context.service.remove(fresh.id);
11522
+ await context.service.updateCursor(fresh, "__lastPolledAt", Date.now());
11523
+ return result.events.length;
11524
+ } finally {
11525
+ activePolls4.delete(record2.id);
11526
+ }
11527
+ }
11528
+ isUnresponsive(record2, now) {
11529
+ const intervalMs = Math.max((record2.pollIntervalSec || 60) * 3e3, 12e4);
11530
+ const lastPolledAt = Number(record2.cursors.__lastPolledAt ?? 0);
11531
+ if (lastPolledAt > 0) return now - lastPolledAt > intervalMs;
11532
+ return now - Date.parse(record2.createdAt) > intervalMs;
11533
+ }
11534
+ };
11535
+ var MAX_WEBHOOK_BODY_BYTES5 = 1024 * 1024;
11536
+ function toMonitorEvent4(event, source) {
11537
+ return {
11538
+ source,
11539
+ kind: event.kind,
11540
+ id: event.id,
11541
+ at: event.at,
11542
+ summary: event.summary,
11543
+ body: event.body,
11544
+ actionable: event.actionable,
11545
+ terminal: event.terminal
11546
+ };
11547
+ }
11548
+ var store$425;
11549
+ var DEFAULT_CONFIG25 = {
11550
+ lang: void 0,
11551
+ message: void 0,
11552
+ abortEarly: void 0,
11553
+ abortPipeEarly: void 0
11554
+ };
11555
+ // @__NO_SIDE_EFFECTS__
11556
+ function getGlobalConfig25(config$1) {
11557
+ if (!config$1 && !store$425) return DEFAULT_CONFIG25;
11558
+ return {
11559
+ lang: config$1?.lang ?? store$425?.lang,
11560
+ message: config$1?.message,
11561
+ abortEarly: config$1?.abortEarly ?? store$425?.abortEarly,
11562
+ abortPipeEarly: config$1?.abortPipeEarly ?? store$425?.abortPipeEarly
11563
+ };
11564
+ }
11565
+ var store$325;
11566
+ // @__NO_SIDE_EFFECTS__
11567
+ function getGlobalMessage25(lang) {
11568
+ return store$325?.get(lang);
11569
+ }
11570
+ var store$225;
11571
+ // @__NO_SIDE_EFFECTS__
11572
+ function getSchemaMessage25(lang) {
11573
+ return store$225?.get(lang);
11574
+ }
11575
+ var store$125;
11576
+ // @__NO_SIDE_EFFECTS__
11577
+ function getSpecificMessage25(reference, lang) {
11578
+ return store$125?.get(reference)?.get(lang);
11579
+ }
11580
+ // @__NO_SIDE_EFFECTS__
11581
+ function _stringify25(input) {
11582
+ const type = typeof input;
11583
+ if (type === "string") return `"${input}"`;
11584
+ if (type === "number" || type === "bigint" || type === "boolean") return `${input}`;
11585
+ if (type === "object" || type === "function") return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null";
11586
+ return type;
11587
+ }
11588
+ function _addIssue25(context, label, dataset, config$1, other) {
11589
+ const input = other && "input" in other ? other.input : dataset.value;
11590
+ const expected = other?.expected ?? context.expects ?? null;
11591
+ const received = other?.received ?? /* @__PURE__ */ _stringify25(input);
11592
+ const issue = {
11593
+ kind: context.kind,
11594
+ type: context.type,
11595
+ input,
11596
+ expected,
11597
+ received,
11598
+ message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`,
11599
+ requirement: context.requirement,
11600
+ path: other?.path,
11601
+ issues: other?.issues,
11602
+ lang: config$1.lang,
11603
+ abortEarly: config$1.abortEarly,
11604
+ abortPipeEarly: config$1.abortPipeEarly
11605
+ };
11606
+ const isSchema = context.kind === "schema";
11607
+ const message$1 = other?.message ?? context.message ?? /* @__PURE__ */ getSpecificMessage25(context.reference, issue.lang) ?? (isSchema ? /* @__PURE__ */ getSchemaMessage25(issue.lang) : null) ?? config$1.message ?? /* @__PURE__ */ getGlobalMessage25(issue.lang);
11608
+ if (message$1 !== void 0) issue.message = typeof message$1 === "function" ? message$1(issue) : message$1;
11609
+ if (isSchema) dataset.typed = false;
11610
+ if (dataset.issues) dataset.issues.push(issue);
11611
+ else dataset.issues = [issue];
11612
+ }
11613
+ var _standardCache25 = /* @__PURE__ */ new WeakMap();
11614
+ // @__NO_SIDE_EFFECTS__
11615
+ function _getStandardProps25(context) {
11616
+ let cached = _standardCache25.get(context);
11617
+ if (!cached) {
11618
+ cached = {
11619
+ version: 1,
11620
+ vendor: "valibot",
11621
+ validate(value$1) {
11622
+ return context["~run"]({ value: value$1 }, /* @__PURE__ */ getGlobalConfig25());
11623
+ }
11624
+ };
11625
+ _standardCache25.set(context, cached);
11626
+ }
11627
+ return cached;
11628
+ }
11629
+ var EMOJI_REGEX25 = new RegExp("^(?:[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation}))*)+$", "u");
11630
+ // @__NO_SIDE_EFFECTS__
11631
+ function getFallback5(schema, dataset, config$1) {
11632
+ return typeof schema.fallback === "function" ? schema.fallback(dataset, config$1) : schema.fallback;
11633
+ }
11634
+ // @__NO_SIDE_EFFECTS__
11635
+ function getDefault5(schema, dataset, config$1) {
11636
+ return typeof schema.default === "function" ? schema.default(dataset, config$1) : schema.default;
11637
+ }
11638
+ // @__NO_SIDE_EFFECTS__
11639
+ function array25(item, message$1) {
11640
+ return {
11641
+ kind: "schema",
11642
+ type: "array",
11643
+ reference: array25,
11644
+ expects: "Array",
11645
+ async: false,
11646
+ item,
11647
+ message: message$1,
11648
+ get "~standard"() {
11649
+ return /* @__PURE__ */ _getStandardProps25(this);
11650
+ },
11651
+ "~run"(dataset, config$1) {
11652
+ const input = dataset.value;
11653
+ if (Array.isArray(input)) {
11654
+ dataset.typed = true;
11655
+ dataset.value = [];
11656
+ for (let key = 0; key < input.length; key++) {
11657
+ const value$1 = input[key];
11658
+ const itemDataset = this.item["~run"]({ value: value$1 }, config$1);
11659
+ if (itemDataset.issues) {
11660
+ const pathItem = {
11661
+ type: "array",
11662
+ origin: "value",
11663
+ input,
11664
+ key,
11665
+ value: value$1
11666
+ };
11667
+ for (const issue of itemDataset.issues) {
11668
+ if (issue.path) issue.path.unshift(pathItem);
11669
+ else issue.path = [pathItem];
11670
+ dataset.issues?.push(issue);
11671
+ }
11672
+ if (!dataset.issues) dataset.issues = itemDataset.issues;
11673
+ if (config$1.abortEarly) {
11674
+ dataset.typed = false;
11675
+ break;
11676
+ }
11677
+ }
11678
+ if (!itemDataset.typed) dataset.typed = false;
11679
+ dataset.value.push(itemDataset.value);
11680
+ }
11681
+ } else _addIssue25(this, "type", dataset, config$1);
11682
+ return dataset;
11683
+ }
11684
+ };
11685
+ }
11686
+ // @__NO_SIDE_EFFECTS__
11687
+ function boolean4(message$1) {
11688
+ return {
11689
+ kind: "schema",
11690
+ type: "boolean",
11691
+ reference: boolean4,
11692
+ expects: "boolean",
11693
+ async: false,
11694
+ message: message$1,
11695
+ get "~standard"() {
11696
+ return /* @__PURE__ */ _getStandardProps25(this);
11697
+ },
11698
+ "~run"(dataset, config$1) {
11699
+ if (typeof dataset.value === "boolean") dataset.typed = true;
11700
+ else _addIssue25(this, "type", dataset, config$1);
11701
+ return dataset;
11702
+ }
11703
+ };
11704
+ }
11705
+ // @__NO_SIDE_EFFECTS__
11706
+ function literal4(literal_, message$1) {
11707
+ return {
11708
+ kind: "schema",
11709
+ type: "literal",
11710
+ reference: literal4,
11711
+ expects: /* @__PURE__ */ _stringify25(literal_),
11712
+ async: false,
11713
+ literal: literal_,
11714
+ message: message$1,
11715
+ get "~standard"() {
11716
+ return /* @__PURE__ */ _getStandardProps25(this);
11717
+ },
11718
+ "~run"(dataset, config$1) {
11719
+ if (dataset.value === this.literal) dataset.typed = true;
11720
+ else _addIssue25(this, "type", dataset, config$1);
11721
+ return dataset;
11722
+ }
11723
+ };
11724
+ }
11725
+ // @__NO_SIDE_EFFECTS__
11726
+ function object5(entries$1, message$1) {
11727
+ return {
11728
+ kind: "schema",
11729
+ type: "object",
11730
+ reference: object5,
11731
+ expects: "Object",
11732
+ async: false,
11733
+ entries: entries$1,
11734
+ message: message$1,
11735
+ get "~standard"() {
11736
+ return /* @__PURE__ */ _getStandardProps25(this);
11737
+ },
11738
+ "~run"(dataset, config$1) {
11739
+ const input = dataset.value;
11740
+ if (input && typeof input === "object") {
11741
+ dataset.typed = true;
11742
+ dataset.value = {};
11743
+ for (const key in this.entries) {
11744
+ const valueSchema = this.entries[key];
11745
+ if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) {
11746
+ const value$1 = key in input ? input[key] : /* @__PURE__ */ getDefault5(valueSchema);
11747
+ const valueDataset = valueSchema["~run"]({ value: value$1 }, config$1);
11748
+ if (valueDataset.issues) {
11749
+ const pathItem = {
11750
+ type: "object",
11751
+ origin: "value",
11752
+ input,
11753
+ key,
11754
+ value: value$1
11755
+ };
11756
+ for (const issue of valueDataset.issues) {
11757
+ if (issue.path) issue.path.unshift(pathItem);
11758
+ else issue.path = [pathItem];
11759
+ dataset.issues?.push(issue);
11760
+ }
11761
+ if (!dataset.issues) dataset.issues = valueDataset.issues;
11762
+ if (config$1.abortEarly) {
11763
+ dataset.typed = false;
11764
+ break;
11765
+ }
11766
+ }
11767
+ if (!valueDataset.typed) dataset.typed = false;
11768
+ dataset.value[key] = valueDataset.value;
11769
+ } else if (valueSchema.fallback !== void 0) dataset.value[key] = /* @__PURE__ */ getFallback5(valueSchema);
11770
+ else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") {
11771
+ _addIssue25(this, "key", dataset, config$1, {
11772
+ input: void 0,
11773
+ expected: `"${key}"`,
11774
+ path: [{
11775
+ type: "object",
11776
+ origin: "key",
11777
+ input,
11778
+ key,
11779
+ value: input[key]
11780
+ }]
11781
+ });
11782
+ if (config$1.abortEarly) break;
11783
+ }
11784
+ }
11785
+ } else _addIssue25(this, "type", dataset, config$1);
11786
+ return dataset;
11787
+ }
11788
+ };
11789
+ }
11790
+ // @__NO_SIDE_EFFECTS__
11791
+ function optional5(wrapped, default_) {
11792
+ return {
11793
+ kind: "schema",
11794
+ type: "optional",
11795
+ reference: optional5,
11796
+ expects: `(${wrapped.expects} | undefined)`,
11797
+ async: false,
11798
+ wrapped,
11799
+ default: default_,
11800
+ get "~standard"() {
11801
+ return /* @__PURE__ */ _getStandardProps25(this);
11802
+ },
11803
+ "~run"(dataset, config$1) {
11804
+ if (dataset.value === void 0) {
11805
+ if (this.default !== void 0) dataset.value = /* @__PURE__ */ getDefault5(this, dataset, config$1);
11806
+ if (dataset.value === void 0) {
11807
+ dataset.typed = true;
11808
+ return dataset;
11809
+ }
11810
+ }
11811
+ return this.wrapped["~run"](dataset, config$1);
11812
+ }
11813
+ };
11814
+ }
11815
+ // @__NO_SIDE_EFFECTS__
11816
+ function string25(message$1) {
11817
+ return {
11818
+ kind: "schema",
11819
+ type: "string",
11820
+ reference: string25,
11821
+ expects: "string",
11822
+ async: false,
11823
+ message: message$1,
11824
+ get "~standard"() {
11825
+ return /* @__PURE__ */ _getStandardProps25(this);
11826
+ },
11827
+ "~run"(dataset, config$1) {
11828
+ if (typeof dataset.value === "string") dataset.typed = true;
11829
+ else _addIssue25(this, "type", dataset, config$1);
11830
+ return dataset;
11831
+ }
11832
+ };
11833
+ }
11834
+ // @__NO_SIDE_EFFECTS__
11835
+ function safeParse25(schema, input, config$1) {
11836
+ const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig25(config$1));
11837
+ return {
11838
+ typed: dataset.typed,
11839
+ success: !dataset.issues,
11840
+ output: dataset.value,
11841
+ issues: dataset.issues
11842
+ };
11843
+ }
11844
+ var YabSourceSchema = /* @__PURE__ */ object5({
11845
+ type: /* @__PURE__ */ literal4("yab"),
11846
+ url: /* @__PURE__ */ string25(),
11847
+ space: /* @__PURE__ */ optional5(/* @__PURE__ */ string25()),
11848
+ match: /* @__PURE__ */ optional5(/* @__PURE__ */ string25()),
11849
+ exclude: /* @__PURE__ */ optional5(/* @__PURE__ */ string25())
11850
+ });
11851
+ var YabCursorSchema = /* @__PURE__ */ object5({
11852
+ primed: /* @__PURE__ */ boolean4(),
11853
+ seenIds: /* @__PURE__ */ array25(/* @__PURE__ */ string25())
11854
+ });
11855
+ var SEEN_LIMIT = 1e3;
11856
+ function feedEvents(source, entries, cursorRaw) {
11857
+ const parsedCursor = /* @__PURE__ */ safeParse25(YabCursorSchema, cursorRaw);
11858
+ let previous = {};
11859
+ if (parsedCursor.success) previous = parsedCursor.output;
11860
+ const cursor = { primed: previous.primed ?? false, seenIds: previous.seenIds ?? [] };
11861
+ let events = [];
11862
+ if (cursor.primed) {
11863
+ const seen = new Set(cursor.seenIds);
11864
+ const match = source.match ? new RegExp(source.match, "i") : void 0;
11865
+ const exclude = source.exclude ? new RegExp(source.exclude, "i") : void 0;
11866
+ events = entries.filter((entry) => !seen.has(entry.id)).filter((entry) => {
11867
+ const text = [entry.title, entry.summary, entry.author].filter(Boolean).join("\n");
11868
+ if (match && !match.test(text)) return false;
11869
+ if (exclude && exclude.test(text)) return false;
11870
+ return true;
11871
+ }).sort((left, right) => left.at && right.at ? left.at.localeCompare(right.at) : 0).map(entryEvent);
11872
+ }
11873
+ cursor.primed = true;
11874
+ cursor.seenIds = [.../* @__PURE__ */ new Set([...cursor.seenIds, ...entries.map((entry) => entry.id)])].slice(-SEEN_LIMIT);
11875
+ return { events, cursor };
11876
+ }
11877
+ function entryEvent(entry) {
11878
+ const title = entry.title || "(untitled)";
11879
+ return {
11880
+ kind: "entry",
11881
+ id: `entry:${entry.id}`,
11882
+ at: entry.at ?? (/* @__PURE__ */ new Date()).toISOString(),
11883
+ summary: entry.author ? `Yab feed entry from ${entry.author}: ${title}` : `Yab feed entry: ${title}`,
11884
+ body: [entry.summary, entry.link].filter(Boolean).join("\n\n") || void 0,
11885
+ actionable: true
11886
+ };
11887
+ }
11888
+ var INVISIBLE = /[\u00AD\u034F\u061C\u115F\u1160\u17B4\u17B5\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u3164\uFEFF]/g;
11889
+ var ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: " " };
11890
+ function parseFeed(body, type = "") {
11891
+ const text = body.trim();
11892
+ if (/json/i.test(type) || text.startsWith("{") || text.startsWith("[")) return parseJsonFeed(text);
11893
+ if (!/<(feed|rss|rdf:RDF)[\s>]/i.test(text)) throw new Error("the page is not an Atom, RSS or JSON feed");
11894
+ const entries = elements(text, "entry");
11895
+ const blocks = entries.length > 0 ? entries : elements(text, "item");
11896
+ return blocks.map(xmlEntry).filter((entry) => entry !== void 0);
11897
+ }
11898
+ function xmlEntry(block) {
11899
+ const title = clean(child(block, "title")) ?? "";
11900
+ const summary = clean(child(block, "summary") ?? child(block, "description") ?? child(block, "content") ?? child(block, "content:encoded"));
11901
+ const link22 = atomLink(block) ?? clean(child(block, "link"));
11902
+ const at = firstDate([child(block, "updated"), child(block, "modified"), child(block, "issued"), child(block, "published"), child(block, "pubDate"), child(block, "dc:date")]);
11903
+ const id = clean(child(block, "id")) ?? clean(child(block, "guid")) ?? link22 ?? (title && at ? `${title}@${at}` : title);
11904
+ if (!id) return void 0;
11905
+ return compact({ id, title, summary, author: xmlAuthor(block), link: link22, at });
11906
+ }
11907
+ function xmlAuthor(block) {
11908
+ const author = child(block, "author");
11909
+ if (author && /<(name|email)[\s>]/i.test(author)) {
11910
+ const name = clean(child(author, "name"));
11911
+ const email = clean(child(author, "email"));
11912
+ if (name && email) return `${name} <${email}>`;
11913
+ return name ?? email;
11914
+ }
11915
+ return clean(author) ?? clean(child(block, "dc:creator"));
11916
+ }
11917
+ function atomLink(block) {
11918
+ let fallback;
11919
+ for (const match of block.matchAll(/<link\b([^>]*?)\/?>/gi)) {
11920
+ const attributes = match[1] ?? "";
11921
+ const href = attributes.match(/\bhref\s*=\s*["']([^"']*)["']/i)?.[1];
11922
+ if (!href) continue;
11923
+ const rel = attributes.match(/\brel\s*=\s*["']([^"']*)["']/i)?.[1];
11924
+ if (!rel || rel === "alternate") return decodeEntities(href);
11925
+ fallback ??= decodeEntities(href);
11926
+ }
11927
+ return fallback;
11928
+ }
11929
+ function parseJsonFeed(text) {
11930
+ const data = JSON.parse(text);
11931
+ let items;
11932
+ if (Array.isArray(data)) items = data;
11933
+ else if (Array.isArray(data?.items)) items = data.items;
11934
+ else if (Array.isArray(data?.entries)) items = data.entries;
11935
+ if (!items) throw new Error("the JSON has no items or entries list");
11936
+ const entries = [];
11937
+ for (const item of items) {
11938
+ if (!item || typeof item !== "object") continue;
11939
+ const link22 = text_(item.url ?? item.link ?? item.html_url);
11940
+ const title = clean(text_(item.title ?? item.subject ?? item.name)) ?? "";
11941
+ const at = firstDate([item.date_published, item.date_modified, item.updated, item.published, item.date, item.created_at]);
11942
+ const id = text_(item.id ?? item.guid) ?? link22 ?? (title && at ? `${title}@${at}` : title);
11943
+ if (!id) continue;
11944
+ const summary = clean(text_(item.summary ?? item.content_text ?? item.description ?? item.content_html ?? item.body ?? item.text));
11945
+ const author = clean(text_(item.author?.name ?? item.authors?.[0]?.name ?? item.author ?? item.from));
11946
+ entries.push(compact({ id, title, summary, author, link: link22, at }));
11947
+ }
11948
+ return entries;
11949
+ }
11950
+ function elements(xml, tag) {
11951
+ const pattern = new RegExp(`<${tag}(?:\\s[^>]*)?>([\\s\\S]*?)</${tag}>`, "gi");
11952
+ return [...xml.matchAll(pattern)].map((match) => match[1] ?? "");
11953
+ }
11954
+ function child(xml, tag) {
11955
+ return elements(xml, tag)[0];
11956
+ }
11957
+ function clean(value) {
11958
+ if (value === void 0) return void 0;
11959
+ const unwrapped = value.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, "$1");
11960
+ const decoded = decodeEntities(stripTags(unwrapped));
11961
+ const text = stripTags(decoded).replace(INVISIBLE, "").replace(/\s+/g, " ").trim();
11962
+ return text || void 0;
11963
+ }
11964
+ function stripTags(value) {
11965
+ return value.replace(/<[^>]*>/g, " ");
11966
+ }
11967
+ function decodeEntities(value) {
11968
+ return value.replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, (entity, name) => {
11969
+ if (name[0] === "#") {
11970
+ const code = name[1]?.toLowerCase() === "x" ? Number.parseInt(name.slice(2), 16) : Number.parseInt(name.slice(1), 10);
11971
+ return Number.isFinite(code) && code <= 1114111 ? String.fromCodePoint(code) : entity;
11972
+ }
11973
+ return ENTITIES[name.toLowerCase()] ?? entity;
11974
+ });
11975
+ }
11976
+ function firstDate(values) {
11977
+ for (const value of values) {
11978
+ const raw = typeof value === "string" ? clean(value) : void 0;
11979
+ if (!raw) continue;
11980
+ const time = Date.parse(raw);
11981
+ if (!Number.isNaN(time)) return new Date(time).toISOString();
11982
+ }
11983
+ return void 0;
11984
+ }
11985
+ function text_(value) {
11986
+ if (typeof value === "string" && value.trim()) return value.trim();
11987
+ if (typeof value === "number") return String(value);
11988
+ return void 0;
11989
+ }
11990
+ function compact(entry) {
11991
+ const result = { id: entry.id, title: entry.title };
11992
+ if (entry.summary) result.summary = entry.summary;
11993
+ if (entry.author) result.author = entry.author;
11994
+ if (entry.link) result.link = entry.link;
11995
+ if (entry.at) result.at = entry.at;
11996
+ return result;
11997
+ }
11998
+ var DEFAULT_YAB_COMMAND = "/Applications/yab.app/Contents/MacOS/yab";
11999
+ var TIMEOUT_MS = 45e3;
12000
+ async function fetchThroughYab(url, space) {
12001
+ const args = { url, html: true };
12002
+ if (space) args.space = space;
12003
+ return parseYabFetch(await callYabTool("fetch", args));
12004
+ }
12005
+ function parseYabFetch(text) {
12006
+ const split = text.indexOf("\n\n");
12007
+ const head = split >= 0 ? text.slice(0, split) : text;
12008
+ const body = split >= 0 ? text.slice(split + 2) : "";
12009
+ const [status = "", type = "", ...rest] = head.split(" \xB7 ");
12010
+ const code = Number(status.trim());
12011
+ if (!Number.isInteger(code) || code <= 0) throw new Error(`yab fetch gave an unexpected answer: ${head.slice(0, 200)}`);
12012
+ return { status: code, type: type.trim(), url: rest.join(" \xB7 ").trim(), body };
12013
+ }
12014
+ function callYabTool(name, args) {
12015
+ const command = process.env.SOURCEFED_YAB_COMMAND || DEFAULT_YAB_COMMAND;
12016
+ return new Promise((resolve, reject) => {
12017
+ const child2 = spawn(command, ["mcp"], { stdio: ["pipe", "pipe", "pipe"] });
12018
+ let buffer = "";
12019
+ let stderr = "";
12020
+ let settled = false;
12021
+ const finish = (error, value = "") => {
12022
+ if (settled) return;
12023
+ settled = true;
12024
+ clearTimeout(timer);
12025
+ child2.kill();
12026
+ if (error) reject(error);
12027
+ else resolve(value);
12028
+ };
12029
+ const send = (message) => {
12030
+ child2.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", ...message })}
12031
+ `);
12032
+ };
12033
+ const timer = setTimeout(() => finish(new Error(`yab ${name} timed out after ${TIMEOUT_MS / 1e3}s`)), TIMEOUT_MS);
12034
+ child2.on("error", (error) => finish(new Error(`yab mcp could not start (${command}): ${error.message}`)));
12035
+ child2.on("exit", (code) => {
12036
+ const detail = stderr.trim() ? `: ${stderr.trim().slice(0, 300)}` : "";
12037
+ finish(new Error(`yab mcp exited (${code ?? "signal"}) before answering${detail}`));
12038
+ });
12039
+ child2.stdin.on("error", () => {
12040
+ });
12041
+ child2.stderr.setEncoding("utf8");
12042
+ child2.stderr.on("data", (chunk) => {
12043
+ stderr += chunk;
12044
+ });
12045
+ child2.stdout.setEncoding("utf8");
12046
+ child2.stdout.on("data", (chunk) => {
12047
+ buffer += chunk;
12048
+ let newline = buffer.indexOf("\n");
12049
+ while (newline >= 0) {
12050
+ const line = buffer.slice(0, newline).trim();
12051
+ buffer = buffer.slice(newline + 1);
12052
+ newline = buffer.indexOf("\n");
12053
+ if (!line) continue;
12054
+ let message;
12055
+ try {
12056
+ message = JSON.parse(line);
12057
+ } catch {
12058
+ continue;
12059
+ }
12060
+ if (message.id === 1) {
12061
+ if (message.error) return finish(new Error(`yab mcp initialize failed: ${message.error.message}`));
12062
+ send({ method: "notifications/initialized" });
12063
+ send({ id: 2, method: "tools/call", params: { name, arguments: args } });
12064
+ } else if (message.id === 2) {
12065
+ if (message.error) return finish(new Error(`yab ${name} failed: ${message.error.message}`));
12066
+ const content = Array.isArray(message.result?.content) ? message.result.content : [];
12067
+ const text = content.filter((part) => part?.type === "text").map((part) => String(part.text)).join("\n");
12068
+ if (message.result?.isError) return finish(new Error(`yab ${name} failed: ${text.slice(0, 300)}`));
12069
+ return finish(void 0, text);
12070
+ }
12071
+ }
12072
+ });
12073
+ send({
12074
+ id: 1,
12075
+ method: "initialize",
12076
+ params: { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "sourcefed", version: "0.3" } }
12077
+ });
12078
+ });
12079
+ }
12080
+ async function pollYab(source, cursorRaw, fetchPage = fetchThroughYab) {
12081
+ const page = await fetchPage(source.url, source.space);
12082
+ if (page.status >= 400) {
12083
+ const hint = page.status === 401 || page.status === 403 ? "; sign in to the site in Yab" : "";
12084
+ throw new Error(`yab fetch of ${source.url} answered ${page.status}${hint}`);
12085
+ }
12086
+ return { ...feedEvents(source, parseFeed(page.body, page.type), cursorRaw), terminal: false };
12087
+ }
12088
+ var yabPollMonitor = new PollMonitor4({
12089
+ run: async (source, cursor) => {
12090
+ const result = await pollYab(source, cursor);
12091
+ return {
12092
+ cursor: result.cursor,
12093
+ events: result.events.map((event) => toMonitorEvent4(event, source)),
12094
+ terminal: result.terminal
12095
+ };
12096
+ }
12097
+ });
12098
+ var YabMonitor = class extends Monitor4 {
12099
+ poll = yabPollMonitor;
12100
+ constructor() {
12101
+ super({ type: "yab", schema: YabSourceSchema });
12102
+ }
12103
+ key = (source) => `yab:${source.space ?? ""}:${source.url}`;
12104
+ icon = "\u{F059F}";
12105
+ label = (source) => new URL(source.url).hostname;
12106
+ detail = (source) => ` ${shortUrl(source.url)}${source.match || source.exclude ? " \xB7 filtered" : ""}`;
12107
+ describe = (source) => `Yab feed ${shortUrl(source.url)}${source.space ? ` (${source.space})` : ""}`;
12108
+ build(input) {
12109
+ if (!input.url) return { error: "url is required for a yab monitor" };
12110
+ let url;
12111
+ try {
12112
+ url = new URL(input.url);
12113
+ } catch {
12114
+ return { error: "url must be a valid http(s) URL" };
12115
+ }
12116
+ if (url.protocol !== "https:" && url.protocol !== "http:") return { error: "url must be a valid http(s) URL" };
12117
+ for (const [key, pattern] of [["match", input.match], ["exclude", input.exclude]]) {
12118
+ if (!pattern) continue;
12119
+ try {
12120
+ new RegExp(pattern, "i");
12121
+ } catch {
12122
+ return { error: `${key} must be a valid regular expression` };
12123
+ }
12124
+ }
12125
+ const source = { type: "yab", url: url.href };
12126
+ if (input.space) source.space = input.space;
12127
+ if (input.match) source.match = input.match;
12128
+ if (input.exclude) source.exclude = input.exclude;
12129
+ return source;
12130
+ }
12131
+ };
12132
+ function shortUrl(href) {
12133
+ const url = new URL(href);
12134
+ return `${url.hostname}${url.pathname === "/" ? "" : url.pathname}`;
12135
+ }
12136
+ var SOURCE_MAP = {
12137
+ jira: new JiraMonitor(),
12138
+ github: new GithubMonitor(),
12139
+ slack: new SlackMonitor(),
12140
+ yab: new YabMonitor()
12141
+ };
12142
+ var SOURCE_TYPES = Object.keys(SOURCE_MAP);
12143
+ function sourceDefinition(source) {
12144
+ return SOURCE_MAP[source.type];
12145
+ }
12146
+ function isSource(input) {
12147
+ return typeof input.type === "string";
12148
+ }
12149
+ function sourceForInput(type, input) {
12150
+ const source = SOURCE_MAP[type];
12151
+ return source.build(input);
12152
+ }
12153
+ function sourceForWebhookPath(pathname) {
12154
+ const sources = Object.values(SOURCE_MAP);
12155
+ for (const source of sources) {
12156
+ if (source.webhook?.path === pathname) return source;
12157
+ }
12158
+ return void 0;
12159
+ }
12160
+ var DAEMON_ENVIRONMENT = [
12161
+ "PATH",
12162
+ "HOME",
12163
+ "USER",
12164
+ "TMPDIR",
12165
+ "LANG",
12166
+ "XDG_CONFIG_HOME",
12167
+ "XDG_STATE_HOME",
12168
+ "ATLASSIAN_EMAIL",
12169
+ "ATLASSIAN_API_KEY",
12170
+ "GH_TOKEN",
12171
+ "GITHUB_TOKEN",
12172
+ "SOURCEFED_JIRA_BASE_URL",
12173
+ "SOURCEFED_JIRA_TERMINAL_STATUS",
12174
+ "SOURCEFED_STATE_DIR",
12175
+ "SOURCEFED_DAEMON_TOKEN",
12176
+ "SOURCEFED_SLACK_TOKEN",
12177
+ "SOURCEFED_GITHUB_WEBHOOK_SECRET",
12178
+ "SOURCEFED_SLACK_SIGNING_SECRET",
12179
+ "SOURCEFED_ENABLE_WEBHOOKS",
12180
+ "SOURCEFED_WEBHOOK_HOST",
12181
+ "SOURCEFED_WEBHOOK_PORT"
12182
+ ];
12183
+ function daemonEnvironment(host) {
12184
+ const environment = Object.fromEntries(
12185
+ DAEMON_ENVIRONMENT.flatMap((name) => process.env[name] === void 0 ? [] : [[name, process.env[name]]])
12186
+ );
12187
+ if (host) environment.SOURCEFED_STATE_DIR ??= path6.join(process.env.XDG_STATE_HOME ?? path6.join(os6.homedir(), ".local", "state"), "sourcefed", host);
12188
+ return environment;
12189
+ }
12190
+ async function serveHttp(options) {
12191
+ const active = /* @__PURE__ */ new Set();
12192
+ const server = createServer((incoming, outgoing) => {
12193
+ active.add(outgoing);
12194
+ outgoing.on("close", () => active.delete(outgoing));
12195
+ void handle(incoming, outgoing, options.handler);
12196
+ });
12197
+ server.requestTimeout = 0;
12198
+ server.on("error", (error) => {
12199
+ console.error(`[sourcefed] http server error: ${error instanceof Error ? error.message : String(error)}`);
12200
+ });
12201
+ server.on("clientError", (_error, socket) => {
12202
+ socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
12203
+ });
12204
+ await new Promise((resolve, reject) => {
12205
+ server.once("error", reject);
12206
+ server.listen(options.port, options.hostname, () => resolve());
12207
+ });
12208
+ const address = server.address();
12209
+ const port = typeof address === "object" && address ? address.port : options.port;
12210
+ return {
12211
+ port,
12212
+ async stop() {
12213
+ for (const outgoing of active) {
12214
+ outgoing.destroy();
12215
+ }
12216
+ active.clear();
12217
+ server.closeIdleConnections?.();
12218
+ await new Promise((resolve) => {
12219
+ server.close(() => resolve());
12220
+ });
12221
+ }
12222
+ };
12223
+ }
12224
+ async function handle(incoming, outgoing, handler) {
12225
+ try {
12226
+ const response = await handler(toRequest(incoming));
12227
+ await writeResponse(outgoing, response);
12228
+ } catch (error) {
12229
+ console.error(`[sourcefed] request failed: ${error instanceof Error ? error.message : String(error)}`);
12230
+ if (!outgoing.headersSent) outgoing.writeHead(500, { "content-type": "text/plain" });
12231
+ outgoing.end("internal error");
12232
+ }
12233
+ }
12234
+ function toRequest(incoming) {
12235
+ const url = new URL(incoming.url ?? "/", `http://${incoming.headers.host ?? "localhost"}`);
12236
+ const method = incoming.method ?? "GET";
12237
+ const hasBody = method !== "GET" && method !== "HEAD";
12238
+ const headers = new Headers();
12239
+ for (const [name, value] of Object.entries(incoming.headers)) {
12240
+ if (value === void 0) continue;
12241
+ if (Array.isArray(value)) {
12242
+ for (const item of value) headers.append(name, item);
12243
+ } else {
12244
+ headers.set(name, value);
12245
+ }
12246
+ }
12247
+ const init = {
12248
+ method,
12249
+ headers,
12250
+ body: hasBody ? Readable.toWeb(incoming) : void 0,
12251
+ duplex: "half"
12252
+ };
12253
+ return new Request(url, init);
12254
+ }
12255
+ async function writeResponse(outgoing, response) {
12256
+ outgoing.writeHead(response.status, Object.fromEntries(response.headers.entries()));
12257
+ if (!response.body) {
12258
+ outgoing.end();
12259
+ return;
12260
+ }
12261
+ const stream = Readable.fromWeb(response.body);
12262
+ stream.on("error", (error) => {
12263
+ console.error(`[sourcefed] response stream error: ${error instanceof Error ? error.message : String(error)}`);
12264
+ });
12265
+ await new Promise((resolve) => {
12266
+ let finished = false;
12267
+ const done = () => {
12268
+ if (finished) return;
12269
+ finished = true;
12270
+ resolve();
12271
+ };
12272
+ outgoing.on("finish", done);
12273
+ outgoing.on("close", () => {
12274
+ stream.unpipe(outgoing);
12275
+ stream.destroy();
12276
+ done();
12277
+ });
12278
+ stream.pipe(outgoing);
12279
+ });
12280
+ }
12281
+ function defaultDaemonUrl() {
12282
+ const port = process.env.SOURCEFED_DAEMON_PORT ?? 18787;
12283
+ return `http://127.0.0.1:${port}`;
12284
+ }
12285
+ function daemonCommand(cliEntryPath) {
12286
+ return {
12287
+ command: nodeExecutable(),
12288
+ args: [cliEntryPath, "daemon"]
12289
+ };
12290
+ }
12291
+ function nodeExecutable() {
12292
+ const base = path7.basename(process.execPath);
12293
+ if (base.includes("node") || base.includes("bun")) return process.execPath;
12294
+ return "node";
12295
+ }
12296
+ async function spawnLocalDaemon(options) {
11429
12297
  const port = options.port ?? Number(process.env.SOURCEFED_DAEMON_PORT ?? 18787);
11430
12298
  const url = `http://127.0.0.1:${port}`;
11431
12299
  const token = options.env?.SOURCEFED_DAEMON_TOKEN ?? process.env.SOURCEFED_DAEMON_TOKEN;
11432
12300
  if (await daemonReachable(url, 750, token)) return { url };
11433
- const proc = spawn(options.command, [...options.args, "--port", String(port)], {
12301
+ const proc = spawn2(options.command, [...options.args, "--port", String(port)], {
11434
12302
  stdio: ["ignore", "ignore", "ignore"],
11435
12303
  detached: true,
11436
12304
  env: { ...process.env, ...options.env }
@@ -11802,164 +12670,225 @@ function parseDaemonFrame(line) {
11802
12670
  return void 0;
11803
12671
  }
11804
12672
  }
12673
+ var DaemonEventStream = class {
12674
+ constructor(url, headers, onEvents, acknowledge, onClose) {
12675
+ this.url = url;
12676
+ this.headers = headers;
12677
+ this.onEvents = onEvents;
12678
+ this.acknowledge = acknowledge;
12679
+ this.onClose = onClose;
12680
+ }
12681
+ controller = new AbortController();
12682
+ subscribed = Promise.withResolvers();
12683
+ stream;
12684
+ delivering = Promise.resolve();
12685
+ closing;
12686
+ ready = false;
12687
+ failedDelivery = false;
12688
+ async start(signal) {
12689
+ const abort = () => {
12690
+ void this.close();
12691
+ };
12692
+ signal?.addEventListener("abort", abort, { once: true });
12693
+ const setup = withTimeout(this.subscribed.promise, 15e3, `sourcefed event stream did not subscribe at ${this.url}`);
12694
+ if (signal?.aborted) abort();
12695
+ const running = this.run();
12696
+ void running.finally(() => signal?.removeEventListener("abort", abort));
12697
+ try {
12698
+ await setup;
12699
+ } catch (error) {
12700
+ await this.close();
12701
+ throw error;
12702
+ }
12703
+ }
12704
+ close() {
12705
+ if (!this.closing) {
12706
+ this.subscribed.reject(new Error("sourcefed event stream closed"));
12707
+ if (!this.ready) this.controller.abort();
12708
+ this.closing = this.drain();
12709
+ }
12710
+ return this.closing;
12711
+ }
12712
+ async drain() {
12713
+ try {
12714
+ await withTimeout(this.delivering, 15e3, "sourcefed event delivery did not drain");
12715
+ } catch (error) {
12716
+ console.error(`[sourcefed] closing event stream: ${String(error)}`);
12717
+ } finally {
12718
+ this.controller.abort();
12719
+ this.stream?.abort();
12720
+ this.onClose();
12721
+ }
12722
+ }
12723
+ async run() {
12724
+ let consecutiveFailures = 0;
12725
+ while (!this.controller.signal.aborted) {
12726
+ this.failedDelivery = false;
12727
+ try {
12728
+ await this.read();
12729
+ consecutiveFailures = 0;
12730
+ } catch (error) {
12731
+ if (!this.controller.signal.aborted && !this.failedDelivery && ++consecutiveFailures === 1) {
12732
+ console.error(`[sourcefed] event stream ended: ${String(error)}`);
12733
+ }
12734
+ }
12735
+ await this.waitForDelivery();
12736
+ if (!this.controller.signal.aborted) await pause(500, this.controller.signal);
12737
+ }
12738
+ }
12739
+ async read() {
12740
+ const controller = new AbortController();
12741
+ const abort = () => controller.abort();
12742
+ this.stream = controller;
12743
+ this.controller.signal.addEventListener("abort", abort, { once: true });
12744
+ let reader;
12745
+ try {
12746
+ this.controller.signal.throwIfAborted();
12747
+ const response = await fetch(this.url, { signal: controller.signal, headers: this.headers });
12748
+ if (!response.ok || !response.body) {
12749
+ await response.body?.cancel();
12750
+ throw new Error(`event stream failed: ${response.status}`);
12751
+ }
12752
+ reader = response.body.getReader();
12753
+ const decoder = new TextDecoder();
12754
+ let buffer = "";
12755
+ while (!controller.signal.aborted) {
12756
+ const { done, value } = await reader.read();
12757
+ if (done) return;
12758
+ buffer += decoder.decode(value, { stream: true });
12759
+ const frames = buffer.split("\n\n");
12760
+ buffer = frames.pop() ?? "";
12761
+ for (const chunk of frames) await this.frame(chunk);
12762
+ }
12763
+ } finally {
12764
+ await reader?.cancel().catch(() => void 0);
12765
+ reader?.releaseLock();
12766
+ this.controller.signal.removeEventListener("abort", abort);
12767
+ if (this.stream === controller) this.stream = void 0;
12768
+ }
12769
+ }
12770
+ async frame(chunk) {
12771
+ if (this.closing || this.controller.signal.aborted) return;
12772
+ for (const line of chunk.split("\n")) {
12773
+ if (!line.startsWith("data: ")) continue;
12774
+ const frame = parseDaemonFrame(line.slice(6));
12775
+ if (!frame || !("type" in frame)) continue;
12776
+ if (frame.type === "subscribed") {
12777
+ this.ready = true;
12778
+ this.subscribed.resolve();
12779
+ }
12780
+ if (frame.type === "event" && frame.events.length > 0) {
12781
+ this.deliver(frame.events);
12782
+ await this.waitForDelivery();
12783
+ }
12784
+ }
12785
+ }
12786
+ deliver(events) {
12787
+ this.delivering = this.delivering.then(async () => {
12788
+ if (this.failedDelivery || this.controller.signal.aborted) return;
12789
+ try {
12790
+ await this.onEvents(events);
12791
+ await this.acknowledge(events, this.controller.signal);
12792
+ } catch (error) {
12793
+ if (!this.controller.signal.aborted) console.error(`[sourcefed] event delivery failed: ${String(error)}`);
12794
+ this.failedDelivery = true;
12795
+ this.stream?.abort();
12796
+ }
12797
+ });
12798
+ }
12799
+ async waitForDelivery() {
12800
+ if (this.controller.signal.aborted) return;
12801
+ const stopped = Promise.withResolvers();
12802
+ const abort = () => stopped.resolve();
12803
+ this.controller.signal.addEventListener("abort", abort, { once: true });
12804
+ try {
12805
+ await Promise.race([this.delivering, stopped.promise]);
12806
+ } finally {
12807
+ this.controller.signal.removeEventListener("abort", abort);
12808
+ }
12809
+ }
12810
+ };
12811
+ function pause(ms, signal) {
12812
+ return new Promise((resolve) => {
12813
+ const finish = () => {
12814
+ clearTimeout(timer);
12815
+ signal.removeEventListener("abort", finish);
12816
+ resolve();
12817
+ };
12818
+ const timer = setTimeout(finish, ms);
12819
+ signal.addEventListener("abort", finish, { once: true });
12820
+ if (signal.aborted) finish();
12821
+ });
12822
+ }
11805
12823
  async function connectDaemonClient(options) {
11806
12824
  const url = options.url ?? process.env.SOURCEFED_DAEMON_URL ?? defaultDaemonUrl();
11807
12825
  return new HttpDaemonClient(url, options.token ?? process.env.SOURCEFED_DAEMON_TOKEN);
11808
12826
  }
11809
12827
  var HttpDaemonClient = class {
11810
- baseURL;
11811
- token;
11812
- router = new RequestRouter();
11813
- listeners = /* @__PURE__ */ new Map();
11814
- streams = /* @__PURE__ */ new Set();
11815
12828
  constructor(baseURL, token) {
11816
- this.baseURL = baseURL.replace(/\/+$/, "");
11817
12829
  this.token = token;
12830
+ this.baseURL = baseURL.replace(/\/+$/, "");
11818
12831
  }
12832
+ baseURL;
12833
+ streams = /* @__PURE__ */ new Set();
12834
+ lifetime = new AbortController();
12835
+ cursor = 0;
12836
+ closing;
11819
12837
  headers() {
11820
12838
  return this.token ? { authorization: `Bearer ${this.token}` } : {};
11821
12839
  }
11822
- async request(method, params) {
11823
- const id = this.router.nextID();
11824
- const promise = this.router.register(id);
12840
+ async request(method, params, signal = this.lifetime.signal) {
12841
+ if (this.closing && signal === this.lifetime.signal) throw new Error("daemon closed");
12842
+ signal.throwIfAborted();
12843
+ const response = await fetch(`${this.baseURL}/rpc`, {
12844
+ method: "POST",
12845
+ headers: { "content-type": "application/json", ...this.headers() },
12846
+ body: JSON.stringify({ id: ++this.cursor, method, params }),
12847
+ signal: AbortSignal.any([signal, this.lifetime.signal, AbortSignal.timeout(15e3)])
12848
+ });
12849
+ const frame = await response.json();
12850
+ if (!response.ok || frame.error) throw new Error(frame.error ?? `daemon request failed: ${response.status}`);
12851
+ return frame.result;
12852
+ }
12853
+ async subscribe(target, onEvents, options) {
12854
+ if (this.closing) throw new Error("daemon closed");
12855
+ this.lifetime.signal.throwIfAborted();
12856
+ const stream = new DaemonEventStream(
12857
+ `${this.baseURL}/events?target=${encodeTarget(target)}`,
12858
+ this.headers(),
12859
+ onEvents,
12860
+ (events, signal) => this.acknowledge(target, events, signal),
12861
+ () => this.streams.delete(stream)
12862
+ );
12863
+ this.streams.add(stream);
11825
12864
  try {
11826
- const response = await fetch(`${this.baseURL}/rpc`, {
11827
- method: "POST",
11828
- headers: { "content-type": "application/json", ...this.headers() },
11829
- body: JSON.stringify({ id, method, params })
11830
- });
11831
- const frame = await response.json();
11832
- if (!response.ok || frame.error) throw new Error(frame.error ?? `daemon request failed: ${response.status}`);
11833
- this.router.settle(id, { result: frame.result });
12865
+ await stream.start(options?.signal);
12866
+ return { close: () => stream.close() };
11834
12867
  } catch (error) {
11835
- this.router.settle(id, { error: error instanceof Error ? error.message : String(error) });
12868
+ await stream.close();
12869
+ throw error;
11836
12870
  }
11837
- return promise;
11838
12871
  }
11839
- async subscribe(target, onEvents) {
11840
- const key = targetKey(target);
11841
- let callbacks = this.listeners.get(key);
11842
- if (!callbacks) {
11843
- callbacks = /* @__PURE__ */ new Set();
11844
- this.listeners.set(key, callbacks);
11845
- }
11846
- callbacks.add(onEvents);
11847
- const controller = new AbortController();
11848
- this.streams.add(controller);
11849
- const url = `${this.baseURL}/events?target=${encodeTarget(target)}`;
11850
- let markSubscribed;
11851
- const subscribed = new Promise((resolve) => {
11852
- markSubscribed = () => resolve();
11853
- });
11854
- let delivering = Promise.resolve();
11855
- let activeStream;
11856
- let retryStream = false;
11857
- const deliver = (events) => {
11858
- if (!callbacks?.has(onEvents) || events.length === 0) return Promise.resolve();
11859
- delivering = delivering.then(async () => {
11860
- try {
11861
- await onEvents(events);
11862
- } catch (error) {
11863
- console.error(`[sourcefed] event delivery failed: ${error instanceof Error ? error.message : String(error)}`);
11864
- retryStream = true;
11865
- activeStream?.abort();
11866
- return;
11867
- }
11868
- await acknowledge(events);
11869
- }).catch((error) => {
11870
- console.error(`[sourcefed] event delivery failed: ${error instanceof Error ? error.message : String(error)}`);
11871
- });
11872
- return delivering;
11873
- };
11874
- const acknowledge = async (events) => {
11875
- let attempt = 0;
11876
- while (!controller.signal.aborted && callbacks?.has(onEvents)) {
11877
- try {
11878
- await this.request("monitor.ack", { target, eventIDs: events.map((event) => event.id) });
11879
- return;
11880
- } catch (error) {
11881
- attempt += 1;
11882
- if (attempt === 3) {
11883
- console.error(`[sourcefed] event acknowledgement still failing; retrying without repeating delivery: ${error instanceof Error ? error.message : String(error)}`);
11884
- }
11885
- await sleep(Math.min(250 * 2 ** (attempt - 1), 4e3));
11886
- }
11887
- }
11888
- };
11889
- const runStream = async () => {
11890
- const streamController = new AbortController();
11891
- const closeStream = () => streamController.abort();
11892
- activeStream = streamController;
11893
- controller.signal.addEventListener("abort", closeStream, { once: true });
12872
+ async acknowledge(target, events, signal) {
12873
+ let attempt = 0;
12874
+ while (!signal.aborted) {
11894
12875
  try {
11895
- const response = await fetch(url, { signal: streamController.signal, headers: this.headers() });
11896
- if (!response.ok || !response.body) throw new Error(`event stream failed: ${response.status}`);
11897
- const reader = response.body.getReader();
11898
- const decoder = new TextDecoder();
11899
- let buffer = "";
11900
- while (true) {
11901
- const { done, value } = await reader.read();
11902
- if (done) break;
11903
- buffer += decoder.decode(value, { stream: true });
11904
- const frames = buffer.split("\n\n");
11905
- buffer = frames.pop() ?? "";
11906
- for (const chunk of frames) {
11907
- for (const line of chunk.split("\n")) {
11908
- if (!line.startsWith("data: ")) continue;
11909
- const frame = parseDaemonFrame(line.slice(6));
11910
- if (!frame || !("type" in frame)) continue;
11911
- if (frame.type === "subscribed") markSubscribed();
11912
- if (frame.type === "event") void deliver(frame.events);
11913
- }
11914
- }
11915
- }
11916
- consecutiveFailures = 0;
12876
+ await this.request("monitor.ack", { target, eventIDs: events.map((event) => event.id) }, signal);
12877
+ return;
11917
12878
  } catch (error) {
11918
- if (!controller.signal.aborted && !retryStream) {
11919
- consecutiveFailures += 1;
11920
- if (consecutiveFailures === 1) {
11921
- console.error(`[sourcefed] event stream ended: ${error instanceof Error ? error.message : String(error)}`);
11922
- }
12879
+ if (++attempt === 3) {
12880
+ console.error(`[sourcefed] event acknowledgement still failing; retrying without repeating delivery: ${String(error)}`);
11923
12881
  }
11924
- } finally {
11925
- controller.signal.removeEventListener("abort", closeStream);
11926
- if (activeStream === streamController) activeStream = void 0;
11927
- retryStream = false;
11928
- }
11929
- };
11930
- let consecutiveFailures = 0;
11931
- void (async () => {
11932
- while (!controller.signal.aborted && callbacks?.has(onEvents)) {
11933
- await runStream();
11934
- if (controller.signal.aborted) break;
11935
- await sleep(500);
12882
+ await pause(Math.min(250 * 2 ** Math.min(attempt - 1, 4), 4e3), signal);
11936
12883
  }
11937
- })();
11938
- try {
11939
- await withTimeout(subscribed, 15e3, `sourcefed event stream did not subscribe at ${url}`);
11940
- } catch (error) {
11941
- const callbacks2 = this.listeners.get(key);
11942
- callbacks2?.delete(onEvents);
11943
- if (callbacks2 && callbacks2.size === 0) this.listeners.delete(key);
11944
- controller.abort();
11945
- this.streams.delete(controller);
11946
- throw error;
11947
12884
  }
11948
- return {
11949
- close: async () => {
11950
- const callbacks2 = this.listeners.get(key);
11951
- callbacks2?.delete(onEvents);
11952
- if (callbacks2 && callbacks2.size === 0) this.listeners.delete(key);
11953
- controller.abort();
11954
- this.streams.delete(controller);
11955
- }
11956
- };
11957
12885
  }
11958
- async close() {
11959
- for (const controller of this.streams) controller.abort();
11960
- this.streams.clear();
11961
- this.router.rejectAll(new Error("daemon closed"));
11962
- this.listeners.clear();
12886
+ close() {
12887
+ this.closing ??= Promise.all([...this.streams].map((stream) => stream.close())).then(() => {
12888
+ this.lifetime.abort();
12889
+ this.streams.clear();
12890
+ });
12891
+ return this.closing;
11963
12892
  }
11964
12893
  };
11965
12894
  async function dispatchDaemonRequest(daemon, method, params) {
@@ -12005,7 +12934,7 @@ function createCreateInput(params) {
12005
12934
  name: params.name,
12006
12935
  sourceType: params.sourceType
12007
12936
  };
12008
- for (const key of ["issueKey", "repo", "channelId", "threadTs", "threadUrl"]) {
12937
+ for (const key of ["issueKey", "repo", "channelId", "threadTs", "threadUrl", "url", "space", "match", "exclude"]) {
12009
12938
  if (typeof params[key] === "string") input[key] = params[key];
12010
12939
  }
12011
12940
  if (typeof params.prNumber === "number") input.prNumber = params.prNumber;