donsetch 2.2.3 → 2.3.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/pi-extension.ts +26 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "donsetch",
3
- "version": "2.2.3",
3
+ "version": "2.3.0",
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,22 +24,26 @@ 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;
31
31
  const CALL_TIMEOUT_MS = 120_000;
32
32
  const SHUTDOWN_GRACE_MS = 2_000;
33
33
 
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.
39
- const C_AMBER = "\x1b[38;2;255;178;0m";
40
- const C_DIM = "\x1b[38;2;130;130;140m";
41
- const C_CREAM = "\x1b[38;2;240;230;210m";
42
- const RESET = "\x1b[0m";
34
+ // ── TUI rendering note ──
35
+ // Pi's TUI wraps tool calls in its own green (success) / red (failure)
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
+ }
43
47
 
44
48
  // ── Tool icons ──
45
49
  const ICONS: Record<string, string> = {
@@ -254,7 +258,7 @@ function getPreview(text: string, maxLen = 72): string {
254
258
  for (const line of lines) {
255
259
  let clean = line.replace(/^#+\s*/, "").replace(/\*\*([^*]+)\*\*/g, "$1").trim();
256
260
  if (clean.length > 0 && !clean.startsWith("{") && !clean.startsWith("[")) {
257
- return truncateToWidth(clean, maxLen, "\u2026");
261
+ return truncate(clean, maxLen);
258
262
  }
259
263
  }
260
264
  return "";
@@ -284,7 +288,7 @@ function shortUrl(url: string): string {
284
288
  const u = new URL(url);
285
289
  return u.hostname + (u.pathname !== "/" ? u.pathname.slice(0, 30) : "");
286
290
  } catch {
287
- return truncateToWidth(url, 50, "\u2026");
291
+ return truncate(url, 50);
288
292
  }
289
293
  }
290
294
 
@@ -429,17 +433,20 @@ export default function (pi: ExtensionAPI) {
429
433
  if (args?.url) {
430
434
  key = shortUrl(args.url);
431
435
  } else if (args?.query) {
432
- key = truncateToWidth(`"${args.query}"`, 50, "\u2026");
436
+ key = truncate(`"${args.query}"`, 50);
433
437
  }
438
+ // Plain text only — no ANSI codes. Pi wraps tool calls
439
+ // in its own green (success) / red (failure) highlight.
440
+ // Any ANSI we emit breaks pi's overlay mid-line.
434
441
  return new Text(
435
- `${C_AMBER}${icon}${RESET} ${C_CREAM}${toolName}${RESET} ${C_DIM}${key}${RESET}`,
442
+ `${icon} ${toolName} ${key}`,
436
443
  0, 0
437
444
  );
438
445
  },
439
446
 
440
447
  renderResult(result: any, opts: any, _theme: any) {
441
448
  if (opts?.isPartial) {
442
- return new Text(`${C_AMBER}\u23F3${RESET} ${C_DIM}${toolName} working…${RESET}`, 0, 0);
449
+ return new Text(`${toolName} working…`, 0, 0);
443
450
  }
444
451
 
445
452
  const isErr = result?.isError || result?.details?.isError;
@@ -469,16 +476,15 @@ export default function (pi: ExtensionAPI) {
469
476
  if (isErr) {
470
477
  line2 = d.error || "failed";
471
478
  } else if (toolName === "web_search" && d.topResult) {
472
- line2 = truncateToWidth(d.topResult, 70, "\u2026");
479
+ line2 = truncate(d.topResult, 70);
473
480
  } else if (d.preview) {
474
481
  line2 = d.preview;
475
482
  }
476
483
 
477
- // No glyph coloringpi 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}`;
484
+ // Plain text onlyno ANSI. Pi handles all coloring.
485
+ const line1 = `${toolName} \u00B7 ${meta}`;
480
486
  const output = line2
481
- ? `${line1}\n ${C_DIM}${line2}${RESET}`
487
+ ? `${line1}\n ${line2}`
482
488
  : line1;
483
489
 
484
490
  return new Text(output, 0, 0);