donsetch 2.2.1 → 2.2.3

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 (2) hide show
  1. package/package.json +1 -1
  2. package/pi-extension.ts +60 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "donsetch",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "description": "Web fetch, search and crawl for AI agents. Zero API keys. Chrome-true TLS.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "author": "Bishesh Bhandari",
package/pi-extension.ts CHANGED
@@ -32,9 +32,11 @@ const CALL_TIMEOUT_MS = 120_000;
32
32
  const SHUTDOWN_GRACE_MS = 2_000;
33
33
 
34
34
  // ── Color palette — DonSeTch amber theme ──
35
+ // Pi's TUI wraps successful tool calls in green and failures in red.
36
+ // We do NOT use green or red in our render output — that's pi's job.
37
+ // Amber for our own accents (tool name, icons), dim for metadata.
38
+ // Clean separation: pi handles success/fail coloring, we handle content.
35
39
  const C_AMBER = "\x1b[38;2;255;178;0m";
36
- const C_GREEN = "\x1b[38;2;100;200;100m";
37
- const C_RED = "\x1b[38;2;229;115;115m";
38
40
  const C_DIM = "\x1b[38;2;130;130;140m";
39
41
  const C_CREAM = "\x1b[38;2;240;230;210m";
40
42
  const RESET = "\x1b[0m";
@@ -286,6 +288,45 @@ function shortUrl(url: string): string {
286
288
  }
287
289
  }
288
290
 
291
+ /**
292
+ * Extract the search provider from structuredContent.
293
+ * Returns "local" when provider is null/undefined (local keyless
294
+ * engine), or the provider name ("exa", "tavily", "serper",
295
+ * "tinyfish") for BYOK.
296
+ */
297
+ function getSearchProvider(sc: any): string {
298
+ if (!sc) return "local";
299
+ const provider = sc.provider;
300
+ if (!provider || provider === "null") return "local";
301
+ return String(provider);
302
+ }
303
+
304
+ /**
305
+ * Extract the fetch source label from structuredContent.
306
+ * Returns "cache" when tier is "1(warm)" (warm cookies, not a
307
+ * fresh fetch), "ghost" when tier starts with "2" (browser
308
+ * escalation), or "" for a normal tier-1 fetch.
309
+ */
310
+ function getFetchSource(sc: any): string {
311
+ if (!sc) return "";
312
+ const tier = String(sc.tier || "");
313
+ if (tier.includes("warm")) return "cache";
314
+ if (tier.startsWith("2")) return "ghost";
315
+ return "";
316
+ }
317
+
318
+ /**
319
+ * Extract the fetch verdict/content status from structuredContent.
320
+ * Returns "blocked" when content_ok is false or verdict is not
321
+ * ContentOk, "" otherwise.
322
+ */
323
+ function getFetchStatus(sc: any): string {
324
+ if (!sc) return "";
325
+ if (sc.content_ok === false) return "blocked";
326
+ if (sc.thin === true) return "thin";
327
+ return "";
328
+ }
329
+
289
330
  // ── Extension ──
290
331
 
291
332
  export default function (pi: ExtensionAPI) {
@@ -342,6 +383,7 @@ export default function (pi: ExtensionAPI) {
342
383
  const result = await callMcpTool(toolName, params);
343
384
  const text = result?.content?.[0]?.text ?? "";
344
385
  const isErr = result?.isError ?? false;
386
+ const sc = result?.structuredContent ?? null;
345
387
 
346
388
  // Build details for TUI rendering
347
389
  const details: any = {
@@ -353,6 +395,10 @@ export default function (pi: ExtensionAPI) {
353
395
  if (toolName === "web_search") {
354
396
  details.results = countSearchResults(text);
355
397
  details.topResult = getFirstResultTitle(text);
398
+ details.provider = getSearchProvider(sc);
399
+ } else if (toolName === "web_fetch") {
400
+ details.source = getFetchSource(sc);
401
+ details.status = getFetchStatus(sc);
356
402
  } else if (toolName === "web_crawl") {
357
403
  details.pages = countCrawlPages(text);
358
404
  }
@@ -398,17 +444,21 @@ export default function (pi: ExtensionAPI) {
398
444
 
399
445
  const isErr = result?.isError || result?.details?.isError;
400
446
  const d = result?.details ?? {};
401
- const glyph = isErr ? "\u2717" : "\u2713";
402
- const color = isErr ? C_RED : C_GREEN;
403
447
 
404
448
  // Build metadata string per tool
405
449
  let meta = "";
406
450
  if (toolName === "web_fetch") {
407
- const chars = d.chars ?? 0;
408
- meta = `${chars.toLocaleString()} chars`;
451
+ const parts: string[] = [];
452
+ parts.push(`${(d.chars ?? 0).toLocaleString()} chars`);
453
+ if (d.source === "cache") parts.push("via cache");
454
+ else if (d.source === "ghost") parts.push("via ghost");
455
+ if (d.status === "blocked") parts.push("blocked");
456
+ else if (d.status === "thin") parts.push("thin");
457
+ meta = parts.join(" \u00B7 ");
409
458
  } else if (toolName === "web_search") {
410
459
  const count = d.results ?? 0;
411
- meta = `${count} result${count !== 1 ? "s" : ""}`;
460
+ const provider = d.provider ?? "local";
461
+ meta = `${count} result${count !== 1 ? "s" : ""} \u00B7 via ${provider}`;
412
462
  } else if (toolName === "web_crawl") {
413
463
  const pages = d.pages ?? 0;
414
464
  meta = `${pages} page${pages !== 1 ? "s" : ""}`;
@@ -424,7 +474,9 @@ export default function (pi: ExtensionAPI) {
424
474
  line2 = d.preview;
425
475
  }
426
476
 
427
- const line1 = `${color}${glyph}${RESET} ${C_CREAM}${toolName}${RESET} ${C_DIM}\u00B7 ${meta}${RESET}`;
477
+ // No glyph coloring pi wraps the whole result in green
478
+ // (success) or red (failure). We just output the text.
479
+ const line1 = `${C_AMBER}${toolName}${RESET} ${C_DIM}\u00B7 ${meta}${RESET}`;
428
480
  const output = line2
429
481
  ? `${line1}\n ${C_DIM}${line2}${RESET}`
430
482
  : line1;