@xiaoso/dsh-tool-plus 0.1.16 → 0.1.17-beta.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 (109) hide show
  1. package/lib/{abort-DZ54CaKU.mjs → abort-BTblp0Rt.mjs} +2 -2
  2. package/lib/{alibaba-coding-plan-DODpkcqi.mjs → alibaba-coding-plan-t3R4YKCB.mjs} +3 -3
  3. package/lib/{alibaba-token-plan-C6lpKCda.mjs → alibaba-token-plan-CO4djG1y.mjs} +4 -4
  4. package/lib/{alibaba-token-plan-CHGyWOfX.mjs → alibaba-token-plan-CUjYJX0-.mjs} +1 -1
  5. package/lib/{anthropic-Dv_GGX6g.mjs → anthropic-nf7w6so1.mjs} +48 -21
  6. package/lib/{api-key-validation-MnMf_ihX.mjs → api-key-validation-C_tZ7Y9a.mjs} +2 -2
  7. package/lib/behavior-BwvTUtag.mjs +111 -0
  8. package/lib/{browser-render-BZXt548F.mjs → browser-render-BQaEVK_n.mjs} +4 -4
  9. package/lib/{reference-CtvM4zLU.mjs → bundled-references-CrQ4dQcT.mjs} +57 -4
  10. package/lib/cascade-BWjRTD1q.mjs +30265 -0
  11. package/lib/{cline-pass-BT9CBEOj.mjs → cline-pass-Bjm-O8GG.mjs} +2 -2
  12. package/lib/cloudflare-CKXRJ0l9.mjs +37 -0
  13. package/lib/{cloudflare-ai-gateway-DReN6ohJ.mjs → cloudflare-ai-gateway-BpnBSjwV.mjs} +8 -4
  14. package/lib/cloudflare-workers-ai-odj9XswL.mjs +32 -0
  15. package/lib/collapse-_nkb2dn7.mjs +1945 -0
  16. package/lib/{coreweave-C82HrLpb.mjs → coreweave-CGDZOD8-.mjs} +1 -1
  17. package/lib/{coreweave-C68UgRQO.mjs → coreweave-DwffcgW5.mjs} +4 -4
  18. package/lib/cursor-BgOuV7Qf.mjs +794 -0
  19. package/lib/{cursor-_gHHq-Dq.mjs → cursor-CF1iHHbv.mjs} +68 -19
  20. package/lib/{cursor-proto-Cr_WEMuv.mjs → cursor-proto-BuNTjX3L.mjs} +823 -23
  21. package/lib/{devin-QpfTSl9H.mjs → devin-7OEeEb80.mjs} +112 -31
  22. package/lib/{devin-proto-DYhp4Ty6.mjs → devin-proto-C-QreeAv.mjs} +71 -5
  23. package/lib/{dom-DG3sPESc.mjs → dom-BmbZv4v9.mjs} +598 -182
  24. package/lib/{error-O63pC8zg.mjs → error-8LVo7tug.mjs} +725 -104
  25. package/lib/factory-droid-ChhmsGWb.mjs +71 -0
  26. package/lib/{fs-promises-shim-B2YFWkcd.mjs → fs-promises-shim-CANAxFWh.mjs} +10 -1
  27. package/lib/{github-copilot-BMEcw8N1.mjs → github-copilot-QwevdT30.mjs} +4 -4
  28. package/lib/{github-copilot-headers-DnjGEbko.mjs → github-copilot-headers-CAUZ0rUD.mjs} +138 -26
  29. package/lib/{gitlab-duo-DnHqJjFY.mjs → gitlab-duo-DigV7k_o.mjs} +2 -2
  30. package/lib/{google-antigravity-B1mSckrK.mjs → google-antigravity-D-oe0r8A.mjs} +6 -7
  31. package/lib/{google-gemini-cli-DJwThCCn.mjs → google-gemini-cli-CQBHgGJT.mjs} +5 -6
  32. package/lib/{google-oauth-shared-BctLpVUN.mjs → google-oauth-shared-CvgVIUwJ.mjs} +2 -2
  33. package/lib/google-validation-CdvRj4ec.mjs +126 -0
  34. package/lib/id-EJwVLDHE.mjs +2548 -0
  35. package/lib/index.mjs +248 -258
  36. package/lib/{kilo-BEgEwMJQ.mjs → kilo-5r6OffCa.mjs} +2 -2
  37. package/lib/{kimi-T9NldEIJ.mjs → kimi-DOOtbXmm.mjs} +9 -10
  38. package/lib/{launch-BIWNyrBB.mjs → launch-DkAjib7h.mjs} +1 -1
  39. package/lib/{markit-Dvp2JPdT.mjs → markit-CCcyeAds.mjs} +359 -140
  40. package/lib/{models-DnXMYGcJ.mjs → models-DCpDT_im.mjs} +199203 -112275
  41. package/lib/{muse-code-CNvqqAp6.mjs → muse-code-CYf8zj_B.mjs} +5 -5
  42. package/lib/{openai-codex-D5-CyTxa.mjs → openai-codex-Cj-TvSFh.mjs} +13 -10
  43. package/lib/{perplexity-A2PEoGaC.mjs → perplexity-Dh_Qgsmx.mjs} +68 -25
  44. package/lib/{pkce-BYjmugmw.mjs → pkce-DO-jBJLV.mjs} +1 -1
  45. package/lib/pricing-DusBEhwm.mjs +593 -0
  46. package/lib/{readability-uGhqb4GC.mjs → readability-XHK0o3bv.mjs} +287 -27
  47. package/lib/{scrapers-C1ujjV8k.mjs → scrapers-B6PADOVm.mjs} +13 -13
  48. package/lib/slugify-ynYWBIA5.mjs +11 -0
  49. package/lib/snowflake-B_jap6lz.mjs +666 -0
  50. package/lib/snowflake-Cu1ZyOp6.mjs +151 -0
  51. package/lib/{src-AELUUb5U.mjs → src-BhinCSpi.mjs} +1172 -458
  52. package/lib/{stream-AVOoe5Hj.mjs → stream-D2ivg3GH.mjs} +3740 -5311
  53. package/lib/{turndown-D6fof1OX.mjs → turndown-Vya8SavL.mjs} +82 -30
  54. package/lib/types/tools/hashline/native/index.d.ts +2 -2
  55. package/lib/types/tools/hashline/native/policy.d.ts +19 -21
  56. package/lib/types/tools/omp/session/agent-storage.d.ts +3 -3
  57. package/lib/types/tools/shared/bun-named-shim.d.ts +5 -0
  58. package/lib/{types-BLrLohwK.mjs → types-tH1v9uRm.mjs} +2 -2
  59. package/lib/{utils-cZX3f_Ls.mjs → utils-C_Ncya1r.mjs} +1737 -509
  60. package/lib/utils-D2tK38xq.mjs +34006 -0
  61. package/lib/{utils-I4I8azHN.mjs → utils-DrDwmNtu.mjs} +8 -3
  62. package/lib/{xai-oauth-CbeldUSV.mjs → xai-oauth-DLLzX6my.mjs} +4 -4
  63. package/lib/{xiaomi-Dl3VSs04.mjs → xiaomi-CqK-KivK.mjs} +2 -2
  64. package/lib/{zai-FyjGSypr.mjs → zai-DoJ2xPIH.mjs} +2 -2
  65. package/lib/{zip-DRrycScC.mjs → zip-DG1mUV6X.mjs} +1 -1
  66. package/package.json +8 -8
  67. package/lib/amazon-bedrock-Dx0rr9dY.mjs +0 -996
  68. package/lib/anthropic-ClCw0PV_.mjs +0 -3624
  69. package/lib/anthropic-wire-lbGAFzYb.mjs +0 -927
  70. package/lib/azure-openai-responses-WE_bgFWp.mjs +0 -285
  71. package/lib/bundled-references-DY3EJxZV.mjs +0 -56
  72. package/lib/cloudflare-ai-gateway-CrMa97Ap.mjs +0 -44
  73. package/lib/collapse-CkMNRNr7.mjs +0 -2304
  74. package/lib/cursor-C6jaIJDg.mjs +0 -283
  75. package/lib/cursor-D-XZYDf_.mjs +0 -4544
  76. package/lib/deterministic-id-CUEIMSqR.mjs +0 -17
  77. package/lib/devin-ExGIghmx.mjs +0 -69
  78. package/lib/devin-u0ljw5P6.mjs +0 -628
  79. package/lib/effort-BdtQMN-_.mjs +0 -23
  80. package/lib/event-stream-BKEtb45Y.mjs +0 -167
  81. package/lib/gemini-headers-Co9cVvex.mjs +0 -54
  82. package/lib/google-auth-qAN-6DMW.mjs +0 -232
  83. package/lib/google-gemini-cli-B2Aw1S5w.mjs +0 -844
  84. package/lib/google-lTxuq28n.mjs +0 -38
  85. package/lib/google-shared-Y01j9xOr.mjs +0 -856
  86. package/lib/google-validation-BEkNs-Bx.mjs +0 -18
  87. package/lib/google-vertex-DcM-FRC5.mjs +0 -99
  88. package/lib/hosts-00rjRzUD.mjs +0 -203
  89. package/lib/id-AL5obQzR.mjs +0 -71
  90. package/lib/idle-iterator-D0ZXEcUq.mjs +0 -366
  91. package/lib/ollama-6R0oXZks.mjs +0 -574
  92. package/lib/openai-codex-responses-C8bnBWOe.mjs +0 -3232
  93. package/lib/openai-completions-DNr3mUsn.mjs +0 -1430
  94. package/lib/openai-configuration-update-xMYUjaK_.mjs +0 -150
  95. package/lib/openai-reasoning-fallback-Ju-5pSR8.mjs +0 -380
  96. package/lib/openai-responses-CjpafAEr.mjs +0 -861
  97. package/lib/protobuf-BMgDYu_U.mjs +0 -717
  98. package/lib/provider-response-SqKSkkUc.mjs +0 -22
  99. package/lib/proxy-DxvCQOCA.mjs +0 -230
  100. package/lib/request-debug-BwPOqN_j.mjs +0 -183
  101. package/lib/sanitize-text-BCf5KmCf.mjs +0 -33
  102. package/lib/sse-debug-B-tkLCPW.mjs +0 -11
  103. package/lib/stream-markup-healing-CN3RsqG9.mjs +0 -267
  104. package/lib/strict-tool-validation-CBTz1dAA.mjs +0 -105
  105. package/lib/taxonomy-DSIM99rS.mjs +0 -15392
  106. package/lib/thinking-ngMwf_1Y.mjs +0 -336
  107. package/lib/type-guards-CttAANEx.mjs +0 -11
  108. package/lib/utils-CE3DSebh.mjs +0 -11763
  109. package/lib/vision-guard-BCpXWUj3.mjs +0 -77
@@ -1,6 +1,6 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/readability/readability.ts
3
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/readability/readability.ts
4
4
  const UNLIKELY$1 = /-ad-|ai2html|banner|breadcrumbs|comment|community|combx|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup/i;
5
5
  const POSSIBLE$1 = /and|article|body|column|content|main|shadow/i;
6
6
  const POSITIVE = /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i;
@@ -42,6 +42,9 @@ const UNLIKELY_ROLES = /* @__PURE__ */ new Set([
42
42
  ]);
43
43
  const ARTICLE_TYPES = /^(?:Article|AdvertiserContentArticle|NewsArticle|AnalysisNewsArticle|OpinionNewsArticle|ReportageNewsArticle|ReviewNewsArticle|Report|ScholarlyArticle|MedicalScholarlyArticle|SocialMediaPosting|BlogPosting|LiveBlogPosting|DiscussionForumPosting|TechArticle|APIReference)$/;
44
44
  const NORMALIZE = /\s{2,}/g;
45
+ const ELEMENT_NODE = 1;
46
+ const TEXT_NODE = 3;
47
+ const CDATA_SECTION_NODE = 4;
45
48
  function elements(collection) {
46
49
  return Array.from(collection);
47
50
  }
@@ -105,6 +108,224 @@ function linkDensity(node) {
105
108
  for (const link of elements(node.getElementsByTagName("a"))) linked += text(link).length * ((link.getAttribute("href") ?? "").startsWith("#") ? .3 : 1);
106
109
  return linked / total;
107
110
  }
111
+ /** Whether a UTF-16 code unit is whitespace to `String#trim` and `\s`. */
112
+ function isSpace(code) {
113
+ if (code <= 32) return code === 32 || code >= 9 && code <= 13;
114
+ if (code < 160) return false;
115
+ return code === 160 || code === 5760 || code >= 8192 && code <= 8202 || code === 8232 || code === 8233 || code === 8239 || code === 8287 || code === 12288 || code === 65279;
116
+ }
117
+ /** Separators `#scoreParagraph` counts clauses by. */
118
+ function isSeparator(code) {
119
+ return code === 44 || code === 1548 || code === 65104 || code === 65040 || code === 65041 || code === 11841 || code === 11828 || code === 11826 || code === 65292;
120
+ }
121
+ const SEPARATORS = /[\u002c\u060c\ufe50\ufe10\ufe11\u2e41\u2e34\u2e32\uff0c]/;
122
+ /** {@link TextRun} flags: no non-whitespace text; starts with whitespace; ends with whitespace. */
123
+ const BLANK = 1;
124
+ const LEADING_SPACE = 2;
125
+ const TRAILING_SPACE = 4;
126
+ /** Measures `text()` of concatenated pieces without building the string. */
127
+ var TextRun = class {
128
+ length = 0;
129
+ /** A blank run that contains whitespace carries both space flags. */
130
+ flags = BLANK;
131
+ commas = 0;
132
+ separators = 0;
133
+ reset() {
134
+ this.length = 0;
135
+ this.flags = BLANK;
136
+ this.commas = 0;
137
+ this.separators = 0;
138
+ }
139
+ /** Append a run measured earlier. */
140
+ append(length, flags, commas, separators) {
141
+ this.commas += commas;
142
+ this.separators += separators;
143
+ if (flags & BLANK) {
144
+ if (flags & LEADING_SPACE) this.flags |= this.flags & BLANK ? 6 : TRAILING_SPACE;
145
+ return;
146
+ }
147
+ if (this.flags & BLANK) {
148
+ this.length = length;
149
+ this.flags = this.flags & LEADING_SPACE | flags;
150
+ return;
151
+ }
152
+ if (this.flags & TRAILING_SPACE || flags & LEADING_SPACE) this.length++;
153
+ this.length += length;
154
+ this.flags = this.flags & LEADING_SPACE | flags & TRAILING_SPACE;
155
+ }
156
+ appendText(value) {
157
+ if (!value) return;
158
+ let length = 0;
159
+ let commas = 0;
160
+ let separators = 0;
161
+ let seen = false;
162
+ let gap = false;
163
+ for (let index = 0; index < value.length; index++) {
164
+ const code = value.charCodeAt(index);
165
+ if (isSpace(code)) {
166
+ if (seen) gap = true;
167
+ continue;
168
+ }
169
+ if (gap) {
170
+ length++;
171
+ gap = false;
172
+ }
173
+ length++;
174
+ seen = true;
175
+ if (isSeparator(code)) {
176
+ separators++;
177
+ if (code === 44) commas++;
178
+ }
179
+ }
180
+ const flags = seen ? (isSpace(value.charCodeAt(0)) ? LEADING_SPACE : 0) | (gap ? TRAILING_SPACE : 0) : 7;
181
+ this.append(length, flags, commas, separators);
182
+ }
183
+ };
184
+ function isTag(node, upper, lower) {
185
+ return node.tagName === upper || node.tagName === lower;
186
+ }
187
+ /**
188
+ * `text()` lengths, comma counts, descendant tag counts and link density of every element in a tree, from one
189
+ * bottom-up pass over the whole tree holding the first element asked about. Answers describe the tree as
190
+ * measured, so only ask about elements whose subtree has not changed since.
191
+ */
192
+ var SubtreeStats = class {
193
+ #countsAsText;
194
+ #index = /* @__PURE__ */ new Map();
195
+ #length = [];
196
+ #flags = [];
197
+ #commas = [];
198
+ #separators = [];
199
+ #paragraphs = [];
200
+ #images = [];
201
+ #inputs = [];
202
+ /** Range of an element's descendant anchors in {@link #links}. */
203
+ #linkStart = [];
204
+ #linkEnd = [];
205
+ /** `linkDensity` term of each anchor, in document order. */
206
+ #links = [];
207
+ /** `countsAsText` tells whether a non-element child's `textContent` is part of its parent's. */
208
+ constructor(countsAsText) {
209
+ this.#countsAsText = countsAsText;
210
+ }
211
+ /** `text(node).length`. */
212
+ length(node) {
213
+ const index = this.#at(node);
214
+ return index < 0 ? text(node).length : this.#length[index];
215
+ }
216
+ /** `!text(node)`. */
217
+ blank(node) {
218
+ const index = this.#at(node);
219
+ return index < 0 ? !text(node) : (this.#flags[index] & BLANK) !== 0;
220
+ }
221
+ /** `text(node).split(",").length - 1`. */
222
+ commas(node) {
223
+ const index = this.#at(node);
224
+ return index < 0 ? text(node).split(",").length - 1 : this.#commas[index];
225
+ }
226
+ /** `text(node).split(SEPARATORS).length - 1`. */
227
+ separators(node) {
228
+ const index = this.#at(node);
229
+ return index < 0 ? text(node).split(SEPARATORS).length - 1 : this.#separators[index];
230
+ }
231
+ /** `node.getElementsByTagName("p").length`. */
232
+ paragraphs(node) {
233
+ const index = this.#at(node);
234
+ return index < 0 ? node.getElementsByTagName("p").length : this.#paragraphs[index];
235
+ }
236
+ /** `node.getElementsByTagName("img").length`. */
237
+ images(node) {
238
+ const index = this.#at(node);
239
+ return index < 0 ? node.getElementsByTagName("img").length : this.#images[index];
240
+ }
241
+ /** `node.getElementsByTagName("input").length`. */
242
+ inputs(node) {
243
+ const index = this.#at(node);
244
+ return index < 0 ? node.getElementsByTagName("input").length : this.#inputs[index];
245
+ }
246
+ /** `linkDensity(node)`, summed in the same order so the result is bit-identical. */
247
+ linkDensity(node) {
248
+ const index = this.#at(node);
249
+ if (index < 0) return linkDensity(node);
250
+ const total = this.#length[index];
251
+ if (!total) return 0;
252
+ let linked = 0;
253
+ for (let link = this.#linkStart[index]; link < this.#linkEnd[index]; link++) linked += this.#links[link];
254
+ return linked / total;
255
+ }
256
+ #at(node) {
257
+ const index = this.#index.get(node);
258
+ if (index !== void 0) return index;
259
+ if (node.nodeType !== ELEMENT_NODE) return -1;
260
+ let root = node;
261
+ while (root.parentNode?.nodeType === ELEMENT_NODE) root = root.parentNode;
262
+ this.#measure(root);
263
+ return this.#index.get(node) ?? -1;
264
+ }
265
+ #measure(root) {
266
+ const first = this.#length.length;
267
+ const order = [];
268
+ const anchors = [];
269
+ const pending = [root];
270
+ while (pending.length) {
271
+ const node = pending.pop();
272
+ if (!node) continue;
273
+ this.#index.set(node, first + order.length);
274
+ order.push(node);
275
+ if (isTag(node, "A", "a")) anchors.push(node);
276
+ this.#linkStart.push(this.#links.length + anchors.length);
277
+ this.#linkEnd.push(0);
278
+ this.#length.push(0);
279
+ this.#flags.push(0);
280
+ this.#commas.push(0);
281
+ this.#separators.push(0);
282
+ this.#paragraphs.push(0);
283
+ this.#images.push(0);
284
+ this.#inputs.push(0);
285
+ const children = node.childNodes;
286
+ for (let child = children.length - 1; child >= 0; child--) if (children[child].nodeType === ELEMENT_NODE) pending.push(children[child]);
287
+ }
288
+ const run = new TextRun();
289
+ for (let offset = order.length - 1; offset >= 0; offset--) {
290
+ const node = order[offset];
291
+ const index = first + offset;
292
+ const children = node.childNodes;
293
+ const leaf = !children.length || isTag(node, "TEMPLATE", "template");
294
+ run.reset();
295
+ if (leaf) run.appendText(node.textContent ?? "");
296
+ let paragraphs = 0;
297
+ let images = 0;
298
+ let inputs = 0;
299
+ let linkEnd = this.#linkStart[index];
300
+ for (let child = 0; child < children.length; child++) {
301
+ const childNode = children[child];
302
+ if (childNode.nodeType !== ELEMENT_NODE) {
303
+ if (!leaf && this.#countsAsText(childNode)) run.appendText(childNode.textContent ?? "");
304
+ continue;
305
+ }
306
+ const element = childNode;
307
+ const at = this.#index.get(element) ?? -1;
308
+ if (!leaf) run.append(this.#length[at], this.#flags[at], this.#commas[at], this.#separators[at]);
309
+ paragraphs += this.#paragraphs[at] + (isTag(element, "P", "p") ? 1 : 0);
310
+ images += this.#images[at] + (isTag(element, "IMG", "img") ? 1 : 0);
311
+ inputs += this.#inputs[at] + (isTag(element, "INPUT", "input") ? 1 : 0);
312
+ linkEnd = this.#linkEnd[at];
313
+ }
314
+ this.#length[index] = run.length;
315
+ this.#flags[index] = run.flags;
316
+ this.#commas[index] = run.commas;
317
+ this.#separators[index] = run.separators;
318
+ this.#paragraphs[index] = paragraphs;
319
+ this.#images[index] = images;
320
+ this.#inputs[index] = inputs;
321
+ this.#linkEnd[index] = linkEnd;
322
+ }
323
+ for (const anchor of anchors) {
324
+ const length = this.#length[this.#index.get(anchor) ?? -1];
325
+ this.#links.push(length * ((anchor.getAttribute("href") ?? "").startsWith("#") ? .3 : 1));
326
+ }
327
+ }
328
+ };
108
329
  function visible(node) {
109
330
  const style = node.getAttribute("style")?.toLowerCase() ?? "";
110
331
  return !node.hasAttribute("hidden") && node.getAttribute("aria-hidden") !== "true" && !/display\s*:\s*none|visibility\s*:\s*hidden/.test(style);
@@ -113,6 +334,22 @@ function removeAll(root, tags) {
113
334
  const container = root;
114
335
  for (const tag of tags) for (const node of elements(container.getElementsByTagName(tag))) node.remove();
115
336
  }
337
+ /** Replace `parent`'s children, detaching the old ones in one step where the DOM supports it. */
338
+ function replaceChildren(parent, children) {
339
+ if (parent.replaceChildren) parent.replaceChildren();
340
+ else while (parent.firstChild) parent.firstChild.remove();
341
+ for (const child of children) parent.appendChild(child);
342
+ }
343
+ /** Move all of `from`'s children to the end of `to` without detaching them one by one. */
344
+ function moveChildren(from, to) {
345
+ if (!from.replaceChildren) {
346
+ while (from.firstChild) to.appendChild(from.firstChild);
347
+ return;
348
+ }
349
+ const children = Array.from(from.childNodes);
350
+ from.replaceChildren();
351
+ for (const child of children) to.appendChild(child);
352
+ }
116
353
  function entityDecode(value) {
117
354
  if (!value) return value;
118
355
  const named = {
@@ -218,6 +455,8 @@ var Readability = class {
218
455
  #scores = /* @__PURE__ */ new Map();
219
456
  #byline;
220
457
  #lang = null;
458
+ /** Per non-text node type, whether this DOM counts its `textContent` in a parent's. */
459
+ #textByNodeType = /* @__PURE__ */ new Map();
221
460
  constructor(document, options = {}) {
222
461
  this.#document = document;
223
462
  this.#options = options;
@@ -236,7 +475,7 @@ var Readability = class {
236
475
  removeAll(this.#document, ["script", "style"]);
237
476
  const body = this.#document.body;
238
477
  if (!body) return null;
239
- const source = body.innerHTML;
478
+ const pristine = Array.from(body.childNodes, (node) => node.cloneNode(true));
240
479
  const attempts = [];
241
480
  for (const mode of [
242
481
  0,
@@ -244,7 +483,7 @@ var Readability = class {
244
483
  2,
245
484
  3
246
485
  ]) {
247
- if (mode) body.innerHTML = source;
486
+ if (mode) replaceChildren(body, mode === 3 ? pristine : pristine.map((node) => node.cloneNode(true)));
248
487
  this.#scores.clear();
249
488
  this.#byline = void 0;
250
489
  const attempt = this.#extract(body, documentElement, metadata.title ?? "", mode);
@@ -287,10 +526,13 @@ var Readability = class {
287
526
  node.remove();
288
527
  continue;
289
528
  }
290
- if (!this.#byline && this.#isByline(node, label)) {
291
- this.#byline = text(node);
292
- node.remove();
293
- continue;
529
+ if (!this.#byline) {
530
+ const byline = this.#bylineText(node, label);
531
+ if (byline) {
532
+ this.#byline = byline;
533
+ node.remove();
534
+ continue;
535
+ }
294
536
  }
295
537
  if (!titleRemoved && /^(?:H1|H2)$/.test(node.tagName) && this.#similar(articleTitle, text(node)) > .75) {
296
538
  titleRemoved = true;
@@ -303,12 +545,13 @@ var Readability = class {
303
545
  }
304
546
  if (SCORE_TAGS.has(node.tagName)) scored.push(node);
305
547
  }
306
- for (const paragraph of scored) this.#scoreParagraph(paragraph, weightClasses);
548
+ const stats = new SubtreeStats(this.#countsAsText);
549
+ for (const paragraph of scored) this.#scoreParagraph(paragraph, weightClasses, stats);
307
550
  let top;
308
551
  let topScore = Number.NEGATIVE_INFINITY;
309
552
  for (const [candidate, raw] of this.#scores) {
310
553
  if (candidate.tagName === "BODY" || candidate.tagName === "HTML") continue;
311
- const score = raw * (1 - linkDensity(candidate));
554
+ const score = raw * (1 - stats.linkDensity(candidate));
312
555
  this.#scores.set(candidate, score);
313
556
  if (score > topScore) {
314
557
  top = candidate;
@@ -322,9 +565,9 @@ var Readability = class {
322
565
  const siblings = parent ? elements(parent.children) : [top];
323
566
  const threshold = Math.max(10, (this.#scores.get(top) ?? topScore) * .2);
324
567
  for (const sibling of siblings) {
325
- const siblingText = text(sibling);
568
+ const siblingLength = stats.length(sibling);
326
569
  const sameClassBonus = sibling.className && sibling.className === top.className ? (this.#scores.get(top) ?? 0) * .2 : 0;
327
- if (!(sibling === top || (this.#scores.get(sibling) ?? 0) + sameClassBonus >= threshold || sibling.tagName === "P" && (siblingText.length > 80 && linkDensity(sibling) < .25 || siblingText.length > 0 && siblingText.length < 80 && linkDensity(sibling) === 0 && /\.(?: |$)/.test(siblingText)))) continue;
570
+ if (!(sibling === top || (this.#scores.get(sibling) ?? 0) + sameClassBonus >= threshold || sibling.tagName === "P" && (siblingLength > 80 && stats.linkDensity(sibling) < .25 || siblingLength > 0 && siblingLength < 80 && stats.linkDensity(sibling) === 0 && /\.(?: |$)/.test(text(sibling))))) continue;
328
571
  if ([
329
572
  "DIV",
330
573
  "ARTICLE",
@@ -338,14 +581,14 @@ var Readability = class {
338
581
  }
339
582
  const replacement = this.#document.createElement("DIV");
340
583
  for (const attribute of Array.from(sibling.attributes)) replacement.setAttribute(attribute.name, attribute.value);
341
- while (sibling.firstChild) replacement.appendChild(sibling.firstChild);
584
+ moveChildren(sibling, replacement);
342
585
  article.appendChild(replacement);
343
586
  }
344
587
  this.#clean(article, mode < 3);
345
588
  const page = this.#document.createElement("DIV");
346
589
  page.id = "readability-page-1";
347
590
  page.className = "page";
348
- while (article.firstChild) page.appendChild(article.firstChild);
591
+ moveChildren(article, page);
349
592
  article.appendChild(page);
350
593
  const content = text(article);
351
594
  let dir;
@@ -363,10 +606,10 @@ var Readability = class {
363
606
  dir
364
607
  };
365
608
  }
366
- #scoreParagraph(node, weightClasses) {
367
- const content = text(node);
368
- if (content.length < 25) return;
369
- const score = 1 + content.split(/[\u002c\u060c\ufe50\ufe10\ufe11\u2e41\u2e34\u2e32\uff0c]/).length + Math.min(Math.floor(content.length / 100), 3);
609
+ #scoreParagraph(node, weightClasses, stats) {
610
+ const length = stats.length(node);
611
+ if (length < 25) return;
612
+ const score = 1 + (stats.separators(node) + 1) + Math.min(Math.floor(length / 100), 3);
370
613
  let ancestor = node.parentNode;
371
614
  for (let level = 0; ancestor && level < 5; level++, ancestor = ancestor.parentNode) {
372
615
  const element = ancestor;
@@ -379,13 +622,14 @@ var Readability = class {
379
622
  #clean(root, conditional) {
380
623
  removeAll(root, DROP_TAGS);
381
624
  for (const heading of elements(root.querySelectorAll("h1, h2, h3, h4, h5, h6"))) if (classWeight(heading) < 0 || linkDensity(heading) > .33) heading.remove();
382
- if (conditional) for (const node of elements(root.querySelectorAll("table, ul, div"))) {
383
- if (node === root) continue;
384
- const nodeText = text(node);
385
- const paragraphs = node.getElementsByTagName("p").length;
386
- const images = node.getElementsByTagName("img").length;
387
- const inputs = node.getElementsByTagName("input").length;
388
- if (classWeight(node) < 0 || !nodeText && !images || nodeText.split(",").length < 10 && (images > paragraphs && paragraphs > 0 || inputs > Math.floor(paragraphs / 3) || linkDensity(node) > .5)) node.remove();
625
+ if (conditional) {
626
+ const stats = new SubtreeStats(this.#countsAsText);
627
+ for (const node of elements(root.querySelectorAll("table, ul, div"))) {
628
+ if (node === root) continue;
629
+ const paragraphs = stats.paragraphs(node);
630
+ const images = stats.images(node);
631
+ if (classWeight(node) < 0 || stats.blank(node) && !images || stats.commas(node) + 1 < 10 && (images > paragraphs && paragraphs > 0 || stats.inputs(node) > Math.floor(paragraphs / 3) || stats.linkDensity(node) > .5)) node.remove();
632
+ }
389
633
  }
390
634
  for (const paragraph of elements(root.getElementsByTagName("p"))) if (!text(paragraph) && !paragraph.querySelector("img, embed, object, iframe")) paragraph.remove();
391
635
  for (const node of [root, ...descendants(root)]) {
@@ -411,10 +655,26 @@ var Readability = class {
411
655
  ]) node.removeAttribute(attr);
412
656
  }
413
657
  }
414
- #isByline(node, label) {
658
+ /** Byline text when `node` is marked as one; the attribute checks run first so most nodes never build text. */
659
+ #bylineText(node, label) {
660
+ if (node.getAttribute("rel") !== "author" && !(node.getAttribute("itemprop") ?? "").includes("author") && !BYLINE.test(label)) return void 0;
415
661
  const value = text(node);
416
- return value.length > 0 && value.length < 100 && (node.getAttribute("rel") === "author" || (node.getAttribute("itemprop") ?? "").includes("author") || BYLINE.test(label));
662
+ return value.length > 0 && value.length < 100 ? value : void 0;
417
663
  }
664
+ /** Whether a non-element child's `textContent` is part of its parent's (text is; comments are in some DOMs). */
665
+ #countsAsText = (node) => {
666
+ if (node.nodeType === TEXT_NODE || node.nodeType === CDATA_SECTION_NODE) return true;
667
+ const value = node.textContent;
668
+ if (!value) return false;
669
+ let counts = this.#textByNodeType.get(node.nodeType);
670
+ if (counts === void 0) {
671
+ const probe = this.#document.createElement("DIV");
672
+ probe.appendChild(node.cloneNode(false));
673
+ counts = probe.textContent === value;
674
+ this.#textByNodeType.set(node.nodeType, counts);
675
+ }
676
+ return counts;
677
+ };
418
678
  #similar(left, right) {
419
679
  const leftTokens = left.toLowerCase().split(/\W+/).filter(Boolean);
420
680
  const rightTokens = right.toLowerCase().split(/\W+/).filter(Boolean);
@@ -423,7 +683,7 @@ var Readability = class {
423
683
  }
424
684
  };
425
685
  //#endregion
426
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/readability/readerable.ts
686
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/readability/readerable.ts
427
687
  const UNLIKELY = /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i;
428
688
  const POSSIBLE = /and|article|body|column|content|main|shadow/i;
429
689
  /** Estimates whether a document contains enough prose for article extraction. */
@@ -1,16 +1,16 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
- import { n as fs_promises_shim_exports } from "./fs-promises-shim-B2YFWkcd.mjs";
4
- import { $ as isEnoent, B as USER_AGENT, C as warn, G as getDocsRsCacheDir, N as $env, c as combineSignals, j as formatNumber, k as formatBytes, l as exec, s as Snowflake, y as parseFrontmatter } from "./src-AELUUb5U.mjs";
5
- import { W as tryParseJson } from "./utils-cZX3f_Ls.mjs";
6
- import { a as fetchBinary, c as getParallelExtractContent, i as convertWithMarkit, l as ensureTool, m as settings, n as asRecord, o as extractWithParallel, r as asString, s as findParallelApiKey, t as asNumber } from "./utils-CE3DSebh.mjs";
7
- import { n as isRecord } from "./type-guards-CttAANEx.mjs";
3
+ import { n as fs_promises_shim_exports } from "./fs-promises-shim-CANAxFWh.mjs";
4
+ import { B as formatNumber, H as $env, R as formatBytes, T as parseFrontmatter, X as USER_AGENT, d as exec, dt as isEnoent, k as warn, l as Snowflake, nt as getDocsRsCacheDir, u as combineSignals } from "./src-BhinCSpi.mjs";
5
+ import { a as fetchBinary, c as getParallelExtractContent, i as convertWithMarkit, l as ensureTool, m as settings, n as asRecord, o as extractWithParallel, r as asString, s as findParallelApiKey, t as asNumber } from "./utils-D2tK38xq.mjs";
6
+ import { ut as tryParseJson } from "./utils-C_Ncya1r.mjs";
7
+ import { h as isRecord } from "./cascade-BWjRTD1q.mjs";
8
8
  import { r as throwIfAborted, t as ToolAbortError } from "./tool-errors-DoyxivAR.mjs";
9
- import { c as getLocalizedText, d as looksLikeHtml, i as decodeHtmlEntities, l as htmlToBasicMarkdown, o as formatIsoDate, r as buildResult, s as formatMediaDuration, u as loadPage } from "./types-BLrLohwK.mjs";
9
+ import { c as getLocalizedText, d as looksLikeHtml, i as decodeHtmlEntities, l as htmlToBasicMarkdown, o as formatIsoDate, r as buildResult, s as formatMediaDuration, u as loadPage } from "./types-tH1v9uRm.mjs";
10
10
  import * as path$1 from "node:path";
11
11
  import * as os from "node:os";
12
12
  import { gunzipSync } from "node:zlib";
13
- //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.1.17/node_modules/@oh-my-pi/pi-utils/src/version.ts
13
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/version.ts
14
14
  const DIGITS = /^\d+$/;
15
15
  /**
16
16
  * Compare two version strings.
@@ -222,7 +222,7 @@ const handleArxiv = async (url, timeout, signal) => {
222
222
  signal
223
223
  });
224
224
  if (!result.ok) return null;
225
- const { parseHTML } = await import("./dom-DG3sPESc.mjs");
225
+ const { parseHTML } = await import("./dom-BmbZv4v9.mjs");
226
226
  const entry = parseHTML(result.content).document.querySelector("entry");
227
227
  if (!entry) return null;
228
228
  const title = entry.querySelector("title")?.textContent?.trim()?.replace(/\s+/g, " ");
@@ -3527,7 +3527,7 @@ const handleGoPkg = async (url, timeout, signal) => {
3527
3527
  notes: ["error"],
3528
3528
  contentType: "text/plain"
3529
3529
  });
3530
- const { parseHTML } = await import("./dom-DG3sPESc.mjs");
3530
+ const { parseHTML } = await import("./dom-BmbZv4v9.mjs");
3531
3531
  const doc = parseHTML(pageResult.content).document;
3532
3532
  const breadcrumb = doc.querySelector(".go-Breadcrumb");
3533
3533
  if (breadcrumb) {
@@ -4183,7 +4183,7 @@ const handleIacr = async (url, timeout, signal) => {
4183
4183
  signal
4184
4184
  });
4185
4185
  if (!result.ok) return null;
4186
- const { parseHTML } = await import("./dom-DG3sPESc.mjs");
4186
+ const { parseHTML } = await import("./dom-BmbZv4v9.mjs");
4187
4187
  const doc = parseHTML(result.content).document;
4188
4188
  const title = doc.querySelector("h3.mb-3")?.textContent?.trim() || doc.querySelector("meta[name=\"citation_title\"]")?.getAttribute("content");
4189
4189
  const authors = Array.from(doc.querySelectorAll("meta[name=\"citation_author\"]")).map((m) => m.getAttribute("content")).filter((author) => Boolean(author));
@@ -6608,7 +6608,7 @@ const handleReadTheDocs = async (url, timeout, signal) => {
6608
6608
  truncated: false,
6609
6609
  notes
6610
6610
  };
6611
- const { parseHTML } = await import("./dom-DG3sPESc.mjs");
6611
+ const { parseHTML } = await import("./dom-BmbZv4v9.mjs");
6612
6612
  const root = parseHTML(result.content).document;
6613
6613
  let mainContent = root.querySelector(".document") || root.querySelector("[role=\"main\"]") || root.querySelector("main") || root.querySelector(".rst-content") || root.querySelector(".body");
6614
6614
  if (!mainContent) {
@@ -8239,7 +8239,7 @@ const handleTwitter = async (url, timeout, signal) => {
8239
8239
  signal
8240
8240
  });
8241
8241
  if (result.ok && result.content.length > 500) {
8242
- const { parseHTML } = await import("./dom-DG3sPESc.mjs");
8242
+ const { parseHTML } = await import("./dom-BmbZv4v9.mjs");
8243
8243
  const doc = parseHTML(result.content).document;
8244
8244
  const tweetContent = doc.querySelector(".tweet-content")?.textContent?.trim();
8245
8245
  const fullname = doc.querySelector(".fullname")?.textContent?.trim();
@@ -8860,7 +8860,7 @@ const handleWikipedia = async (url, timeout, signal) => {
8860
8860
  signal
8861
8861
  });
8862
8862
  if (contentResult.ok) {
8863
- const { parseHTML } = await import("./dom-DG3sPESc.mjs");
8863
+ const { parseHTML } = await import("./dom-BmbZv4v9.mjs");
8864
8864
  const sections = parseHTML(contentResult.content).document.querySelectorAll("section");
8865
8865
  for (const section of sections) {
8866
8866
  const heading = section.querySelector("h2, h3, h4");
@@ -0,0 +1,11 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ //#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/slugify.ts
4
+ /** Lowercase ASCII kebab slug: [^a-z0-9]+ → "-", edge dashes trimmed; optional maxLength truncates then re-trims trailing dashes; throws RangeError unless maxLength is a non-negative integer. Returns "" when nothing survives. */
5
+ function slugify(input, options) {
6
+ if (options?.maxLength !== void 0 && !(Number.isInteger(options.maxLength) && options.maxLength >= 0)) throw new RangeError(`slugify maxLength must be a non-negative integer, got ${options.maxLength}`);
7
+ const slug = input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
8
+ return options?.maxLength === void 0 ? slug : slug.slice(0, options.maxLength).replace(/-+$/g, "");
9
+ }
10
+ //#endregion
11
+ export { slugify as t };