cliskill 1.0.0 → 1.0.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/README.md +159 -44
- package/dist/bootstrap/cli.js +1 -1
- package/dist/{chunk-ULZHJVWD.js → chunk-CBGJMMA3.js} +95 -16
- package/dist/chunk-CBGJMMA3.js.map +1 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.js +1 -1
- package/package.json +1 -2
- package/dist/chunk-ULZHJVWD.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
**Независимый AI-ассистент для терминала с поддержкой любых LLM провайдеров**
|
|
8
8
|
|
|
9
|
-
[]()
|
|
10
9
|
[](LICENSE)
|
|
11
|
-
[]()
|
|
12
11
|
[]()
|
|
13
12
|
|
|
14
13
|
[Бесплатный](#) · [Без подписок](#) · [Без vendor lock-in](#) · [Универсальный](#)
|
|
@@ -21,10 +20,13 @@
|
|
|
21
20
|
|
|
22
21
|
- [О проекте](#-о-проекте)
|
|
23
22
|
- [Возможности](#-возможности)
|
|
24
|
-
- [
|
|
23
|
+
- [Быстрый старт](#-быстрый-старт)
|
|
25
24
|
- [Использование](#-использование)
|
|
26
25
|
- [Конфигурация](#-конфигурация)
|
|
26
|
+
- [Инструменты](#-инструменты)
|
|
27
|
+
- [Агентская система](#-агентская-система)
|
|
27
28
|
- [Архитектура](#-архитектура)
|
|
29
|
+
- [API провайдеры](#-api-провайдеры)
|
|
28
30
|
- [Разработка](#-разработка)
|
|
29
31
|
- [Технологии](#-технологии)
|
|
30
32
|
- [Лицензия](#-лицензия)
|
|
@@ -58,37 +60,6 @@
|
|
|
58
60
|
- **Автоматический fallback** — переключение на резервные модели при ошибках
|
|
59
61
|
- **Rate Limit Handler** — корректная обработка лимитов без upsell
|
|
60
62
|
|
|
61
|
-
### 🔧 Инструменты (15 штук)
|
|
62
|
-
|
|
63
|
-
| Инструмент | Описание |
|
|
64
|
-
|------------|----------|
|
|
65
|
-
| 🖥️ **Bash Tool** | Выполнение shell команд с инспекцией безопасности |
|
|
66
|
-
| 📄 **File Read** | Чтение файлов с поддержкой изображений |
|
|
67
|
-
| ✏️ **File Write** | Создание и перезапись файлов |
|
|
68
|
-
| 📝 **File Edit** | Точечное редактирование файлов (search/replace) |
|
|
69
|
-
| 🔍 **Glob** | Поиск файлов по паттернам |
|
|
70
|
-
| 🔎 **Grep** | Поиск текста с поддержкой regex |
|
|
71
|
-
| 🌐 **Web Search** | Веб-поиск через поисковые системы |
|
|
72
|
-
| 🌍 **Web Fetch** | Загрузка и парсинг веб-страниц |
|
|
73
|
-
| 🤖 **Agent Tool** | Порождение суб-агентов для подзадач |
|
|
74
|
-
| 📡 **LSP Tool** | Интеграция с Language Server Protocol |
|
|
75
|
-
| ✅ **Todo Write** | Управление списками задач |
|
|
76
|
-
| 🖱️ **Computer Use** | Управление мышью и клавиатурой |
|
|
77
|
-
| 🔗 **Remote Tool** | Выполнение команд на удалённых серверах через SSH |
|
|
78
|
-
| 🌳 **Worktree Tool** | Управление git worktree для параллельной работы |
|
|
79
|
-
| 📋 **Plan Mode** | Планирование с 3 параллельными агентами |
|
|
80
|
-
|
|
81
|
-
### 🤖 Агентская система
|
|
82
|
-
|
|
83
|
-
- **Auto Mode** — 3 уровня автономности:
|
|
84
|
-
- `full-auto` — полная автономия, все действия без подтверждения
|
|
85
|
-
- `safe-auto` — автоматическое выполнение безопасных операций
|
|
86
|
-
- `ask` — подтверждение каждого действия (по умолчанию)
|
|
87
|
-
- **Fast Mode** — оптимизации скорости ответов
|
|
88
|
-
- **Multi-Agent Plan Mode V2** — 3 параллельных агента для планирования
|
|
89
|
-
- **Swarm Coordinator** — мульти-агентная координация сложных задач
|
|
90
|
-
- **Task System** — фоновые задачи с отслеживанием статуса
|
|
91
|
-
|
|
92
63
|
### 🏗️ Инфраструктура
|
|
93
64
|
|
|
94
65
|
| Система | Описание |
|
|
@@ -105,7 +76,7 @@
|
|
|
105
76
|
### 🛠️ Утилиты
|
|
106
77
|
|
|
107
78
|
- 🎬 **Asciicast Recording** — запись сессий в формате asciicast v2
|
|
108
|
-
- 🎨 **ANSI→SVG** —
|
|
79
|
+
- 🎨 **ANSI→SVG** — рендеринг терминального вывода в SVG
|
|
109
80
|
- 🔄 **Conversation Recovery** — умное восстановление сессий с ремонтом
|
|
110
81
|
- 🔗 **Deep Links** — протокол `cliskill://` для интеграции с ОС
|
|
111
82
|
- 🧹 **Background Housekeeping** — автоматическая очистка и обслуживание
|
|
@@ -116,13 +87,13 @@
|
|
|
116
87
|
|
|
117
88
|
---
|
|
118
89
|
|
|
119
|
-
## 📦
|
|
90
|
+
## 📦 Быстрый старт
|
|
120
91
|
|
|
121
|
-
###
|
|
92
|
+
### Установка из исходников
|
|
122
93
|
|
|
123
94
|
```bash
|
|
124
95
|
# Клонирование репозитория
|
|
125
|
-
git clone
|
|
96
|
+
git clone https://github.com/nic11/cliskill.git
|
|
126
97
|
cd cliskill
|
|
127
98
|
|
|
128
99
|
# Установка зависимостей
|
|
@@ -135,11 +106,27 @@ npm run build
|
|
|
135
106
|
npm link
|
|
136
107
|
```
|
|
137
108
|
|
|
109
|
+
### Установка из npm
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm install -g cliskill
|
|
113
|
+
```
|
|
114
|
+
|
|
138
115
|
### Требования
|
|
139
116
|
|
|
140
117
|
- **Node.js** >= 20.0.0
|
|
141
118
|
- **npm** >= 9.0.0
|
|
142
119
|
|
|
120
|
+
### Первый запуск
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Интерактивный мастер настройки
|
|
124
|
+
cliskill
|
|
125
|
+
|
|
126
|
+
# Или с явным указанием провайдера
|
|
127
|
+
cliskill --base-url https://api.example.com/v1 --api-key your-key
|
|
128
|
+
```
|
|
129
|
+
|
|
143
130
|
---
|
|
144
131
|
|
|
145
132
|
## 🚀 Использование
|
|
@@ -289,8 +276,8 @@ cliskill open-uri "cliskill://prompt?text=hello" # обработать URI
|
|
|
289
276
|
### Переменные окружения
|
|
290
277
|
|
|
291
278
|
```bash
|
|
292
|
-
export CLISKILL_API_KEY="
|
|
293
|
-
export CLISKILL_BASE_URL="https://api.
|
|
279
|
+
export CLISKILL_API_KEY="your-api-key"
|
|
280
|
+
export CLISKILL_BASE_URL="https://api.example.com/v1"
|
|
294
281
|
```
|
|
295
282
|
|
|
296
283
|
### Форматы провайдеров
|
|
@@ -326,6 +313,68 @@ description: Описание навыка
|
|
|
326
313
|
|
|
327
314
|
---
|
|
328
315
|
|
|
316
|
+
## 🔧 Инструменты
|
|
317
|
+
|
|
318
|
+
cliskill включает 15 встроенных инструментов для полноценной работы:
|
|
319
|
+
|
|
320
|
+
| # | Инструмент | Описание | Категория |
|
|
321
|
+
|---|------------|----------|-----------|
|
|
322
|
+
| 1 | 🖥️ **Bash** | Выполнение shell команд с инспекцией безопасности | Выполнение |
|
|
323
|
+
| 2 | 📄 **File Read** | Чтение файлов с поддержкой изображений | Файлы |
|
|
324
|
+
| 3 | ✏️ **File Write** | Создание и перезапись файлов | Файлы |
|
|
325
|
+
| 4 | 📝 **File Edit** | Точечное редактирование файлов (search/replace) | Файлы |
|
|
326
|
+
| 5 | 🔍 **Glob** | Поиск файлов по паттернам | Поиск |
|
|
327
|
+
| 6 | 🔎 **Grep** | Поиск текста с поддержкой regex | Поиск |
|
|
328
|
+
| 7 | 🌐 **Web Search** | Веб-поиск через поисковые системы | Веб |
|
|
329
|
+
| 8 | 🌍 **Web Fetch** | Загрузка и парсинг веб-страниц | Веб |
|
|
330
|
+
| 9 | 🤖 **Agent** | Порождение суб-агентов для подзадач | Агенты |
|
|
331
|
+
| 10 | 📡 **LSP** | Интеграция с Language Server Protocol | IDE |
|
|
332
|
+
| 11 | ✅ **Todo Write** | Управление списками задач | Планирование |
|
|
333
|
+
| 12 | 🖱️ **Computer Use** | Управление мышью и клавиатурой | Автоматизация |
|
|
334
|
+
| 13 | 🔗 **Remote** | Выполнение команд на удалённых серверах через SSH | Удалённый доступ |
|
|
335
|
+
| 14 | 🌳 **Worktree** | Управление git worktree для параллельной работы | Git |
|
|
336
|
+
| 15 | 📋 **Plan Mode** | Планирование с 3 параллельными агентами | Планирование |
|
|
337
|
+
|
|
338
|
+
### Безопасность инструментов
|
|
339
|
+
|
|
340
|
+
Инструменты классифицируются по уровню безопасности:
|
|
341
|
+
|
|
342
|
+
- **readOnly** (Glob, Grep, File Read, LSP) — могут выполняться параллельно
|
|
343
|
+
- **write** (File Write, File Edit, Bash) — выполняются эксклюзивно
|
|
344
|
+
- **network** (Web Search, Web Fetch) — контролируемые сетевые операции
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 🤖 Агентская система
|
|
349
|
+
|
|
350
|
+
### Auto Mode
|
|
351
|
+
|
|
352
|
+
3 уровня автономности для автоматического выполнения задач:
|
|
353
|
+
|
|
354
|
+
| Уровень | Описание | Подтверждение |
|
|
355
|
+
|---------|----------|---------------|
|
|
356
|
+
| `full-auto` | Полная автономия | Все действия без подтверждения |
|
|
357
|
+
| `safe-auto` | Безопасная автономия | Только потенциально опасные операции |
|
|
358
|
+
| `ask` | Ручное управление | Каждое действие (по умолчанию) |
|
|
359
|
+
|
|
360
|
+
### Multi-Agent система
|
|
361
|
+
|
|
362
|
+
- **Fast Mode** — оптимизации скорости ответов
|
|
363
|
+
- **Multi-Agent Plan Mode V2** — 3 параллельных агента для планирования
|
|
364
|
+
- **Swarm Coordinator** — мульти-агентная координация сложных задач
|
|
365
|
+
- **Task System** — фоновые задачи с отслеживанием статуса
|
|
366
|
+
|
|
367
|
+
### Agent Loop
|
|
368
|
+
|
|
369
|
+
Ядро системы — агентский цикл с поддержкой:
|
|
370
|
+
|
|
371
|
+
- **Streaming** — потоковая обработка ответов LLM
|
|
372
|
+
- **Tool calling** — параллельный вызов инструментов
|
|
373
|
+
- **Error recovery** — 3-уровневая стратегия восстановления при `max_tokens`
|
|
374
|
+
- **Context management** — автоматическое сжатие при переполнении контекста
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
329
378
|
## 🏛️ Архитектура
|
|
330
379
|
|
|
331
380
|
```
|
|
@@ -344,7 +393,7 @@ src/
|
|
|
344
393
|
├── 🐝 swarm/ — Мульти-агентная координация
|
|
345
394
|
├── 📋 tasks/ — Фоновые задачи
|
|
346
395
|
├── 🔗 remote/ — SSH сессии
|
|
347
|
-
├── 🧩 extensions/ — Расширения
|
|
396
|
+
├── 🧩 extensions/ — Расширения и навыки
|
|
348
397
|
├── 🏗️ infra/ — Инфраструктурные модули
|
|
349
398
|
└── 🔀 utils/ — Общие утилиты
|
|
350
399
|
```
|
|
@@ -372,6 +421,60 @@ graph TB
|
|
|
372
421
|
Swarm --> Tasks[Task System]
|
|
373
422
|
```
|
|
374
423
|
|
|
424
|
+
### Поток данных
|
|
425
|
+
|
|
426
|
+
```mermaid
|
|
427
|
+
sequenceDiagram
|
|
428
|
+
participant U as User
|
|
429
|
+
participant R as REPL/TUI
|
|
430
|
+
participant L as Agent Loop
|
|
431
|
+
participant P as Provider Adapter
|
|
432
|
+
participant T as Tool System
|
|
433
|
+
|
|
434
|
+
U->>R: Ввод запроса
|
|
435
|
+
R->>L: Передача сообщения
|
|
436
|
+
L->>P: API запрос (streaming)
|
|
437
|
+
P-->>L: Потоковый ответ
|
|
438
|
+
L->>T: Вызов инструментов
|
|
439
|
+
T-->>L: Результат выполнения
|
|
440
|
+
L->>P: Продолжение диалога
|
|
441
|
+
P-->>L: Финальный ответ
|
|
442
|
+
L-->>R: Событие результата
|
|
443
|
+
R-->>U: Отображение ответа
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## 🌐 API провайдеры
|
|
449
|
+
|
|
450
|
+
### Поддерживаемые форматы
|
|
451
|
+
|
|
452
|
+
cliskill работает с **любым** API, совместимым с OpenAI `/chat/completions`:
|
|
453
|
+
|
|
454
|
+
| Провайдер | Base URL | Формат |
|
|
455
|
+
|-----------|----------|--------|
|
|
456
|
+
| OpenAI | `https://api.openai.com/v1` | `openai-compatible` |
|
|
457
|
+
| GLM / Z.AI | `https://api.z.ai/api/coding/paas/v4` | `openai-compatible` |
|
|
458
|
+
| DeepSeek | `https://api.deepseek.com/v1` | `openai-compatible` |
|
|
459
|
+
| LocalAI | `http://localhost:8080/v1` | `openai-compatible` |
|
|
460
|
+
| Ollama | `http://localhost:11434/v1` | `openai-compatible` |
|
|
461
|
+
| LM Studio | `http://localhost:1234/v1` | `openai-compatible` |
|
|
462
|
+
| Любой другой | `<your-endpoint>/v1` | `openai-compatible` |
|
|
463
|
+
|
|
464
|
+
### Модель алиасов
|
|
465
|
+
|
|
466
|
+
Предустановленные алиасы для быстрого переключения моделей:
|
|
467
|
+
|
|
468
|
+
| Алиас | Описание | Модель по умолчанию |
|
|
469
|
+
|-------|----------|---------------------|
|
|
470
|
+
| `smart` | Максимальное качество | `gpt-4o` |
|
|
471
|
+
| `fast` | Быстрые ответы | `gpt-4o-mini` |
|
|
472
|
+
| `balanced` | Баланс качества/скорости | `gpt-4o` |
|
|
473
|
+
| `reasoning` | Логические задачи | `o1` |
|
|
474
|
+
| `code` | Код-специфичные задачи | `gpt-4o` |
|
|
475
|
+
|
|
476
|
+
Алиасы настраиваются в `.cliskillrc.json` → `models.aliases`.
|
|
477
|
+
|
|
375
478
|
---
|
|
376
479
|
|
|
377
480
|
## 👨💻 Разработка
|
|
@@ -382,7 +485,7 @@ graph TB
|
|
|
382
485
|
npm install # Установить зависимости
|
|
383
486
|
npm run build # Сборка проекта (tsup)
|
|
384
487
|
npm run dev # Разработка с watch-режимом
|
|
385
|
-
npm test # Запустить тесты (
|
|
488
|
+
npm test # Запустить тесты (Vitest)
|
|
386
489
|
npm run test:watch # Тесты в watch-режиме
|
|
387
490
|
npm run typecheck # Проверка типов TypeScript
|
|
388
491
|
npm run lint # Линтинг (= typecheck)
|
|
@@ -423,6 +526,19 @@ src/
|
|
|
423
526
|
└── bash-parser.ts / .test.ts
|
|
424
527
|
```
|
|
425
528
|
|
|
529
|
+
### Добавление нового инструмента
|
|
530
|
+
|
|
531
|
+
1. Создайте файл в `src/tools/builtins/your-tool.ts`
|
|
532
|
+
2. Реализуйте интерфейс `Tool` из `src/tools/types.ts`
|
|
533
|
+
3. Зарегистрируйте в `src/tools/builtins/index.ts`
|
|
534
|
+
4. Добавьте тесты `your-tool.test.ts`
|
|
535
|
+
|
|
536
|
+
### Добавление нового провайдера
|
|
537
|
+
|
|
538
|
+
1. Создайте адаптер в `src/connect/your-adapter.ts`
|
|
539
|
+
2. Реализуйте интерфейс `ProviderAdapter` из `src/connect/types.ts`
|
|
540
|
+
3. Зарегистрируйте в `src/connect/registry.ts`
|
|
541
|
+
|
|
426
542
|
---
|
|
427
543
|
|
|
428
544
|
## 🧪 Технологии
|
|
@@ -445,14 +561,13 @@ src/
|
|
|
445
561
|
| [Ink](https://github.com/vadimdemedes/ink) / [React](https://react.dev) | Terminal UI |
|
|
446
562
|
| [Ora](https://github.com/sindresorhus/ora) | Спиннеры загрузки |
|
|
447
563
|
| [ssh2](https://github.com/mscdex/ssh2) | SSH подключения |
|
|
448
|
-
| [dotenv](https://github.com/motdotla/dotenv) | Переменные окружения |
|
|
449
564
|
|
|
450
565
|
### Dev-зависимости
|
|
451
566
|
|
|
452
567
|
| Библиотека | Назначение |
|
|
453
568
|
|------------|------------|
|
|
454
569
|
| [tsup](https://tsup.egoist.dev) | Сборка (esbuild-based) |
|
|
455
|
-
| [Vitest](https://vitest.dev) | Тестирование
|
|
570
|
+
| [Vitest](https://vitest.dev) | Тестирование |
|
|
456
571
|
| [TypeScript](https://www.typescriptlang.org) | Компилятор и проверка типов |
|
|
457
572
|
|
|
458
573
|
---
|
package/dist/bootstrap/cli.js
CHANGED
|
@@ -2061,14 +2061,16 @@ import { z as z13 } from "zod";
|
|
|
2061
2061
|
var webSearchInputSchema = z13.object({
|
|
2062
2062
|
query: z13.string().describe("Search query"),
|
|
2063
2063
|
max_results: z13.number().default(5).describe("Maximum number of results"),
|
|
2064
|
-
search_engine: z13.enum(["duckduckgo", "
|
|
2064
|
+
search_engine: z13.enum(["duckduckgo", "wikipedia"]).default("duckduckgo").describe("Search engine to use")
|
|
2065
2065
|
});
|
|
2066
2066
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
2067
2067
|
var DDG_HTML_URL = "https://html.duckduckgo.com/html/?q=";
|
|
2068
2068
|
var DDG_LITE_URL = "https://lite.duckduckgo.com/lite/?q=";
|
|
2069
|
+
var WIKI_API_URL = "https://en.wikipedia.org/w/api.php";
|
|
2069
2070
|
var COMMON_HEADERS = {
|
|
2070
|
-
"User-Agent": "Mozilla/5.0 (
|
|
2071
|
-
Accept: "text/html"
|
|
2071
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
2072
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
2073
|
+
"Accept-Language": "en-US,en;q=0.5"
|
|
2072
2074
|
};
|
|
2073
2075
|
function parseDuckDuckGoHtml(html, maxResults) {
|
|
2074
2076
|
const results = [];
|
|
@@ -2120,6 +2122,15 @@ function parseDuckDuckGoLite(html, maxResults) {
|
|
|
2120
2122
|
}
|
|
2121
2123
|
return results;
|
|
2122
2124
|
}
|
|
2125
|
+
function parseWikipediaResults(data, maxResults) {
|
|
2126
|
+
const search = data.query?.search;
|
|
2127
|
+
if (!search) return [];
|
|
2128
|
+
return search.slice(0, maxResults).map((item) => ({
|
|
2129
|
+
title: item.title,
|
|
2130
|
+
url: `https://en.wikipedia.org/wiki/${encodeURIComponent(item.title.replace(/ /g, "_"))}`,
|
|
2131
|
+
snippet: stripTags(item.snippet)
|
|
2132
|
+
}));
|
|
2133
|
+
}
|
|
2123
2134
|
function stripTags(html) {
|
|
2124
2135
|
return html.replace(/<[^>]+>/g, "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, " ").trim();
|
|
2125
2136
|
}
|
|
@@ -2141,13 +2152,13 @@ No results found. Try rephrasing your query or use web_fetch for specific URLs.`
|
|
|
2141
2152
|
}
|
|
2142
2153
|
return lines.join("\n").trim();
|
|
2143
2154
|
}
|
|
2144
|
-
async function fetchWithTimeout(url) {
|
|
2155
|
+
async function fetchWithTimeout(url, headers) {
|
|
2145
2156
|
const controller = new AbortController();
|
|
2146
2157
|
const timeout = setTimeout(() => controller.abort(), SEARCH_TIMEOUT_MS);
|
|
2147
2158
|
try {
|
|
2148
2159
|
const response = await fetch(url, {
|
|
2149
2160
|
signal: controller.signal,
|
|
2150
|
-
headers: COMMON_HEADERS,
|
|
2161
|
+
headers: headers ?? COMMON_HEADERS,
|
|
2151
2162
|
redirect: "follow"
|
|
2152
2163
|
});
|
|
2153
2164
|
return response;
|
|
@@ -2157,32 +2168,58 @@ async function fetchWithTimeout(url) {
|
|
|
2157
2168
|
}
|
|
2158
2169
|
var WebSearchTool = class extends BaseTool {
|
|
2159
2170
|
name = "web_search";
|
|
2160
|
-
description = "Search the web for information";
|
|
2171
|
+
description = "Search the web for information using DuckDuckGo or Wikipedia";
|
|
2161
2172
|
inputSchema = webSearchInputSchema;
|
|
2162
2173
|
riskLevel = "safe";
|
|
2163
2174
|
concurrencySafe = true;
|
|
2164
2175
|
readOnly = true;
|
|
2165
2176
|
async execute(input, _context) {
|
|
2166
|
-
if (input.search_engine !== "duckduckgo") {
|
|
2167
|
-
return `Error: Only DuckDuckGo search engine is currently supported. Use web_fetch for other sources.`;
|
|
2168
|
-
}
|
|
2169
2177
|
const encodedQuery = encodeURIComponent(input.query);
|
|
2178
|
+
if (input.search_engine === "wikipedia") {
|
|
2179
|
+
return this.searchWikipedia(input.query, encodedQuery, input.max_results);
|
|
2180
|
+
}
|
|
2181
|
+
return this.searchDuckDuckGo(input.query, encodedQuery, input.max_results);
|
|
2182
|
+
}
|
|
2183
|
+
async searchDuckDuckGo(query, encodedQuery, maxResults) {
|
|
2170
2184
|
try {
|
|
2171
2185
|
const response = await fetchWithTimeout(`${DDG_HTML_URL}${encodedQuery}`);
|
|
2172
2186
|
if (!response.ok) {
|
|
2173
|
-
return
|
|
2187
|
+
return this.fallbackToWikipedia(
|
|
2188
|
+
query,
|
|
2189
|
+
encodedQuery,
|
|
2190
|
+
maxResults,
|
|
2191
|
+
`DuckDuckGo returned HTTP ${response.status}`
|
|
2192
|
+
);
|
|
2174
2193
|
}
|
|
2175
2194
|
const html = await response.text();
|
|
2176
|
-
let results = parseDuckDuckGoHtml(html,
|
|
2195
|
+
let results = parseDuckDuckGoHtml(html, maxResults);
|
|
2196
|
+
if (results.length === 0) {
|
|
2197
|
+
results = await this.fallbackLiteSearch(encodedQuery, maxResults);
|
|
2198
|
+
}
|
|
2177
2199
|
if (results.length === 0) {
|
|
2178
|
-
|
|
2200
|
+
return this.fallbackToWikipedia(
|
|
2201
|
+
query,
|
|
2202
|
+
encodedQuery,
|
|
2203
|
+
maxResults,
|
|
2204
|
+
"DuckDuckGo returned no results"
|
|
2205
|
+
);
|
|
2179
2206
|
}
|
|
2180
|
-
return formatResults(
|
|
2207
|
+
return formatResults(query, results);
|
|
2181
2208
|
} catch (err) {
|
|
2182
2209
|
if (err.name === "AbortError") {
|
|
2183
|
-
return
|
|
2210
|
+
return this.fallbackToWikipedia(
|
|
2211
|
+
query,
|
|
2212
|
+
encodedQuery,
|
|
2213
|
+
maxResults,
|
|
2214
|
+
"DuckDuckGo request timed out"
|
|
2215
|
+
);
|
|
2184
2216
|
}
|
|
2185
|
-
return
|
|
2217
|
+
return this.fallbackToWikipedia(
|
|
2218
|
+
query,
|
|
2219
|
+
encodedQuery,
|
|
2220
|
+
maxResults,
|
|
2221
|
+
err.message
|
|
2222
|
+
);
|
|
2186
2223
|
}
|
|
2187
2224
|
}
|
|
2188
2225
|
async fallbackLiteSearch(encodedQuery, maxResults) {
|
|
@@ -2195,6 +2232,48 @@ var WebSearchTool = class extends BaseTool {
|
|
|
2195
2232
|
return [];
|
|
2196
2233
|
}
|
|
2197
2234
|
}
|
|
2235
|
+
async searchWikipedia(query, encodedQuery, maxResults) {
|
|
2236
|
+
try {
|
|
2237
|
+
const url = `${WIKI_API_URL}?action=query&list=search&srsearch=${encodedQuery}&srlimit=${maxResults}&format=json&origin=*`;
|
|
2238
|
+
const response = await fetchWithTimeout(url, {
|
|
2239
|
+
"User-Agent": "cliskill/1.0 (https://github.com/nic11/cliskill)"
|
|
2240
|
+
});
|
|
2241
|
+
if (!response.ok) {
|
|
2242
|
+
return `Error: Wikipedia search failed with HTTP ${response.status}. Try web_fetch instead.`;
|
|
2243
|
+
}
|
|
2244
|
+
const data = await response.json();
|
|
2245
|
+
const results = parseWikipediaResults(data, maxResults);
|
|
2246
|
+
return formatResults(query, results);
|
|
2247
|
+
} catch (err) {
|
|
2248
|
+
if (err.name === "AbortError") {
|
|
2249
|
+
return "Error: Wikipedia search timed out after 15 seconds. Try web_fetch instead.";
|
|
2250
|
+
}
|
|
2251
|
+
return `Error searching Wikipedia: ${err.message}. Try web_fetch instead.`;
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
async fallbackToWikipedia(query, encodedQuery, maxResults, reason) {
|
|
2255
|
+
const wikiResults = await this.searchWikipediaRaw(encodedQuery, maxResults);
|
|
2256
|
+
if (wikiResults.length > 0) {
|
|
2257
|
+
const header = `\u26A0\uFE0F DuckDuckGo unavailable (${reason}). Showing Wikipedia results:
|
|
2258
|
+
|
|
2259
|
+
`;
|
|
2260
|
+
return header + formatResults(query, wikiResults);
|
|
2261
|
+
}
|
|
2262
|
+
return `Error: Search failed (${reason}) and Wikipedia fallback returned no results. Try web_fetch for specific URLs.`;
|
|
2263
|
+
}
|
|
2264
|
+
async searchWikipediaRaw(encodedQuery, maxResults) {
|
|
2265
|
+
try {
|
|
2266
|
+
const url = `${WIKI_API_URL}?action=query&list=search&srsearch=${encodedQuery}&srlimit=${maxResults}&format=json&origin=*`;
|
|
2267
|
+
const response = await fetchWithTimeout(url, {
|
|
2268
|
+
"User-Agent": "cliskill/1.0 (https://github.com/nic11/cliskill)"
|
|
2269
|
+
});
|
|
2270
|
+
if (!response.ok) return [];
|
|
2271
|
+
const data = await response.json();
|
|
2272
|
+
return parseWikipediaResults(data, maxResults);
|
|
2273
|
+
} catch {
|
|
2274
|
+
return [];
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2198
2277
|
};
|
|
2199
2278
|
|
|
2200
2279
|
// src/tools/builtins/lsp-tool.ts
|
|
@@ -9942,4 +10021,4 @@ export {
|
|
|
9942
10021
|
MessageList,
|
|
9943
10022
|
runCli
|
|
9944
10023
|
};
|
|
9945
|
-
//# sourceMappingURL=chunk-
|
|
10024
|
+
//# sourceMappingURL=chunk-CBGJMMA3.js.map
|