@apmantza/greedysearch-pi 1.8.10 → 1.9.1
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 +532 -462
- package/bin/cdp.mjs +15 -2
- package/bin/launch-visible.mjs +65 -0
- package/bin/launch.mjs +440 -417
- package/bin/search.mjs +674 -668
- package/extractors/bing-copilot.mjs +68 -11
- package/extractors/common.mjs +86 -2
- package/extractors/consent.mjs +388 -315
- package/extractors/gemini.mjs +217 -207
- package/extractors/perplexity.mjs +56 -7
- package/extractors/selectors.mjs +55 -54
- package/index.ts +175 -177
- package/package.json +3 -2
- package/skills/greedy-search/skill.md +2 -7
- package/src/fetcher.mjs +666 -652
- package/src/formatters/synthesis.ts +1 -5
- package/src/search/chrome.mjs +62 -1
- package/src/search/constants.mjs +39 -43
- package/src/search/engines.mjs +76 -67
- package/src/search/file-sources.mjs +46 -0
- package/src/search/output.mjs +23 -1
- package/src/search/query.mjs +49 -0
- package/src/search/recovery.mjs +20 -1
- package/src/search/sources.mjs +466 -450
- package/src/search/synthesis.mjs +27 -16
- package/src/tools/greedy-search-handler.ts +226 -124
- package/extractors/google-search.mjs +0 -234
package/bin/cdp.mjs
CHANGED
|
@@ -365,10 +365,23 @@ async function captureMainContext(cdp, sid) {
|
|
|
365
365
|
// Always disable Runtime after capturing
|
|
366
366
|
await cdp.send("Runtime.disable", {}, sid).catch(() => {});
|
|
367
367
|
|
|
368
|
-
//
|
|
369
|
-
|
|
368
|
+
// Get the root frame ID so we can prefer its context when multiple
|
|
369
|
+
// isDefault contexts exist (e.g. Gemini embeds _/bscframe as a child
|
|
370
|
+
// frame whose context fires first and would otherwise be picked instead).
|
|
371
|
+
let rootFrameId = null;
|
|
372
|
+
try {
|
|
373
|
+
const ft = await cdp.send("Page.getFrameTree", {}, sid);
|
|
374
|
+
rootFrameId = ft?.frameTree?.frame?.id ?? null;
|
|
375
|
+
} catch {}
|
|
376
|
+
|
|
377
|
+
const defaults = contexts.filter(
|
|
370
378
|
(ctx) => ctx.auxData?.isDefault && ctx.auxData?.type === "default",
|
|
371
379
|
);
|
|
380
|
+
// Prefer the context whose frameId matches the root frame
|
|
381
|
+
const main =
|
|
382
|
+
(rootFrameId && defaults.find((ctx) => ctx.auxData?.frameId === rootFrameId)) ||
|
|
383
|
+
defaults[0] ||
|
|
384
|
+
null;
|
|
372
385
|
return main?.id ?? null;
|
|
373
386
|
}
|
|
374
387
|
|
package/bin/launch-visible.mjs
CHANGED
|
@@ -106,6 +106,69 @@ function httpGet(url, timeoutMs = 1000) {
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
async function minimizeViaCDP(port) {
|
|
110
|
+
try {
|
|
111
|
+
const version = await httpGet(`http://localhost:${port}/json/version`).then(
|
|
112
|
+
(r) => JSON.parse(r.body),
|
|
113
|
+
);
|
|
114
|
+
const targets = await httpGet(`http://localhost:${port}/json/list`).then(
|
|
115
|
+
(r) => JSON.parse(r.body),
|
|
116
|
+
);
|
|
117
|
+
const targetId = targets.find((t) => t.type === "page")?.id;
|
|
118
|
+
if (!targetId) return;
|
|
119
|
+
|
|
120
|
+
// Validate browser WebSocket URL to prevent SSRF (SonarCloud javasecurity:S5335)
|
|
121
|
+
const wsUrlStr = version.webSocketDebuggerUrl;
|
|
122
|
+
if (typeof wsUrlStr !== "string") return;
|
|
123
|
+
const wsUrl = new URL(wsUrlStr);
|
|
124
|
+
if (wsUrl.hostname !== "localhost" && wsUrl.hostname !== "127.0.0.1")
|
|
125
|
+
return;
|
|
126
|
+
if (!/^ws:\/\/localhost:\d+/.test(`ws://${wsUrl.host}`)) return;
|
|
127
|
+
const wsPath = wsUrl.pathname;
|
|
128
|
+
const ws = new WebSocket(`ws://localhost:${port}${wsPath}`);
|
|
129
|
+
await new Promise((resolve) => {
|
|
130
|
+
ws.onopen = () =>
|
|
131
|
+
ws.send(
|
|
132
|
+
JSON.stringify({
|
|
133
|
+
id: 1,
|
|
134
|
+
method: "Browser.getWindowForTarget",
|
|
135
|
+
params: { targetId },
|
|
136
|
+
}),
|
|
137
|
+
);
|
|
138
|
+
ws.onmessage = (ev) => {
|
|
139
|
+
const msg = JSON.parse(ev.data);
|
|
140
|
+
if (msg.id === 1 && msg.result?.windowId) {
|
|
141
|
+
ws.send(
|
|
142
|
+
JSON.stringify({
|
|
143
|
+
id: 2,
|
|
144
|
+
method: "Browser.setWindowBounds",
|
|
145
|
+
params: {
|
|
146
|
+
windowId: msg.result.windowId,
|
|
147
|
+
bounds: { windowState: "minimized" },
|
|
148
|
+
},
|
|
149
|
+
}),
|
|
150
|
+
);
|
|
151
|
+
} else if (msg.id === 2) {
|
|
152
|
+
ws.close();
|
|
153
|
+
resolve();
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
ws.onerror = () => {
|
|
157
|
+
ws.close();
|
|
158
|
+
resolve();
|
|
159
|
+
};
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
try {
|
|
162
|
+
ws.close();
|
|
163
|
+
} catch {}
|
|
164
|
+
resolve();
|
|
165
|
+
}, 5000);
|
|
166
|
+
});
|
|
167
|
+
} catch {
|
|
168
|
+
// best-effort — Chrome is still usable if minimize fails
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
109
172
|
async function waitForPort(timeoutMs = 15000) {
|
|
110
173
|
const deadline = Date.now() + timeoutMs;
|
|
111
174
|
while (Date.now() < deadline) {
|
|
@@ -226,6 +289,8 @@ async function main() {
|
|
|
226
289
|
process.exit(1);
|
|
227
290
|
}
|
|
228
291
|
|
|
292
|
+
await minimizeViaCDP(PORT);
|
|
293
|
+
|
|
229
294
|
console.log("Visible Chrome ready on port 9222.");
|
|
230
295
|
console.log("Keep this terminal open to keep Chrome alive.");
|
|
231
296
|
}
|