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