donsetch 3.2.0 → 3.2.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 +23 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "donsetch",
3
- "version": "3.2.0",
3
+ "version": "3.2.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
@@ -182,6 +182,24 @@ function startServer(): Promise<void> {
182
182
  pending.clear();
183
183
  });
184
184
 
185
+ // A write to a server that just died sinks into the stream and
186
+ // comes back as an async 'error' event (EPIPE/ECONNRESET). With
187
+ // no listener Node escalates it to an uncaughtException, killing
188
+ // the whole pi process, the "write EPIPE" crash. Handling it like
189
+ // an unexpected exit keeps pi alive and fails the request cleanly.
190
+ const onStreamError = (err: NodeJS.ErrnoException) => {
191
+ proc = null;
192
+ initialized = false;
193
+ for (const [, e] of pending) {
194
+ clearTimeout(e.timer);
195
+ e.reject(new Error(`donsetch MCP server stream error: ${err.code || err.message}`));
196
+ }
197
+ pending.clear();
198
+ };
199
+ proc.stdin?.on("error", onStreamError);
200
+ proc.stdout?.on("error", onStreamError);
201
+ proc.stderr?.on("error", onStreamError);
202
+
185
203
  sendRequest(
186
204
  "initialize",
187
205
  {
@@ -260,7 +278,11 @@ function sendRequest(
260
278
  function sendNotification(method: string, params: any): void {
261
279
  if (!proc?.stdin?.writable) return;
262
280
  const msg = JSON.stringify({ jsonrpc: "2.0", method, params });
263
- proc.stdin.write(msg + "\n");
281
+ try {
282
+ proc.stdin.write(msg + "\n");
283
+ } catch {
284
+ // Stream error handler covers the async EPIPE; nothing to do here.
285
+ }
264
286
  }
265
287
 
266
288
  async function callMcpTool(name: string, args: any, signal?: AbortSignal): Promise<any> {