@pi-unipi/unipi 2.6.1 → 2.6.2

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 (186) hide show
  1. package/package.json +1 -2
  2. package/packages/ask-user/settings-tui.ts +18 -34
  3. package/packages/autocomplete/src/constants.ts +0 -15
  4. package/packages/autocomplete/src/provider.ts +3 -17
  5. package/packages/btw/extensions/btw.ts +18 -45
  6. package/packages/compactor/README.md +2 -2
  7. package/packages/compactor/skills/compactor/SKILL.md +1 -1
  8. package/packages/compactor/skills/compactor-detail/SKILL.md +3 -5
  9. package/packages/compactor/skills/compactor-doctor/SKILL.md +1 -1
  10. package/packages/compactor/skills/compactor-stats/SKILL.md +1 -1
  11. package/packages/compactor/src/commands/index.ts +47 -78
  12. package/packages/compactor/src/compaction/brief.ts +161 -90
  13. package/packages/compactor/src/compaction/build-sections.ts +3 -4
  14. package/packages/compactor/src/compaction/compact-args.ts +86 -0
  15. package/packages/compactor/src/compaction/cut.ts +270 -28
  16. package/packages/compactor/src/compaction/drill-down.ts +261 -0
  17. package/packages/compactor/src/compaction/format-recall.ts +96 -0
  18. package/packages/compactor/src/compaction/format.ts +8 -3
  19. package/packages/compactor/src/compaction/hooks.ts +248 -72
  20. package/packages/compactor/src/compaction/merge.ts +34 -4
  21. package/packages/compactor/src/compaction/rank.ts +270 -0
  22. package/packages/compactor/src/compaction/recall-scope.ts +28 -0
  23. package/packages/compactor/src/compaction/search-entries.ts +333 -96
  24. package/packages/compactor/src/compaction/skill-collapse.ts +35 -0
  25. package/packages/compactor/src/compaction/summarize.ts +37 -6
  26. package/packages/compactor/src/compaction/token-estimate.ts +104 -0
  27. package/packages/compactor/src/compaction/touched-files.ts +35 -0
  28. package/packages/compactor/src/config/manager.ts +2 -27
  29. package/packages/compactor/src/config/presets.ts +0 -2
  30. package/packages/compactor/src/config/schema.ts +2 -16
  31. package/packages/compactor/src/executor/executor.ts +6 -15
  32. package/packages/compactor/src/executor/runtime.ts +2 -12
  33. package/packages/compactor/src/index.ts +4 -121
  34. package/packages/compactor/src/info-screen.ts +3 -10
  35. package/packages/compactor/src/security/evaluator.ts +0 -53
  36. package/packages/compactor/src/security/policy.ts +7 -8
  37. package/packages/compactor/src/session/db.ts +0 -6
  38. package/packages/compactor/src/tools/ctx-execute-file.ts +0 -5
  39. package/packages/compactor/src/tools/register.ts +27 -50
  40. package/packages/compactor/src/tools/vcc-recall.ts +86 -48
  41. package/packages/compactor/src/tui/settings-overlay.ts +20 -40
  42. package/packages/compactor/src/types.ts +43 -100
  43. package/packages/core/constants.ts +0 -28
  44. package/packages/core/events.ts +1 -83
  45. package/packages/core/index.ts +1 -0
  46. package/packages/core/package.json +2 -0
  47. package/packages/core/tui-overlay.ts +89 -0
  48. package/packages/core/tui-width.ts +18 -0
  49. package/packages/core/utils.ts +43 -0
  50. package/packages/footer/src/help.ts +2 -2
  51. package/packages/footer/src/index.ts +9 -10
  52. package/packages/footer/src/presets.ts +1 -27
  53. package/packages/footer/src/registry/index.ts +0 -23
  54. package/packages/footer/src/rendering/icons.ts +0 -13
  55. package/packages/footer/src/rendering/renderer.ts +5 -40
  56. package/packages/footer/src/rendering/separators.ts +0 -10
  57. package/packages/footer/src/rendering/theme.ts +1 -15
  58. package/packages/footer/src/segments/compactor.ts +7 -14
  59. package/packages/footer/src/segments/core.ts +15 -54
  60. package/packages/footer/src/segments/kanboard.ts +5 -5
  61. package/packages/footer/src/segments/mcp.ts +5 -5
  62. package/packages/footer/src/segments/memory.ts +4 -4
  63. package/packages/footer/src/segments/notify.ts +2 -2
  64. package/packages/footer/src/segments/ralph.ts +3 -3
  65. package/packages/footer/src/segments/status-ext.ts +1 -1
  66. package/packages/footer/src/segments/workflow.ts +3 -3
  67. package/packages/footer/src/tps-tracker.ts +0 -8
  68. package/packages/footer/src/tui/settings-tui.ts +14 -31
  69. package/packages/footer/src/types.ts +0 -15
  70. package/packages/image/src/register-providers.ts +0 -11
  71. package/packages/image/src/tools.ts +0 -3
  72. package/packages/image/src/tui/model-selector.ts +36 -71
  73. package/packages/info-screen/config.ts +0 -16
  74. package/packages/info-screen/core-groups.ts +0 -10
  75. package/packages/info-screen/index.ts +22 -13
  76. package/packages/info-screen/registry.ts +1 -72
  77. package/packages/info-screen/tui/info-overlay.ts +85 -100
  78. package/packages/info-screen/usage-parser.ts +12 -47
  79. package/packages/input-shortcuts/src/index.ts +3 -3
  80. package/packages/input-shortcuts/src/registers.ts +0 -8
  81. package/packages/input-shortcuts/src/settings-overlay.ts +4 -13
  82. package/packages/input-shortcuts/src/undo-redo.ts +0 -12
  83. package/packages/mcp/src/bridge/client.ts +0 -15
  84. package/packages/mcp/src/config/manager.ts +0 -38
  85. package/packages/mcp/src/config/schema.ts +0 -27
  86. package/packages/mcp/src/config/sync.ts +0 -29
  87. package/packages/mcp/src/index.ts +1 -1
  88. package/packages/mcp/src/tui/add-overlay.ts +6 -6
  89. package/packages/mcp/src/types.ts +0 -6
  90. package/packages/memory/embedding.ts +0 -31
  91. package/packages/memory/mempalace.ts +0 -16
  92. package/packages/memory/package.json +2 -6
  93. package/packages/memory/storage.ts +56 -753
  94. package/packages/milestone/hooks.ts +1 -6
  95. package/packages/milestone/milestone.ts +2 -41
  96. package/packages/notify/events.ts +0 -10
  97. package/packages/notify/settings.ts +0 -19
  98. package/packages/notify/tui/gotify-setup.ts +108 -143
  99. package/packages/notify/tui/ntfy-setup.ts +137 -172
  100. package/packages/notify/tui/recap-model-selector.ts +36 -71
  101. package/packages/notify/tui/settings-overlay.ts +50 -86
  102. package/packages/notify/tui/telegram-setup.ts +48 -79
  103. package/packages/notify/types.ts +0 -2
  104. package/packages/ralph/index.ts +11 -35
  105. package/packages/ralph/ralph-loop.ts +3 -44
  106. package/packages/subagents/package.json +1 -0
  107. package/packages/subagents/src/agent-manager.ts +0 -51
  108. package/packages/subagents/src/agent-runner.ts +6 -80
  109. package/packages/subagents/src/conversation-viewer.ts +1 -19
  110. package/packages/subagents/src/core-compat.ts +8 -25
  111. package/packages/subagents/src/custom-agents.ts +0 -1
  112. package/packages/subagents/src/index.ts +3 -48
  113. package/packages/subagents/src/types.ts +0 -11
  114. package/packages/subagents/src/widget.ts +5 -5
  115. package/packages/unipi/bundled.js +4330 -7707
  116. package/packages/unipi/index.ts +6 -3
  117. package/packages/updater/src/changelog.ts +1 -16
  118. package/packages/updater/src/index.ts +0 -5
  119. package/packages/updater/src/installer.ts +4 -26
  120. package/packages/updater/src/markdown.ts +6 -152
  121. package/packages/updater/src/settings.ts +0 -15
  122. package/packages/updater/src/tui/changelog-overlay.ts +42 -234
  123. package/packages/updater/src/tui/list-detail-overlay.ts +260 -0
  124. package/packages/updater/src/tui/readme-overlay.ts +53 -210
  125. package/packages/updater/src/tui/settings-overlay.ts +13 -26
  126. package/packages/updater/src/version.ts +2 -31
  127. package/packages/utility/package.json +1 -3
  128. package/packages/utility/src/commands.ts +4 -5
  129. package/packages/utility/src/herdr-sync.ts +136 -0
  130. package/packages/utility/src/index.ts +11 -68
  131. package/packages/utility/src/lifecycle/cleanup.ts +2 -16
  132. package/packages/utility/src/{diff/settings.ts → settings.ts} +42 -80
  133. package/packages/utility/src/tools/env.ts +0 -0
  134. package/packages/utility/src/tui/name-badge-state.ts +18 -2
  135. package/packages/utility/src/tui/name-badge.ts +5 -4
  136. package/packages/utility/src/tui/util-settings-tui.ts +41 -224
  137. package/packages/web-api/package.json +0 -4
  138. package/packages/web-api/src/engine/dependencies.ts +13 -134
  139. package/packages/web-api/src/engine/extract.ts +9 -99
  140. package/packages/web-api/src/engine/format.ts +0 -75
  141. package/packages/web-api/src/engine/types.ts +0 -39
  142. package/packages/web-api/src/index.ts +1 -2
  143. package/packages/web-api/src/providers/base.ts +0 -10
  144. package/packages/web-api/src/providers/duckduckgo.ts +0 -1
  145. package/packages/web-api/src/providers/firecrawl.ts +0 -9
  146. package/packages/web-api/src/providers/jina-reader.ts +0 -9
  147. package/packages/web-api/src/providers/jina-search.ts +0 -9
  148. package/packages/web-api/src/providers/perplexity.ts +0 -9
  149. package/packages/web-api/src/providers/registry.ts +0 -80
  150. package/packages/web-api/src/providers/serpapi.ts +0 -9
  151. package/packages/web-api/src/providers/tavily.ts +0 -9
  152. package/packages/web-api/src/providers/wigolo-client.ts +0 -30
  153. package/packages/web-api/src/providers/wigolo.ts +0 -1
  154. package/packages/web-api/src/settings.ts +17 -77
  155. package/packages/web-api/src/tools.ts +21 -24
  156. package/packages/web-api/src/tui/settings-dialog.ts +0 -1
  157. package/packages/workflow/commands.ts +38 -122
  158. package/packages/workflow/index.ts +1 -5
  159. package/packages/cocoindex/README.md +0 -94
  160. package/packages/cocoindex/bridge.ts +0 -842
  161. package/packages/cocoindex/commands.ts +0 -175
  162. package/packages/cocoindex/index.ts +0 -48
  163. package/packages/cocoindex/installer.ts +0 -397
  164. package/packages/cocoindex/package.json +0 -49
  165. package/packages/cocoindex/skills/cocoindex/SKILL.md +0 -88
  166. package/packages/cocoindex/tools.ts +0 -157
  167. package/packages/compactor/src/display/diff-renderer.ts +0 -281
  168. package/packages/compactor/src/display/line-width-safety.ts +0 -28
  169. package/packages/compactor/src/display/render-utils.ts +0 -52
  170. package/packages/compactor/src/display/thinking-label.ts +0 -18
  171. package/packages/compactor/src/display/tool-overrides.ts +0 -136
  172. package/packages/compactor/src/tools/compact.ts +0 -20
  173. package/packages/subagents/src/file-lock.ts +0 -102
  174. package/packages/utility/src/cache/ttl-cache.ts +0 -311
  175. package/packages/utility/src/diff/highlighter.ts +0 -352
  176. package/packages/utility/src/diff/parser.ts +0 -191
  177. package/packages/utility/src/diff/renderer.ts +0 -395
  178. package/packages/utility/src/diff/theme.ts +0 -316
  179. package/packages/utility/src/diff/wrapper.ts +0 -339
  180. package/packages/utility/src/display/capabilities.ts +0 -214
  181. package/packages/utility/src/display/width.ts +0 -226
  182. package/packages/utility/src/tools/batch.ts +0 -229
  183. package/packages/utility/src/tui/badge-settings-tui.ts +0 -388
  184. package/packages/utility/src/tui/badge-settings.ts +0 -67
  185. package/packages/utility/src/tui/settings-inspector.ts +0 -303
  186. package/packages/web-api/src/providers/llm-summarize.ts +0 -71
@@ -9,11 +9,8 @@ import type {
9
9
  FetchResult,
10
10
  FetchError,
11
11
  FetchOptions,
12
- FetchProgress,
13
- FetchExecutionHooks,
14
12
  BatchFetchResult,
15
13
  BatchFetchItemResult,
16
- FetchProgressStatus,
17
14
  } from "./types.js";
18
15
  import {
19
16
  DEFAULT_BROWSER,
@@ -27,7 +24,7 @@ import {
27
24
  DEFAULT_BATCH_CONCURRENCY,
28
25
  } from "./constants.js";
29
26
  import { resolveBrowserProfile, resolveOSProfile } from "./profiles.js";
30
- import { getWreq, getDefuddle, getMimeTypes } from "./dependencies.js";
27
+ import { getWreq, getDefuddle } from "./dependencies.js";
31
28
  import { parseHTML, extractTextContent, elementToMarkdown } from "./dom.js";
32
29
  import { truncateContent, formatContent } from "./format.js";
33
30
 
@@ -224,13 +221,11 @@ function detectContentType(
224
221
  *
225
222
  * @param url - URL to fetch
226
223
  * @param options - Fetch options
227
- * @param hooks - Execution hooks for progress
228
224
  * @returns Fetch result or throws FetchError
229
225
  */
230
226
  export async function defuddleFetch(
231
227
  url: string,
232
228
  options: FetchOptions = {},
233
- hooks?: FetchExecutionHooks
234
229
  ): Promise<FetchResult> {
235
230
  const {
236
231
  browser = DEFAULT_BROWSER,
@@ -244,29 +239,10 @@ export async function defuddleFetch(
244
239
  headers: customHeaders,
245
240
  } = options;
246
241
 
247
- // Track progress
248
- const updateProgress = (
249
- status: FetchProgressStatus,
250
- percent: number = 0,
251
- phase: string = "",
252
- bytesLoaded: number = 0,
253
- bytesTotal: number = 0
254
- ) => {
255
- hooks?.onProgress?.({
256
- url,
257
- status,
258
- percent,
259
- bytesLoaded,
260
- bytesTotal,
261
- phase,
262
- });
263
- };
264
-
265
242
  let finalUrl = url;
266
243
  let redirectCount = 0;
267
244
 
268
245
  // Validate URL
269
- updateProgress("connecting", 0, "validation");
270
246
  try {
271
247
  validateUrl(url);
272
248
  } catch (error) {
@@ -279,7 +255,7 @@ export async function defuddleFetch(
279
255
  }
280
256
 
281
257
  // Get wreq-js
282
- const wreq = await getWreq();
258
+ const wreq = getWreq();
283
259
 
284
260
  // Build request options
285
261
  const resolvedBrowser = resolveBrowserProfile(browser);
@@ -292,7 +268,6 @@ export async function defuddleFetch(
292
268
 
293
269
  // Main fetch loop (handles meta refresh redirects)
294
270
  while (redirectCount < MAX_REDIRECTS) {
295
- updateProgress("connecting", 10, "connecting");
296
271
 
297
272
  try {
298
273
  // wreq-js request
@@ -304,8 +279,6 @@ export async function defuddleFetch(
304
279
  headers: requestHeaders,
305
280
  });
306
281
 
307
- updateProgress("waiting", 30, "waiting");
308
-
309
282
  // Check HTTP status
310
283
  if (!response.ok) {
311
284
  throw createError(
@@ -322,21 +295,16 @@ export async function defuddleFetch(
322
295
  );
323
296
  }
324
297
 
325
- updateProgress("loading", 40, "loading");
326
-
327
298
  // Get response body
328
299
  const buffer = await response.arrayBuffer();
329
300
  const contentLength = response.headers.get("content-length");
330
301
  const bytesTotal = contentLength ? parseInt(contentLength, 10) : buffer.byteLength;
331
302
 
332
- updateProgress("loading", 60, "loading", buffer.byteLength, bytesTotal);
333
-
334
303
  // Detect content type
335
304
  const { mimeType, isBinary } = detectContentType(response, buffer);
336
305
 
337
306
  // Handle binary content
338
307
  if (isBinary) {
339
- updateProgress("processing", 80, "processing");
340
308
 
341
309
  // For binary files, return a placeholder with metadata
342
310
  return createResult(url, finalUrl, `[Binary file: ${mimeType}]`, {
@@ -347,7 +315,6 @@ export async function defuddleFetch(
347
315
 
348
316
  // Handle JSON
349
317
  if (mimeType === "application/json") {
350
- updateProgress("processing", 80, "processing");
351
318
  const text = new TextDecoder().decode(buffer);
352
319
  const json = JSON.parse(text);
353
320
  const content = JSON.stringify(json, null, 2);
@@ -361,7 +328,6 @@ export async function defuddleFetch(
361
328
 
362
329
  // Handle plain text
363
330
  if (mimeType.startsWith("text/plain")) {
364
- updateProgress("processing", 80, "processing");
365
331
  const text = new TextDecoder().decode(buffer);
366
332
  const truncated = truncateContent(text, maxChars);
367
333
 
@@ -372,7 +338,6 @@ export async function defuddleFetch(
372
338
  }
373
339
 
374
340
  // Handle HTML
375
- updateProgress("processing", 70, "processing");
376
341
 
377
342
  const html = new TextDecoder().decode(buffer);
378
343
  const { document, window } = parseHTML(html);
@@ -391,7 +356,7 @@ export async function defuddleFetch(
391
356
  let metadata: Partial<FetchResult> = {};
392
357
 
393
358
  try {
394
- const defuddle = await getDefuddle();
359
+ const defuddle = getDefuddle();
395
360
 
396
361
  // defuddle expects a window object with document
397
362
  const defuddleOptions = {
@@ -425,8 +390,6 @@ export async function defuddleFetch(
425
390
  maxChars
426
391
  );
427
392
 
428
- updateProgress("done", 100, "done", bytesTotal, bytesTotal);
429
-
430
393
  return createResult(url, finalUrl, formattedContent, {
431
394
  ...metadata,
432
395
  mimeType,
@@ -504,13 +467,11 @@ function fallbackExtraction(document: Document): string {
504
467
  *
505
468
  * @param urls - URLs to fetch
506
469
  * @param options - Fetch options
507
- * @param hooks - Execution hooks
508
470
  * @returns Batch fetch result
509
471
  */
510
472
  export async function defuddleFetchMultiple(
511
473
  urls: string[],
512
474
  options: FetchOptions & { batchConcurrency?: number } = {},
513
- hooks?: FetchExecutionHooks
514
475
  ): Promise<BatchFetchResult> {
515
476
  const {
516
477
  batchConcurrency = DEFAULT_BATCH_CONCURRENCY,
@@ -518,76 +479,28 @@ export async function defuddleFetchMultiple(
518
479
  } = options;
519
480
 
520
481
  const items: BatchFetchItemResult[] = new Array(urls.length);
521
- const progress: FetchProgress[] = urls.map((url) => ({
522
- url,
523
- status: "queued" as FetchProgressStatus,
524
- percent: 0,
525
- bytesLoaded: 0,
526
- bytesTotal: 0,
527
- phase: "queued",
528
- }));
529
-
530
- // Worker function
531
- const fetchWorker = async (index: number): Promise<void> => {
532
- const url = urls[index];
533
482
 
534
- progress[index] = {
535
- url,
536
- status: "connecting",
537
- percent: 0,
538
- bytesLoaded: 0,
539
- bytesTotal: 0,
540
- phase: "connecting",
541
- };
542
- hooks?.onUpdate?.([...progress]);
483
+ // Bounded concurrency
484
+ let nextIndex = 0;
485
+ const workers: Promise<void>[] = [];
543
486
 
487
+ const fetchWorker = async (index: number): Promise<void> => {
544
488
  try {
545
- const result = await defuddleFetch(url, fetchOptions, {
546
- onProgress: (p) => {
547
- progress[index] = p;
548
- hooks?.onUpdate?.([...progress]);
549
- },
550
- });
551
-
489
+ const result = await defuddleFetch(urls[index], fetchOptions);
552
490
  items[index] = { status: "done", result };
553
- progress[index] = {
554
- url,
555
- status: "done",
556
- percent: 100,
557
- bytesLoaded: progress[index].bytesTotal,
558
- bytesTotal: progress[index].bytesTotal,
559
- phase: "done",
560
- };
561
491
  } catch (error) {
562
492
  const fetchError = (error as FetchError).code
563
493
  ? (error as FetchError)
564
- : createError("processing_error", "unknown", (error as Error).message, false, { url });
565
-
494
+ : createError("processing_error", "unknown", (error as Error).message, false, { url: urls[index] });
566
495
  items[index] = { status: "error", error: fetchError };
567
- progress[index] = {
568
- url,
569
- status: "error",
570
- percent: 0,
571
- bytesLoaded: 0,
572
- bytesTotal: 0,
573
- phase: "error",
574
- error: fetchError,
575
- };
576
496
  }
577
-
578
- hooks?.onUpdate?.([...progress]);
579
497
  };
580
498
 
581
- // Bounded concurrency
582
- let nextIndex = 0;
583
- const workers: Promise<void>[] = [];
584
-
585
499
  const startWorker = (): void => {
586
500
  if (nextIndex >= urls.length) return;
587
501
  const index = nextIndex++;
588
502
  workers.push(
589
503
  fetchWorker(index).then(() => {
590
- // Start next worker after completion
591
504
  if (nextIndex < urls.length) {
592
505
  startWorker();
593
506
  }
@@ -595,15 +508,12 @@ export async function defuddleFetchMultiple(
595
508
  );
596
509
  };
597
510
 
598
- // Start initial workers
599
511
  for (let i = 0; i < Math.min(batchConcurrency, urls.length); i++) {
600
512
  startWorker();
601
513
  }
602
514
 
603
- // Wait for all workers to complete
604
515
  await Promise.all(workers);
605
516
 
606
- // Calculate statistics
607
517
  const succeeded = items.filter((item) => item.status === "done").length;
608
518
  const failed = items.filter((item) => item.status === "error").length;
609
519
 
@@ -136,51 +136,6 @@ function stripMarkdown(markdown: string): string {
136
136
  * @param error - Fetch error
137
137
  * @returns Human-readable error string
138
138
  */
139
- export function buildErrorText(error: FetchError): string {
140
- const parts: string[] = [];
141
-
142
- // Main error message
143
- parts.push(error.error);
144
-
145
- // Code and phase context
146
- parts.push(`(${error.code} during ${error.phase})`);
147
-
148
- // URL context
149
- if (error.url) {
150
- if (error.finalUrl && error.finalUrl !== error.url) {
151
- parts.push(`URL: ${error.url} → ${error.finalUrl}`);
152
- } else {
153
- parts.push(`URL: ${error.url}`);
154
- }
155
- }
156
-
157
- // HTTP status
158
- if (error.statusCode) {
159
- parts.push(`Status: ${error.statusCode}${error.statusText ? ` ${error.statusText}` : ""}`);
160
- }
161
-
162
- // Network details
163
- if (error.mimeType) {
164
- parts.push(`Content-Type: ${error.mimeType}`);
165
- }
166
- if (error.contentLength !== undefined) {
167
- const sizeKB = Math.round(error.contentLength / 1024);
168
- parts.push(`Size: ${sizeKB} KB`);
169
- }
170
- if (error.downloadedBytes !== undefined && error.contentLength) {
171
- const percent = Math.round((error.downloadedBytes / error.contentLength) * 100);
172
- parts.push(`Downloaded: ${percent}%`);
173
- }
174
-
175
- // Retry hint
176
- if (error.retryable) {
177
- parts.push("This error may be retried.");
178
- } else {
179
- parts.push("This error is not retryable.");
180
- }
181
-
182
- return parts.join("\n");
183
- }
184
139
 
185
140
  /**
186
141
  * Format a single FetchResult for display.
@@ -274,33 +229,3 @@ export function formatBatchResult(result: BatchFetchResult): string {
274
229
  * @param error - Fetch error
275
230
  * @returns Formatted error string
276
231
  */
277
- export function formatErrorResult(error: FetchError): string {
278
- const lines: string[] = [];
279
-
280
- lines.push(`# Fetch Error`);
281
- lines.push("");
282
- lines.push(`**${error.error}**`);
283
- lines.push("");
284
- lines.push(`Code: \`${error.code}\``);
285
- lines.push(`Phase: \`${error.phase}\``);
286
-
287
- if (error.url) {
288
- lines.push("");
289
- lines.push(`URL: ${error.url}`);
290
- if (error.finalUrl && error.finalUrl !== error.url) {
291
- lines.push(`Final URL: ${error.finalUrl}`);
292
- }
293
- }
294
-
295
- if (error.statusCode) {
296
- lines.push("");
297
- lines.push(`HTTP Status: ${error.statusCode}${error.statusText ? ` ${error.statusText}` : ""}`);
298
- }
299
-
300
- if (error.retryable) {
301
- lines.push("");
302
- lines.push(`*This error may be retried.*`);
303
- }
304
-
305
- return lines.join("\n");
306
- }
@@ -128,42 +128,3 @@ export interface BatchFetchResult {
128
128
  items: BatchFetchItemResult[];
129
129
  }
130
130
 
131
- // ─── Progress Types ────────────────────────────────────────────
132
-
133
- /** Status of a single URL in the fetch pipeline */
134
- export type FetchProgressStatus =
135
- | "queued"
136
- | "connecting"
137
- | "waiting"
138
- | "loading"
139
- | "processing"
140
- | "done"
141
- | "error";
142
-
143
- /** Progress update for a single URL */
144
- export interface FetchProgress {
145
- /** URL being fetched */
146
- url: string;
147
- /** Current pipeline status */
148
- status: FetchProgressStatus;
149
- /** Progress percentage (0-100) */
150
- percent: number;
151
- /** Bytes loaded so far */
152
- bytesLoaded: number;
153
- /** Total bytes expected */
154
- bytesTotal: number;
155
- /** Current phase label */
156
- phase: string;
157
- /** Error details (if status is "error") */
158
- error?: FetchError;
159
- }
160
-
161
- // ─── Execution Hooks ───────────────────────────────────────────
162
-
163
- /** Hooks for observing fetch execution progress */
164
- export interface FetchExecutionHooks {
165
- /** Called with progress updates for a single URL fetch */
166
- onProgress?: (progress: FetchProgress) => void;
167
- /** Called with full progress snapshot for batch fetches */
168
- onUpdate?: (progress: FetchProgress[]) => void;
169
- }
@@ -28,7 +28,6 @@ import "./providers/serpapi.js";
28
28
  import "./providers/tavily.js";
29
29
  import "./providers/firecrawl.js";
30
30
  import "./providers/perplexity.js";
31
- import "./providers/llm-summarize.js";
32
31
 
33
32
  /** Package version */
34
33
  const VERSION = getPackageVersion(dirname(fileURLToPath(import.meta.url)));
@@ -91,7 +90,7 @@ export default function (pi: ExtensionAPI) {
91
90
  ).length;
92
91
 
93
92
  // Check smart-fetch engine availability
94
- const deps = await checkDependencies();
93
+ const deps = checkDependencies();
95
94
  const smartFetchStatus = deps.available ? "✓ Ready" : `Missing: ${deps.missing.join(", ")}`;
96
95
 
97
96
  // wigolo status — only probe when the user has it enabled, so a
@@ -79,9 +79,6 @@ export interface WebProvider {
79
79
  */
80
80
  ranking: ProviderRanking;
81
81
 
82
- /** Provider-specific configuration */
83
- config: Record<string, unknown>;
84
-
85
82
  /**
86
83
  * Search the web.
87
84
  * @param query - Search query string
@@ -106,11 +103,4 @@ export interface WebProvider {
106
103
  * @returns Summarized content
107
104
  */
108
105
  summarize?(url: string, prompt?: string, config?: ProviderConfig): Promise<SummarizeResult>;
109
-
110
- /**
111
- * Validate API key (optional).
112
- * @param apiKey - API key to validate
113
- * @returns true if valid
114
- */
115
- validateApiKey?(apiKey: string): Promise<boolean>;
116
106
  }
@@ -146,7 +146,6 @@ const duckduckgoProvider: WebProvider = {
146
146
  read: 0,
147
147
  summarize: 0,
148
148
  },
149
- config: {},
150
149
 
151
150
  async search(query: string, _config?: ProviderConfig): Promise<SearchResult[]> {
152
151
  return searchDDG(query);
@@ -79,7 +79,6 @@ const firecrawlProvider: WebProvider = {
79
79
  read: 3,
80
80
  summarize: 0,
81
81
  },
82
- config: {},
83
82
 
84
83
  async read(url: string, config?: ProviderConfig): Promise<ReadResult> {
85
84
  const apiKey = config?.apiKey || process.env.FIRECRAWL_API_KEY;
@@ -89,14 +88,6 @@ const firecrawlProvider: WebProvider = {
89
88
  return readFirecrawl(url, apiKey);
90
89
  },
91
90
 
92
- async validateApiKey(apiKey: string): Promise<boolean> {
93
- try {
94
- await readFirecrawl("https://example.com", apiKey);
95
- return true;
96
- } catch {
97
- return false;
98
- }
99
- },
100
91
  };
101
92
 
102
93
  // Register provider
@@ -66,21 +66,12 @@ const jinaReaderProvider: WebProvider = {
66
66
  read: 2,
67
67
  summarize: 0,
68
68
  },
69
- config: {},
70
69
 
71
70
  async read(url: string, config?: ProviderConfig): Promise<ReadResult> {
72
71
  const apiKey = config?.apiKey || process.env.JINA_API_KEY;
73
72
  return readJina(url, apiKey);
74
73
  },
75
74
 
76
- async validateApiKey(apiKey: string): Promise<boolean> {
77
- try {
78
- await readJina("https://example.com", apiKey);
79
- return true;
80
- } catch {
81
- return false;
82
- }
83
- },
84
75
  };
85
76
 
86
77
  // Register provider
@@ -65,21 +65,12 @@ const jinaSearchProvider: WebProvider = {
65
65
  read: 0,
66
66
  summarize: 0,
67
67
  },
68
- config: {},
69
68
 
70
69
  async search(query: string, config?: ProviderConfig): Promise<SearchResult[]> {
71
70
  const apiKey = config?.apiKey || process.env.JINA_API_KEY;
72
71
  return searchJina(query, apiKey);
73
72
  },
74
73
 
75
- async validateApiKey(apiKey: string): Promise<boolean> {
76
- try {
77
- const results = await searchJina("test", apiKey);
78
- return Array.isArray(results);
79
- } catch {
80
- return false;
81
- }
82
- },
83
74
  };
84
75
 
85
76
  // Register provider
@@ -142,7 +142,6 @@ const perplexityProvider: WebProvider = {
142
142
  read: 4,
143
143
  summarize: 1,
144
144
  },
145
- config: {},
146
145
 
147
146
  async search(query: string, config?: ProviderConfig): Promise<SearchResult[]> {
148
147
  const apiKey = config?.apiKey || process.env.PERPLEXITY_API_KEY;
@@ -175,14 +174,6 @@ const perplexityProvider: WebProvider = {
175
174
  return summarizePerplexity(url, prompt, apiKey);
176
175
  },
177
176
 
178
- async validateApiKey(apiKey: string): Promise<boolean> {
179
- try {
180
- await searchPerplexity("test", apiKey);
181
- return true;
182
- } catch {
183
- return false;
184
- }
185
- },
186
177
  };
187
178
 
188
179
  // Register provider
@@ -8,25 +8,14 @@
8
8
  import type {
9
9
  WebProvider,
10
10
  WebCapability,
11
- ProviderConfig,
12
11
  } from "./base.js";
13
12
 
14
13
  /**
15
14
  * ProviderRegistry manages all registered web providers.
16
- *
17
- * Provides methods to:
18
- * - Register providers
19
- * - Retrieve providers by ID
20
- * - Get providers for a specific capability
21
- * - Get ranked providers for smart selection
22
15
  */
23
16
  export class ProviderRegistry {
24
17
  private providers: Map<string, WebProvider> = new Map();
25
18
 
26
- /**
27
- * Register a provider.
28
- * @param provider - Provider to register
29
- */
30
19
  register(provider: WebProvider): void {
31
20
  if (this.providers.has(provider.id)) {
32
21
  throw new Error(`Provider "${provider.id}" is already registered`);
@@ -34,94 +23,25 @@ export class ProviderRegistry {
34
23
  this.providers.set(provider.id, provider);
35
24
  }
36
25
 
37
- /**
38
- * Unregister a provider.
39
- * @param providerId - Provider ID to unregister
40
- */
41
- unregister(providerId: string): void {
42
- this.providers.delete(providerId);
43
- }
44
-
45
- /**
46
- * Get a provider by ID.
47
- * @param providerId - Provider ID
48
- * @returns Provider or undefined
49
- */
50
26
  getProvider(providerId: string): WebProvider | undefined {
51
27
  return this.providers.get(providerId);
52
28
  }
53
29
 
54
- /**
55
- * Get all registered providers.
56
- * @returns Array of all providers
57
- */
58
30
  getAllProviders(): WebProvider[] {
59
31
  return Array.from(this.providers.values());
60
32
  }
61
33
 
62
- /**
63
- * Get providers that support a specific capability.
64
- * @param capability - Capability to filter by
65
- * @returns Array of providers with the capability
66
- */
67
34
  getProvidersForCapability(capability: WebCapability): WebProvider[] {
68
35
  return this.getAllProviders().filter((p) =>
69
36
  p.capabilities.includes(capability)
70
37
  );
71
38
  }
72
39
 
73
- /**
74
- * Get ranked providers for a specific capability.
75
- * Sorted by ranking (lower = better/simpler/cheaper).
76
- * @param capability - Capability to rank by
77
- * @returns Array of providers sorted by ranking
78
- */
79
40
  getRankedProviders(capability: WebCapability): WebProvider[] {
80
41
  return this.getProvidersForCapability(capability)
81
42
  .filter((p) => p.ranking[capability] > 0)
82
43
  .sort((a, b) => a.ranking[capability] - b.ranking[capability]);
83
44
  }
84
-
85
- /**
86
- * Get the best provider for a capability (lowest rank).
87
- * @param capability - Capability to find best provider for
88
- * @returns Best provider or undefined
89
- */
90
- getBestProvider(capability: WebCapability): WebProvider | undefined {
91
- const ranked = this.getRankedProviders(capability);
92
- return ranked[0];
93
- }
94
-
95
- /**
96
- * Get a provider by rank for a capability.
97
- * @param capability - Capability to search
98
- * @param rank - Desired rank (1-based)
99
- * @returns Provider at that rank or undefined
100
- */
101
- getProviderByRank(capability: WebCapability, rank: number): WebProvider | undefined {
102
- const ranked = this.getRankedProviders(capability);
103
- return ranked.find((p) => p.ranking[capability] === rank);
104
- }
105
-
106
- /**
107
- * Get enabled providers based on configuration.
108
- * @param configMap - Map of provider ID to config
109
- * @returns Array of enabled providers
110
- */
111
- getEnabledProviders(configMap: Map<string, ProviderConfig>): WebProvider[] {
112
- return this.getAllProviders().filter((p) => {
113
- const config = configMap.get(p.id);
114
- return config?.enabled !== false;
115
- });
116
- }
117
-
118
- /**
119
- * Get provider count.
120
- * @returns Number of registered providers
121
- */
122
- get count(): number {
123
- return this.providers.size;
124
- }
125
45
  }
126
46
 
127
47
  /** Singleton registry instance */
@@ -60,7 +60,6 @@ const serpapiProvider: WebProvider = {
60
60
  read: 0,
61
61
  summarize: 0,
62
62
  },
63
- config: {},
64
63
 
65
64
  async search(query: string, config?: ProviderConfig): Promise<SearchResult[]> {
66
65
  const apiKey = config?.apiKey || process.env.SERPAPI_KEY;
@@ -70,14 +69,6 @@ const serpapiProvider: WebProvider = {
70
69
  return searchSerpAPI(query, apiKey);
71
70
  },
72
71
 
73
- async validateApiKey(apiKey: string): Promise<boolean> {
74
- try {
75
- const results = await searchSerpAPI("test", apiKey);
76
- return Array.isArray(results);
77
- } catch {
78
- return false;
79
- }
80
- },
81
72
  };
82
73
 
83
74
  // Register provider
@@ -69,7 +69,6 @@ const tavilyProvider: WebProvider = {
69
69
  read: 0,
70
70
  summarize: 0,
71
71
  },
72
- config: {},
73
72
 
74
73
  async search(query: string, config?: ProviderConfig): Promise<SearchResult[]> {
75
74
  const apiKey = config?.apiKey || process.env.TAVILY_API_KEY;
@@ -79,14 +78,6 @@ const tavilyProvider: WebProvider = {
79
78
  return searchTavily(query, apiKey);
80
79
  },
81
80
 
82
- async validateApiKey(apiKey: string): Promise<boolean> {
83
- try {
84
- const results = await searchTavily("test", apiKey);
85
- return Array.isArray(results);
86
- } catch {
87
- return false;
88
- }
89
- },
90
81
  };
91
82
 
92
83
  // Register provider