donsetch 2.2.4 → 2.3.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/pi-extension.ts +16 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "donsetch",
3
- "version": "2.2.4",
3
+ "version": "2.3.1",
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
@@ -24,7 +24,7 @@ import { Type } from "typebox";
24
24
  import { spawn, execFileSync, type ChildProcess } from "node:child_process";
25
25
  import { existsSync } from "node:fs";
26
26
  import { join } from "node:path";
27
- import { Text, visibleWidth, truncateToWidth } from "@earendil-works/pi-tui";
27
+ import { Text } from "@earendil-works/pi-tui";
28
28
 
29
29
  // ── Constants ──
30
30
  const INIT_TIMEOUT_MS = 10_000;
@@ -33,11 +33,17 @@ const SHUTDOWN_GRACE_MS = 2_000;
33
33
 
34
34
  // ── TUI rendering note ──
35
35
  // Pi's TUI wraps tool calls in its own green (success) / red (failure)
36
- // highlight. We output PLAIN TEXT only — no ANSI color codes. Any
37
- // ANSI we emit (especially RESET) breaks pi's overlay mid-line,
38
- // causing text to fall outside the green/red highlight and show
39
- // with the TUI background color instead. Plain text = pi colors
40
- // the whole thing uniformly.
36
+ // highlight. We output PLAIN TEXT only — no ANSI codes at all.
37
+ // pi-tui's truncateToWidth injects \x1b[0m RESET around the ellipsis,
38
+ // which breaks pi's overlay mid-line. We use our own truncate()
39
+ // that adds zero ANSI codes.
40
+
41
+ /** Plain text truncation — no ANSI codes. */
42
+ function truncate(text: string, maxLen: number): string {
43
+ if (text.length <= maxLen) return text;
44
+ if (maxLen <= 3) return text.slice(0, maxLen);
45
+ return text.slice(0, maxLen - 3) + "...";
46
+ }
41
47
 
42
48
  // ── Tool icons ──
43
49
  const ICONS: Record<string, string> = {
@@ -252,7 +258,7 @@ function getPreview(text: string, maxLen = 72): string {
252
258
  for (const line of lines) {
253
259
  let clean = line.replace(/^#+\s*/, "").replace(/\*\*([^*]+)\*\*/g, "$1").trim();
254
260
  if (clean.length > 0 && !clean.startsWith("{") && !clean.startsWith("[")) {
255
- return truncateToWidth(clean, maxLen, "\u2026");
261
+ return truncate(clean, maxLen);
256
262
  }
257
263
  }
258
264
  return "";
@@ -282,7 +288,7 @@ function shortUrl(url: string): string {
282
288
  const u = new URL(url);
283
289
  return u.hostname + (u.pathname !== "/" ? u.pathname.slice(0, 30) : "");
284
290
  } catch {
285
- return truncateToWidth(url, 50, "\u2026");
291
+ return truncate(url, 50);
286
292
  }
287
293
  }
288
294
 
@@ -427,7 +433,7 @@ export default function (pi: ExtensionAPI) {
427
433
  if (args?.url) {
428
434
  key = shortUrl(args.url);
429
435
  } else if (args?.query) {
430
- key = truncateToWidth(`"${args.query}"`, 50, "\u2026");
436
+ key = truncate(`"${args.query}"`, 50);
431
437
  }
432
438
  // Plain text only — no ANSI codes. Pi wraps tool calls
433
439
  // in its own green (success) / red (failure) highlight.
@@ -470,7 +476,7 @@ export default function (pi: ExtensionAPI) {
470
476
  if (isErr) {
471
477
  line2 = d.error || "failed";
472
478
  } else if (toolName === "web_search" && d.topResult) {
473
- line2 = truncateToWidth(d.topResult, 70, "\u2026");
479
+ line2 = truncate(d.topResult, 70);
474
480
  } else if (d.preview) {
475
481
  line2 = d.preview;
476
482
  }