pi-chrome-search 2.0.0 → 2.1.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.
package/README.md CHANGED
@@ -1,8 +1,16 @@
1
1
  # pi-chrome-search
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/pi-chrome-search)](https://www.npmjs.com/package/pi-chrome-search)
4
+ [![downloads](https://img.shields.io/npm/dm/pi-chrome-search)](https://www.npmjs.com/package/pi-chrome-search)
5
+ [![pi](https://img.shields.io/badge/pi-package-6f42c1)](https://pi.dev/packages)
6
+ [![ci](https://github.com/sh2nk/pi-chrome-search/actions/workflows/ci.yml/badge.svg)](https://github.com/sh2nk/pi-chrome-search/actions/workflows/ci.yml)
7
+ [![license](https://img.shields.io/npm/l/pi-chrome-search)](LICENSE)
8
+ [![node](https://img.shields.io/badge/node-%3E%3D26-brightgreen)](package.json)
9
+
3
10
  Web search and page reading for [pi](https://pi.dev), through your own visible Chrome. Same profile,
4
11
  cookies and IP. Google, DuckDuckGo and Yandex return compact Markdown and their native AI summary when
5
- there is one. No keys, no paid APIs, no headless mode, no fingerprint spoofing. Node 26+, Chrome 136+.
12
+ there is one; Avito listings (price, location, age) are available opt-in. No keys, no paid APIs, no
13
+ headless mode, no fingerprint spoofing. Node 26+, Chrome 136+.
6
14
 
7
15
  ## Install
8
16
 
@@ -24,7 +32,7 @@ The window stays visible. The extension attaches to it and never launches, resta
24
32
  <!-- tools:start -->
25
33
  | Tool | Exposure | Arguments |
26
34
  |---|---|---|
27
- | `web_search` | direct | `q` string; `n?` integer 1..10; `engines?` "auto" or ("google" or "duckduckgo" or "yandex") or list of ("google" or "duckduckgo" or "yandex") 1..3; `summary?` boolean; `page?` integer >=1; `format?` "md" or "json" |
35
+ | `web_search` | direct | `q` string; `n?` integer 1..10; `engines?` "auto" or ("google" or "duckduckgo" or "yandex" or "avito") or list of ("google" or "duckduckgo" or "yandex" or "avito") 1..4; `summary?` boolean; `page?` integer >=1; `format?` "md" or "json" |
28
36
  | `web_read` | direct | `url` string; `offset?` integer >=0; `maxChars?` integer >=1; `format?` "md" or "text" |
29
37
  | `image_search` | deferred | `q` string; `n?` integer 1..12; `engine?` "google" or "yandex"; `attach?` boolean or "bytes" |
30
38
  | `web_research` | deferred | `q` string; `budget?` "quick" or "normal" or "deep" |
@@ -32,7 +40,14 @@ The window stays visible. The extension attaches to it and never launches, resta
32
40
  <!-- tools:end -->
33
41
 
34
42
  A call has one 60 second deadline. DuckDuckGo has no pagination: `page > 1` is reported as
35
- `ignored.page`. Every unresolved link stays marked `unresolved`.
43
+ `ignored.page`; Avito has no AI block: `summary` is reported as `ignored.summary`. Every unresolved
44
+ link stays marked `unresolved`, and card facts (price/availability/rating/location) render on their
45
+ own line after the snippet.
46
+
47
+ `engines: "auto"` only ever means Google → DuckDuckGo → Yandex. Avito is a *special* engine: it is off
48
+ by default and reachable only by naming it. To turn it on, set `engines.avito.enabled` to `true` (and
49
+ optionally `engines.avito.location`, a region slug such as `kaluga` or `all`) in
50
+ `~/.pi/agent/web-search.json` — ask your agent to do it, that is the intended path.
36
51
 
37
52
  ## Limits
38
53
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-chrome-search",
3
- "version": "2.0.0",
4
- "description": "Free, keyless web search through the user's own visible Chrome (Google, DuckDuckGo, Yandex) for pi",
3
+ "version": "2.1.0",
4
+ "description": "Free, keyless web search through the user's own visible Chrome (Google, DuckDuckGo, Yandex, and opt-in Avito listings) for pi",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "pi": {
@@ -45,7 +45,8 @@
45
45
  "web-search",
46
46
  "google",
47
47
  "duckduckgo",
48
- "yandex"
48
+ "yandex",
49
+ "avito"
49
50
  ],
50
51
  "files": [
51
52
  "index.ts",
@@ -48,10 +48,26 @@ export interface YandexConfig {
48
48
  lr: string;
49
49
  }
50
50
 
51
+ export interface AvitoConfig {
52
+ /**
53
+ * OFF by default (SPEC §15 D12): Avito is a *special* engine, so a fresh
54
+ * install must not touch its anti-bot machinery. Enabling it is one key in
55
+ * `web-search.json`; the disabled-engine hint names the file.
56
+ */
57
+ enabled: boolean;
58
+ /**
59
+ * Region path slug in the Avito URL (`all`, `moskva`, `kaluga`), not a display
60
+ * name. `all` = every region; Avito itself falls back to nearby regions with
61
+ * delivery when the item is not sold locally.
62
+ */
63
+ location: string;
64
+ }
65
+
51
66
  export interface EnginesConfig {
52
67
  google: GoogleConfig;
53
68
  duckduckgo: DuckDuckGoConfig;
54
69
  yandex: YandexConfig;
70
+ avito: AvitoConfig;
55
71
  }
56
72
 
57
73
  export type PacingWindow = [number, number];
@@ -60,6 +76,8 @@ export interface PacingConfig {
60
76
  google: PacingWindow;
61
77
  duckduckgo: PacingWindow;
62
78
  yandex: PacingWindow;
79
+ /** Slowest window: Avito is the most aggressive of the four about automation. */
80
+ avito: PacingWindow;
63
81
  }
64
82
 
65
83
  export interface SearchConfig {
@@ -130,8 +148,9 @@ export const DEFAULT_CONFIG: Config = {
130
148
  google: { enabled: true, lang: "auto", gl: "auto" },
131
149
  duckduckgo: { enabled: true, kl: "auto" },
132
150
  yandex: { enabled: true, lr: "auto" },
151
+ avito: { enabled: false, location: "all" },
133
152
  },
134
- pacing: { google: [2500, 5000], yandex: [5000, 9000], duckduckgo: [2000, 4000] },
153
+ pacing: { google: [2500, 5000], yandex: [5000, 9000], duckduckgo: [2000, 4000], avito: [6000, 12000] },
135
154
  search: {
136
155
  budgetMs: 60000,
137
156
  n: 5,
package/src/config/doc.ts CHANGED
@@ -28,9 +28,12 @@ const CONFIG_DOCS: Readonly<Record<string, string>> = {
28
28
  "engines.duckduckgo.kl": "Region/language; `auto` omits it.",
29
29
  "engines.yandex.enabled": "Use Yandex.",
30
30
  "engines.yandex.lr": "`lr`; `auto` omits it.",
31
+ "engines.avito.enabled": "Use the Avito marketplace engine (special: only an explicit `engines: \"avito\"` reaches it, `auto` never does). Off by default.",
32
+ "engines.avito.location": "Region path slug in the Avito URL (`all`, `moskva`, `kaluga`), not a display name.",
31
33
  "pacing.google": "Min/max gap in ms between Google searches.",
32
34
  "pacing.duckduckgo": "Min/max gap in ms between DuckDuckGo searches.",
33
35
  "pacing.yandex": "Min/max gap in ms between Yandex searches.",
36
+ "pacing.avito": "Min/max gap in ms between Avito searches.",
34
37
  "search.budgetMs": "Whole-call deadline in ms; pacing, settle, AI wait and link resolution draw from it (S8.1).",
35
38
  "search.n": "Default result count.",
36
39
  "search.nMax": "Hard ceiling for `n`; never above 10.",
@@ -54,6 +54,7 @@ export const CONFIG_SPEC: Spec = {
54
54
  google: { kind: "object", fields: { enabled: BOOL, lang: STRING_NE, gl: STRING_NE } },
55
55
  duckduckgo: { kind: "object", fields: { enabled: BOOL, kl: STRING_NE } },
56
56
  yandex: { kind: "object", fields: { enabled: BOOL, lr: STRING_NE } },
57
+ avito: { kind: "object", fields: { enabled: BOOL, location: STRING_NE } },
57
58
  },
58
59
  },
59
60
  pacing: {
@@ -62,6 +63,7 @@ export const CONFIG_SPEC: Spec = {
62
63
  google: { kind: "tuple", items: [NUM(0), NUM(0)] },
63
64
  duckduckgo: { kind: "tuple", items: [NUM(0), NUM(0)] },
64
65
  yandex: { kind: "tuple", items: [NUM(0), NUM(0)] },
66
+ avito: { kind: "tuple", items: [NUM(0), NUM(0)] },
65
67
  },
66
68
  },
67
69
  search: {