zames_pro 2.81.14 → 2.81.15
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.
- package/CHANGELOG.md +6 -0
- package/dist/web.js +36 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.81.15] - 2026-10-21
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **web:** a search result without a snippet no longer borrows the next one
|
|
15
|
+
|
|
10
16
|
## [2.81.14] - 2026-10-21
|
|
11
17
|
|
|
12
18
|
### Fixed
|
package/dist/web.js
CHANGED
|
@@ -645,33 +645,47 @@ export function createWebTools() {
|
|
|
645
645
|
// wraps links in a /l/?uddg=... redirect which must be unwrapped.
|
|
646
646
|
export function parseDuckDuckGoResults(body, limit) {
|
|
647
647
|
const results = [];
|
|
648
|
-
|
|
648
|
+
// Parse the page ROW BY ROW: each `result__a` title opens a result, and a
|
|
649
|
+
// `result__snippet` belongs to the result opened most recently. The old
|
|
650
|
+
// single regex made the snippet group OPTIONAL with an unbounded gap, so a
|
|
651
|
+
// result without a snippet picked up the FOLLOWING result's snippet (wrong
|
|
652
|
+
// text under a URL). A row scan ties every snippet to its own result.
|
|
653
|
+
const anchorRe = /<a[^>]*class="[^"]*result__(a|snippet)[^"]*"[^>]*>([\s\S]*?)<\/a>/gi;
|
|
654
|
+
const hrefOf = (tag) => {
|
|
655
|
+
const m = tag.match(/href="([^"]*)"/i);
|
|
656
|
+
return m ? m[1] : '';
|
|
657
|
+
};
|
|
658
|
+
let cur = null;
|
|
649
659
|
let m;
|
|
650
|
-
while ((m =
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
try {
|
|
658
|
-
href = decodeURIComponent(uddgMatch[1]);
|
|
660
|
+
while ((m = anchorRe.exec(body))) {
|
|
661
|
+
const kind = m[1].toLowerCase();
|
|
662
|
+
if (kind === 'a') {
|
|
663
|
+
if (cur && cur.title && /^https?:\/\//i.test(cur.url)) {
|
|
664
|
+
results.push(cur);
|
|
665
|
+
if (results.length >= limit)
|
|
666
|
+
return results;
|
|
659
667
|
}
|
|
660
|
-
|
|
661
|
-
|
|
668
|
+
cur = { title: htmlToText(m[2] || '').trim(), url: '', snippet: '' };
|
|
669
|
+
// The href lives in the OPENING tag, which m[0] starts with.
|
|
670
|
+
let href = hrefOf(m[0].slice(0, m[0].indexOf('>') + 1));
|
|
671
|
+
const uddg = href.match(/[?&]uddg=([^&]+)/);
|
|
672
|
+
if (uddg) {
|
|
673
|
+
try {
|
|
674
|
+
href = decodeURIComponent(uddg[1]);
|
|
675
|
+
}
|
|
676
|
+
catch {
|
|
677
|
+
href = uddg[1];
|
|
678
|
+
}
|
|
662
679
|
}
|
|
663
|
-
|
|
664
|
-
const title = htmlToText(m[2] || '').trim();
|
|
665
|
-
const snippet = htmlToText(m[3] || '').trim();
|
|
666
|
-
// Only an absolute http(s) link is a real result. The page can carry a
|
|
667
|
-
// `javascript:`/`data:` href (malicious or broken markup) or a
|
|
668
|
-
// site-relative one; handing either to the model as a result URL is wrong
|
|
669
|
-
// (a `javascript:` URL looks fetchable, a relative one is not).
|
|
670
|
-
if (!title || !/^https?:\/\//i.test(href))
|
|
680
|
+
cur.url = href;
|
|
671
681
|
continue;
|
|
672
|
-
|
|
682
|
+
}
|
|
683
|
+
if (cur && !cur.snippet)
|
|
684
|
+
cur.snippet = htmlToText(m[2] || '').trim();
|
|
673
685
|
}
|
|
674
|
-
|
|
686
|
+
if (cur && cur.title && /^https?:\/\//i.test(cur.url))
|
|
687
|
+
results.push(cur);
|
|
688
|
+
return results.slice(0, limit);
|
|
675
689
|
}
|
|
676
690
|
function formatResult(status, url, text, limit) {
|
|
677
691
|
let out = text;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zames_pro",
|
|
3
|
-
"version": "2.81.
|
|
3
|
+
"version": "2.81.15",
|
|
4
4
|
"description": "Terminal coding agent that drives a real browser to chat with DeepSeek, Qwen and other web LLMs — no API key required. Reads and edits files, runs commands, commits to git, like Claude Code / Codex CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|