donsetch 3.4.4 → 3.5.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 +2 -2
- package/install.js +7 -7
- package/package.json +1 -1
- package/pi-extension.ts +41 -10
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://github.com/dondai44423/donsetch/actions/workflows/ci.yml)
|
|
7
7
|
[](https://github.com/dondai44423/donsetch/blob/master/LICENSE)
|
|
8
8
|
|
|
9
|
-
DonSeTch gives AI agents web research from a single local process
|
|
9
|
+
DonSeTch gives AI agents web research from a single local process : fetch any URL, search across 10+ engines, and crawl multi-page docs. Chrome-true TLS fingerprinting, bot-wall bypass, PDF extraction with OCR, semantic reranking. Zero API keys.
|
|
10
10
|
|
|
11
11
|
## Install
|
|
12
12
|
|
|
@@ -60,6 +60,6 @@ donsetch update
|
|
|
60
60
|
|
|
61
61
|
## License
|
|
62
62
|
|
|
63
|
-
AGPL-3.0
|
|
63
|
+
AGPL-3.0 : Copyright (c) 2026 Bishesh Bhandari
|
|
64
64
|
|
|
65
65
|
Full documentation: [github.com/dondai44423/donsetch](https://github.com/dondai44423/donsetch)
|
package/install.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// donsetch postinstall: download the prebuilt binary for this platform
|
|
5
5
|
// from GitHub Releases, verify SHA256, and extract to ./binaries/.
|
|
6
6
|
//
|
|
7
|
-
// The binary is NOT bundled in the npm package
|
|
7
|
+
// The binary is NOT bundled in the npm package : it's fetched at
|
|
8
8
|
// install time from the GitHub release matching this package version.
|
|
9
9
|
// This keeps the npm registry clean (no 35 MB binary tarballs) and
|
|
10
10
|
// uses the same release artifacts that manual users download.
|
|
@@ -40,8 +40,8 @@ const plat = PLATFORMS[platKey];
|
|
|
40
40
|
|
|
41
41
|
if (!plat) {
|
|
42
42
|
const known = {
|
|
43
|
-
'darwin-x64': 'prebuilt binaries exist
|
|
44
|
-
'win32-arm64': 'no prebuilt binary yet
|
|
43
|
+
'darwin-x64': 'prebuilt binaries exist : update donsetch to a version that ships one',
|
|
44
|
+
'win32-arm64': 'no prebuilt binary yet : build from source (see below)',
|
|
45
45
|
}[platKey];
|
|
46
46
|
console.error(`donsetch: unsupported platform ${platKey}${known ? ` (${known})` : ''}`);
|
|
47
47
|
console.error('');
|
|
@@ -58,7 +58,7 @@ if (!plat) {
|
|
|
58
58
|
|
|
59
59
|
// ── musl detection (Alpine etc.) ────────────────────────────────
|
|
60
60
|
// The Linux binaries are glibc-linked. On musl systems they install
|
|
61
|
-
// fine but can never exec (missing ld-linux loader)
|
|
61
|
+
// fine but can never exec (missing ld-linux loader) : fail HERE with
|
|
62
62
|
// the actual cause instead of a cryptic spawn error on first run.
|
|
63
63
|
//
|
|
64
64
|
// Checking for /lib/ld-musl-*.so.1 existence is a false positive on
|
|
@@ -143,7 +143,7 @@ if (fs.existsSync(binaryPath)) {
|
|
|
143
143
|
console.log(`donsetch: binary already present (${plat.binary})`);
|
|
144
144
|
process.exit(0);
|
|
145
145
|
}
|
|
146
|
-
console.log(`donsetch: leftover ${plat.binary} is ${size} bytes
|
|
146
|
+
console.log(`donsetch: leftover ${plat.binary} is ${size} bytes : re-downloading`);
|
|
147
147
|
try { fs.unlinkSync(binaryPath); } catch (_) {}
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -236,7 +236,7 @@ async function main() {
|
|
|
236
236
|
|
|
237
237
|
// 4. Extract (tar is built into Linux, macOS, and Windows 10+)
|
|
238
238
|
console.log('donsetch: extracting...');
|
|
239
|
-
// execFileSync: no shell, no string interpolation
|
|
239
|
+
// execFileSync: no shell, no string interpolation : the install
|
|
240
240
|
// path (which can contain quotes/spaces) is passed as argv.
|
|
241
241
|
execFileSync('tar', ['xzf', tarball, '-C', binDir], { stdio: 'inherit' });
|
|
242
242
|
|
|
@@ -244,7 +244,7 @@ async function main() {
|
|
|
244
244
|
try { fs.unlinkSync(tarball); } catch (_) {}
|
|
245
245
|
try { fs.unlinkSync(checksumFile); } catch (_) {}
|
|
246
246
|
|
|
247
|
-
// 6. Verify the binary exists after extraction (BEFORE chmod
|
|
247
|
+
// 6. Verify the binary exists after extraction (BEFORE chmod :
|
|
248
248
|
// chmod on a missing file throws an opaque error).
|
|
249
249
|
if (!fs.existsSync(binaryPath)) {
|
|
250
250
|
console.error(`donsetch: expected ${plat.binary} not found after extraction`);
|
package/package.json
CHANGED
package/pi-extension.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DonSeTch pi extension
|
|
2
|
+
* DonSeTch pi extension : bridges the donsetch MCP binary into pi.
|
|
3
3
|
*
|
|
4
4
|
* `pi install npm:donsetch` installs this package. At session_start the
|
|
5
5
|
* extension spawns `donsetch mcp`, performs the MCP handshake, discovers
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Zero maintenance: tool definitions are fetched dynamically from the
|
|
10
10
|
* binary. When donsetch adds or changes tools, this extension picks
|
|
11
|
-
* them up automatically
|
|
11
|
+
* them up automatically : no code changes needed here.
|
|
12
12
|
*
|
|
13
13
|
* Auto-download: if the binary is missing (e.g. postinstall was
|
|
14
14
|
* blocked by npm 10+), the extension runs install.js at session_start
|
|
15
15
|
* to fetch it from GitHub Releases.
|
|
16
16
|
*
|
|
17
17
|
* Custom TUI: each tool has clean renderCall/renderResult showing
|
|
18
|
-
* a compact summary card
|
|
18
|
+
* a compact summary card : not the full raw output. The LLM still
|
|
19
19
|
* receives complete content; the user sees a minimal status line +
|
|
20
20
|
* one-line preview. Amber theme matching DonSeTch's identity.
|
|
21
21
|
*/
|
|
@@ -31,14 +31,20 @@ 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
|
+
// A raw process.stderr.write bypasses pi's TUI paint cycle and
|
|
35
|
+
// corrupts the viewport (worse across parallel agents). Gate it here.
|
|
36
|
+
const DEBUG_MODE =
|
|
37
|
+
(process.env.DONSETCH_DEBUG ?? "").length > 0 ||
|
|
38
|
+
(process.env.DEBUG ?? "").length > 0;
|
|
39
|
+
|
|
34
40
|
// ── TUI rendering note ──
|
|
35
41
|
// Pi's TUI wraps tool calls in its own green (success) / red (failure)
|
|
36
|
-
// highlight. We output PLAIN TEXT only
|
|
42
|
+
// highlight. We output PLAIN TEXT only : no ANSI codes at all.
|
|
37
43
|
// pi-tui's truncateToWidth injects \x1b[0m RESET around the ellipsis,
|
|
38
44
|
// which breaks pi's overlay mid-line. We use our own truncate()
|
|
39
45
|
// that adds zero ANSI codes.
|
|
40
46
|
|
|
41
|
-
/** Plain text truncation
|
|
47
|
+
/** Plain text truncation : no ANSI codes. */
|
|
42
48
|
function truncate(text: string, maxLen: number): string {
|
|
43
49
|
if (text.length <= maxLen) return text;
|
|
44
50
|
if (maxLen <= 3) return text.slice(0, maxLen);
|
|
@@ -120,7 +126,7 @@ function startServer(): Promise<void> {
|
|
|
120
126
|
try {
|
|
121
127
|
// --supervised: crash-only daemon. If the MCP server is SIGKILLed
|
|
122
128
|
// (OOM, crash), the supervisor respawns it and replays in-flight
|
|
123
|
-
// requests
|
|
129
|
+
// requests : pi users never see a dead tool until the process
|
|
124
130
|
// itself dies.
|
|
125
131
|
proc = spawn(binaryPath, ["mcp", "--supervised"], {
|
|
126
132
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -158,8 +164,29 @@ function startServer(): Promise<void> {
|
|
|
158
164
|
}
|
|
159
165
|
});
|
|
160
166
|
|
|
167
|
+
// The daemon writes diagnostics to stderr (Xvfb warnings,
|
|
168
|
+
// fallback notices, ghost telemetry). Pi's TUI surfaces stderr
|
|
169
|
+
// as user-facing output: raw forwarding used to pop non-fatal
|
|
170
|
+
// warnings up (issue #95). Gate it:
|
|
171
|
+
// - DONSETCH_DEBUG / DEBUG set: forward everything (dev mode)
|
|
172
|
+
// - otherwise only crash/fatal lines survive; the rest is
|
|
173
|
+
// tool-level information the caller already has
|
|
174
|
+
const FATAL_RE = /fatal|panic|crash|SIGSEGV|abort|OOM|out of memory/i;
|
|
175
|
+
let stderrTail = "";
|
|
161
176
|
proc.stderr?.on("data", (chunk: Buffer) => {
|
|
162
|
-
|
|
177
|
+
if (DEBUG_MODE) {
|
|
178
|
+
process.stderr.write(chunk);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
stderrTail = (stderrTail + chunk.toString()).slice(-2048);
|
|
182
|
+
const lines = stderrTail.split("\n");
|
|
183
|
+
stderrTail = lines.pop() || "";
|
|
184
|
+
for (const line of lines) {
|
|
185
|
+
const trimmed = line.trim();
|
|
186
|
+
if (trimmed && FATAL_RE.test(trimmed)) {
|
|
187
|
+
process.stderr.write(`[donsetch] ${trimmed}\n`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
163
190
|
});
|
|
164
191
|
|
|
165
192
|
proc.on("error", (err) => {
|
|
@@ -518,7 +545,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
518
545
|
} else if (args?.query) {
|
|
519
546
|
key = truncate(`"${args.query}"`, 50);
|
|
520
547
|
}
|
|
521
|
-
// Plain text only
|
|
548
|
+
// Plain text only : no ANSI codes. Pi wraps tool calls
|
|
522
549
|
// in its own green (success) / red (failure) highlight.
|
|
523
550
|
// Any ANSI we emit breaks pi's overlay mid-line.
|
|
524
551
|
return new Text(
|
|
@@ -567,7 +594,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
567
594
|
line2 = d.preview;
|
|
568
595
|
}
|
|
569
596
|
|
|
570
|
-
// Plain text only
|
|
597
|
+
// Plain text only : no ANSI. Pi handles all coloring.
|
|
571
598
|
const line1 = `${toolName} \u00B7 ${meta}`;
|
|
572
599
|
const output = line2
|
|
573
600
|
? `${line1}\n ${line2}`
|
|
@@ -578,7 +605,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
578
605
|
});
|
|
579
606
|
}
|
|
580
607
|
|
|
581
|
-
|
|
608
|
+
// Fires every session_start (unlike the failure paths above), so
|
|
609
|
+
// this one corrupted the viewport on every normal run.
|
|
610
|
+
if (DEBUG_MODE) {
|
|
611
|
+
process.stderr.write(`[donsetch] ${mcpTools.length} tools registered: ${toolNames.join(", ")}\n`);
|
|
612
|
+
}
|
|
582
613
|
});
|
|
583
614
|
|
|
584
615
|
pi.on("session_shutdown", () => {
|