@atlisp/mcp 1.3.3 → 1.3.4

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.
@@ -34,7 +34,8 @@ var SessionTransport = class {
34
34
  this._started = true;
35
35
  }
36
36
  async send(message) {
37
- if (this._closed) return;
37
+ if (this._closed)
38
+ return;
38
39
  if (this._pendingRequest) {
39
40
  const { resolve, reject, timeout } = this._pendingRequest;
40
41
  clearTimeout(timeout);
@@ -43,7 +44,8 @@ var SessionTransport = class {
43
44
  }
44
45
  }
45
46
  async close() {
46
- if (this._closed) return;
47
+ if (this._closed)
48
+ return;
47
49
  this._closed = true;
48
50
  if (this._pendingRequest) {
49
51
  const { reject, timeout } = this._pendingRequest;
@@ -210,7 +212,8 @@ function setupStdoutHandler(w) {
210
212
  const lines = buffer.split("\n");
211
213
  buffer = lines.pop() || "";
212
214
  for (const line of lines) {
213
- if (!line.trim()) continue;
215
+ if (!line.trim())
216
+ continue;
214
217
  try {
215
218
  const result = JSON.parse(line);
216
219
  const rid = result.requestId;
@@ -235,7 +238,8 @@ function setupStdoutHandler(w) {
235
238
  }
236
239
  function getWorker() {
237
240
  if (!worker || !worker.connected) {
238
- if (worker) worker.kill();
241
+ if (worker)
242
+ worker.kill();
239
243
  worker = spawn("node", [workerPath], {
240
244
  stdio: ["pipe", "pipe", "pipe"]
241
245
  });
@@ -244,7 +248,8 @@ function getWorker() {
244
248
  const w = worker;
245
249
  w.on("exit", (code) => {
246
250
  console.error("worker exited:", code);
247
- if (w !== worker) return;
251
+ if (w !== worker)
252
+ return;
248
253
  w.connected = false;
249
254
  for (const [id, { reject, timeout }] of pendingRequests) {
250
255
  clearTimeout(timeout);
@@ -263,7 +268,8 @@ function getWorker() {
263
268
  return worker;
264
269
  }
265
270
  function startHeartbeat() {
266
- if (heartbeatTimer) clearInterval(heartbeatTimer);
271
+ if (heartbeatTimer)
272
+ clearInterval(heartbeatTimer);
267
273
  heartbeatTimer = setInterval(async () => {
268
274
  try {
269
275
  const result = await sendMessage({ type: "ping" });
@@ -308,7 +314,8 @@ var CadConnection = class {
308
314
  return process.platform === "win32";
309
315
  }
310
316
  async connect() {
311
- if (!this.isAvailable()) return false;
317
+ if (!this.isAvailable())
318
+ return false;
312
319
  try {
313
320
  const result = await sendMessage({ type: "connect" });
314
321
  if (result && result.success) {
@@ -324,13 +331,16 @@ var CadConnection = class {
324
331
  return false;
325
332
  }
326
333
  async sendCommand(code) {
327
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
334
+ if (!this.connected)
335
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
328
336
  const result = await sendMessage({ type: "send", code, platform: _platform });
329
- if (result.success) return true;
337
+ if (result.success)
338
+ return true;
330
339
  throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
331
340
  }
332
341
  async sendCommandWithResult(code, encoding = null) {
333
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
342
+ if (!this.connected)
343
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
334
344
  const result = await sendMessage({ type: "sendResult", code, platform: _platform, encoding: encoding || "" });
335
345
  if (result.success) {
336
346
  return result.result || "";
@@ -344,7 +354,8 @@ var CadConnection = class {
344
354
  return this.product;
345
355
  }
346
356
  async isBusy() {
347
- if (!this.connected) return false;
357
+ if (!this.connected)
358
+ return false;
348
359
  try {
349
360
  const result = await sendMessage({ type: "isBusy", platform: _platform });
350
361
  return result && result.isBusy;
@@ -353,7 +364,8 @@ var CadConnection = class {
353
364
  }
354
365
  }
355
366
  async hasDoc() {
356
- if (!this.connected) return { hasDoc: false, docCount: 0 };
367
+ if (!this.connected)
368
+ return { hasDoc: false, docCount: 0 };
357
369
  try {
358
370
  const result = await sendMessage({ type: "hasdoc", platform: _platform });
359
371
  return result || { hasDoc: false, docCount: 0 };
@@ -362,7 +374,8 @@ var CadConnection = class {
362
374
  }
363
375
  }
364
376
  async newDoc() {
365
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
377
+ if (!this.connected)
378
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
366
379
  try {
367
380
  const result = await sendMessage({ type: "newdoc", platform: _platform });
368
381
  return result && result.success;
@@ -371,7 +384,8 @@ var CadConnection = class {
371
384
  }
372
385
  }
373
386
  async bringToFront() {
374
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
387
+ if (!this.connected)
388
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
375
389
  try {
376
390
  const result = await sendMessage({ type: "bringToFront", platform: _platform });
377
391
  return result && result.success;
@@ -380,7 +394,8 @@ var CadConnection = class {
380
394
  }
381
395
  }
382
396
  async getInfo() {
383
- if (!this.connected) return "CAD \u672A\u8FDE\u63A5";
397
+ if (!this.connected)
398
+ return "CAD \u672A\u8FDE\u63A5";
384
399
  return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
385
400
  }
386
401
  async disconnect() {
@@ -462,7 +477,7 @@ async function evalLisp(code, withResult = false, encoding = null) {
462
477
  }
463
478
  return { content: [{ type: "text", text: "\u6267\u884C\u5931\u8D25\u6216\u65E0\u8FD4\u56DE\u503C" }], isError: true };
464
479
  } else {
465
- await cad.sendCommand("\x1B\x1B" + code + "\n");
480
+ await cad.sendCommand(code + "\n");
466
481
  return { content: [{ type: "text", text: `\u5DF2\u53D1\u9001\u547D\u4EE4: ${code}` }] };
467
482
  }
468
483
  } catch (e) {
@@ -473,20 +488,23 @@ async function getCadInfo() {
473
488
  if (!cad.connected) {
474
489
  await cad.connect();
475
490
  }
476
- if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
491
+ if (!cad.connected)
492
+ return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
477
493
  const info = await cad.getInfo();
478
494
  return { content: [{ type: "text", text: info }] };
479
495
  }
480
496
  async function atCommand(command) {
481
- if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
482
- await cad.sendCommand("\x1B\x1B" + command + "\n");
497
+ if (!cad.connected)
498
+ return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
499
+ await cad.sendCommand(command + "\n");
483
500
  return { content: [{ type: "text", text: `\u5DF2\u53D1\u9001\u547D\u4EE4: ${command}` }] };
484
501
  }
485
502
  async function newDocument() {
486
503
  if (!cad.connected) {
487
504
  await cad.connect();
488
505
  }
489
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
506
+ if (!cad.connected)
507
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
490
508
  const result = await cad.newDoc();
491
509
  if (result) {
492
510
  return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
@@ -497,7 +515,8 @@ async function bringToFront() {
497
515
  if (!cad.connected) {
498
516
  await cad.connect();
499
517
  }
500
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
518
+ if (!cad.connected)
519
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
501
520
  const result = await cad.bringToFront();
502
521
  if (result) {
503
522
  return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
@@ -508,19 +527,22 @@ async function installAtlisp() {
508
527
  if (!cad.connected) {
509
528
  await cad.connect();
510
529
  }
511
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
530
+ if (!cad.connected)
531
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
512
532
  const installCode = `(progn(vl-load-com)(setq s strcat h "http" o(vlax-create-object (s"win"h".win"h"request.5.1"))v vlax-invoke e eval r read)(v o'open "get" (s h"://atlisp.""cn/@"):vlax-true)(v o'send)(v o'WaitforResponse 1000)(e(r(vlax-get-property o'ResponseText))))`;
513
- await cad.sendCommand("\x1B\x1B" + installCode + "\n");
533
+ await cad.sendCommand(installCode + "\n");
514
534
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
515
535
  }
516
536
  async function listFunctionsInCad() {
517
537
  if (!cad.connected) {
518
538
  await cad.connect();
519
539
  }
520
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
540
+ if (!cad.connected)
541
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
521
542
  try {
522
543
  const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
523
- if (result) return { content: [{ type: "text", text: result }] };
544
+ if (result)
545
+ return { content: [{ type: "text", text: result }] };
524
546
  return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
525
547
  } catch (e) {
526
548
  return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
@@ -530,7 +552,8 @@ async function initAtlisp() {
530
552
  if (!cad.connected) {
531
553
  await cad.connect();
532
554
  }
533
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
555
+ if (!cad.connected)
556
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
534
557
  const code = `(if (null @::load-module)
535
558
  (progn
536
559
  (vl-load-com)
@@ -540,7 +563,7 @@ async function initAtlisp() {
540
563
  (v o'WaitforResponse 1000)
541
564
  (e(r(vlax-get o'ResponseText)))))`;
542
565
  try {
543
- await cad.sendCommand("\x1B\x1B" + code + "\n");
566
+ await cad.sendCommand(code + "\n");
544
567
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u51FD\u6570\u5E93\u52A0\u8F7D\u4EE3\u7801\u5230 CAD" }] };
545
568
  } catch (e) {
546
569
  return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
@@ -570,10 +593,13 @@ async function fetchPackages() {
570
593
  return null;
571
594
  }
572
595
  async function listPackages() {
573
- if (!cad.connected) await cad.connect();
574
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
596
+ if (!cad.connected)
597
+ await cad.connect();
598
+ if (!cad.connected)
599
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
575
600
  const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
576
- if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
601
+ if (result && result !== "nil")
602
+ return { content: [{ type: "text", text: result }] };
577
603
  const packages = MOCK_PACKAGES.map((p) => `${p.name} v${p.version} - ${p.description}`);
578
604
  return { content: [{ type: "text", text: `\u5DF2\u5B89\u88C5\u7684 @lisp \u5305:
579
605
  ${packages.join("\n")}` }] };
@@ -590,10 +616,12 @@ async function searchPackages(query) {
590
616
  for (const p of items) {
591
617
  const name = (p.name || "").toLowerCase();
592
618
  const desc = (p.description || "").toLowerCase();
593
- if (name.includes(q) || desc.includes(q)) results.push(p);
619
+ if (name.includes(q) || desc.includes(q))
620
+ results.push(p);
594
621
  }
595
622
  } else {
596
- for (const p of items) results.push(p);
623
+ for (const p of items)
624
+ results.push(p);
597
625
  }
598
626
  if (results.length === 0) {
599
627
  return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
@@ -635,7 +663,8 @@ async function getFunctionUsage(funcName, packageName) {
635
663
  const data = await response.json();
636
664
  const funcs = Object.values(data.all_functions || {});
637
665
  const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
638
- if (func) results.push(func);
666
+ if (func)
667
+ results.push(func);
639
668
  }
640
669
  } catch (e) {
641
670
  log(`function-handlers fetch error: ${e.message}`);
@@ -646,7 +675,8 @@ async function getFunctionUsage(funcName, packageName) {
646
675
  const raw = await fs2.readFile(path3.join(FUNCTIONS_DIR, file), "utf-8");
647
676
  const data = JSON.parse(raw);
648
677
  const func = data.functions?.find((f2) => f2.name === funcName);
649
- if (func) results.push(func);
678
+ if (func)
679
+ results.push(func);
650
680
  }
651
681
  }
652
682
  if (results.length === 0) {
@@ -727,11 +757,14 @@ function setCache(key, data) {
727
757
  resourceCache.set(key, { data, timestamp: Date.now() });
728
758
  }
729
759
  function parseLispList(str) {
730
- if (!str || typeof str !== "string") return null;
760
+ if (!str || typeof str !== "string")
761
+ return null;
731
762
  const trimmed = str.trim();
732
- if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) return null;
763
+ if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
764
+ return null;
733
765
  const content = trimmed.slice(1, -1).trim();
734
- if (!content) return [];
766
+ if (!content)
767
+ return [];
735
768
  const result = [];
736
769
  let depth = 0;
737
770
  let current = "";
@@ -773,15 +806,21 @@ function parseLispList(str) {
773
806
  }
774
807
  current += ch;
775
808
  }
776
- if (current.trim()) result.push(current.trim());
809
+ if (current.trim())
810
+ result.push(current.trim());
777
811
  return result.map((item) => {
778
812
  const t = item.trim();
779
- if (t === "nil") return null;
780
- if (t === "t") return true;
781
- if (t === "T") return true;
813
+ if (t === "nil")
814
+ return null;
815
+ if (t === "t")
816
+ return true;
817
+ if (t === "T")
818
+ return true;
782
819
  const num = Number(t);
783
- if (!isNaN(num) && t !== "") return num;
784
- if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
820
+ if (!isNaN(num) && t !== "")
821
+ return num;
822
+ if (t.startsWith('"') && t.endsWith('"'))
823
+ return t.slice(1, -1);
785
824
  return t;
786
825
  });
787
826
  }
@@ -796,14 +835,16 @@ var RESOURCES = [
796
835
  ];
797
836
  function parseQuery(uri) {
798
837
  const qIdx = uri.indexOf("?");
799
- if (qIdx === -1) return { base: uri, params: {} };
838
+ if (qIdx === -1)
839
+ return { base: uri, params: {} };
800
840
  const base = uri.substring(0, qIdx);
801
841
  const params = {};
802
842
  uri.substring(qIdx + 1).split("&").forEach((p) => {
803
843
  const eqIdx = p.indexOf("=");
804
844
  const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
805
845
  const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
806
- if (k) params[k] = decodeURIComponent(v);
846
+ if (k)
847
+ params[k] = decodeURIComponent(v);
807
848
  });
808
849
  return { base, params };
809
850
  }
@@ -839,7 +880,8 @@ async function readResource(uri) {
839
880
  }
840
881
  async function getCadInfo2() {
841
882
  const cached = getCached("cad:info");
842
- if (cached) return cached;
883
+ if (cached)
884
+ return cached;
843
885
  if (!cad.connected) {
844
886
  await cad.connect();
845
887
  }
@@ -866,9 +908,12 @@ async function getCadInfo2() {
866
908
  async function getLayers(filterName = null) {
867
909
  const cacheKey = filterName ? `layers:${filterName}` : "layers:all";
868
910
  const cached = getCached(cacheKey);
869
- if (cached) return cached;
870
- if (!cad.connected) await cad.connect();
871
- if (!cad.connected) return [];
911
+ if (cached)
912
+ return cached;
913
+ if (!cad.connected)
914
+ await cad.connect();
915
+ if (!cad.connected)
916
+ return [];
872
917
  try {
873
918
  const code = filterName ? `(tblnext "LAYER" T)` : `(progn (setq res nil)(while (setq e (tblnext "LAYER" (null res)))(setq res (cons (list (cdr (assoc 2 e)) (cdr (assoc 62 e)) (cdr (assoc 70 e))) res))) (reverse res))`;
874
919
  const result = await cad.sendCommandWithResult(code);
@@ -915,8 +960,10 @@ async function getLayers(filterName = null) {
915
960
  async function getEntities(filterType = null) {
916
961
  const cacheKey = filterType ? `entities:${filterType}` : "entities:all";
917
962
  const cached = getCached(cacheKey);
918
- if (cached) return cached;
919
- if (!cad.connected) await cad.connect();
963
+ if (cached)
964
+ return cached;
965
+ if (!cad.connected)
966
+ await cad.connect();
920
967
  if (!cad.connected) {
921
968
  const result = { total: 0, byType: {} };
922
969
  setCache(cacheKey, result);
@@ -970,8 +1017,10 @@ async function getEntities(filterType = null) {
970
1017
  }
971
1018
  }
972
1019
  async function getDwgName() {
973
- if (!cad.connected) await cad.connect();
974
- if (!cad.connected) return { name: null };
1020
+ if (!cad.connected)
1021
+ await cad.connect();
1022
+ if (!cad.connected)
1023
+ return { name: null };
975
1024
  try {
976
1025
  const code = `(vl-princ-to-string (getvar "dwgname"))`;
977
1026
  const name = await cad.sendCommandWithResult(code);
@@ -981,8 +1030,10 @@ async function getDwgName() {
981
1030
  }
982
1031
  }
983
1032
  async function getDwgPath() {
984
- if (!cad.connected) await cad.connect();
985
- if (!cad.connected) return { path: null, name: null };
1033
+ if (!cad.connected)
1034
+ await cad.connect();
1035
+ if (!cad.connected)
1036
+ return { path: null, name: null };
986
1037
  try {
987
1038
  const code = `(progn
988
1039
  (setq prefix (vl-princ-to-string (getvar "dwgprefix")))
@@ -1000,7 +1051,8 @@ async function getDwgPath() {
1000
1051
  }
1001
1052
  if (!parsed) {
1002
1053
  const listResult = parseLispList(result);
1003
- if (listResult && listResult.length >= 2) parsed = listResult;
1054
+ if (listResult && listResult.length >= 2)
1055
+ parsed = listResult;
1004
1056
  }
1005
1057
  if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
1006
1058
  return { path: String(parsed[0]), name: String(parsed[1]) };
@@ -1204,10 +1256,14 @@ ${generateSuggestions(entities, layers)}`
1204
1256
  }
1205
1257
  function generateSuggestions(entities, layers) {
1206
1258
  const suggestions = [];
1207
- if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
1208
- if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
1209
- if (entities.byType.LINE && entities.byType.LINE > 500) suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
1210
- if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
1259
+ if (entities.total > 1e3)
1260
+ suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
1261
+ if (layers.length > 20)
1262
+ suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
1263
+ if (entities.byType.LINE && entities.byType.LINE > 500)
1264
+ suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
1265
+ if (!entities.byType.DIMENSION)
1266
+ suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
1211
1267
  return suggestions.length ? suggestions.join("\n") : "- \u56FE\u7EB8\u7ED3\u6784\u826F\u597D";
1212
1268
  }
1213
1269
  async function generateBatchLinesPrompt(args) {
@@ -1523,9 +1579,11 @@ var SseSession = class {
1523
1579
  return lines.join("\n") + "\n\n";
1524
1580
  }
1525
1581
  _setupDrain() {
1526
- if (typeof this.#res.on !== "function") return;
1582
+ if (typeof this.#res.on !== "function")
1583
+ return;
1527
1584
  this.#drainHandler = () => {
1528
- if (!this.#active) return;
1585
+ if (!this.#active)
1586
+ return;
1529
1587
  if (this.#backpressureBuffer.length > 0) {
1530
1588
  this._drainBuffer();
1531
1589
  }
@@ -1547,7 +1605,8 @@ var SseSession = class {
1547
1605
  }
1548
1606
  }
1549
1607
  _write(content) {
1550
- if (!this.#active) return false;
1608
+ if (!this.#active)
1609
+ return false;
1551
1610
  try {
1552
1611
  if (this.#backpressureBuffer.length > 0) {
1553
1612
  this.#backpressureBuffer.push(content);
@@ -1817,7 +1876,8 @@ var SERVER_CAPABILITIES = {
1817
1876
  prompts: {}
1818
1877
  };
1819
1878
  var { port, host, transport, apiKey, rateLimitWindow, rateLimitMax } = config_default;
1820
- if (apiKey) log("API Key authentication enabled");
1879
+ if (apiKey)
1880
+ log("API Key authentication enabled");
1821
1881
  var mcpLimiter = rateLimit({
1822
1882
  windowMs: rateLimitWindow,
1823
1883
  max: rateLimitMax,
@@ -1867,7 +1927,8 @@ ${CAD_PLATFORMS.join("\n")}
1867
1927
  list_symbols: (a) => listSymbols(a.package),
1868
1928
  import_funlib: async (a) => {
1869
1929
  const data = await loadAtlibFunctionLib();
1870
- if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
1930
+ if (!data)
1931
+ return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
1871
1932
  if (a.format === "list") {
1872
1933
  const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
1873
1934
  return { content: [{ type: "text", text: items.join("\n") }] };
@@ -2029,7 +2090,8 @@ var tools = [
2029
2090
  ];
2030
2091
  async function handleToolCall(name, args) {
2031
2092
  const handler = TOOL_HANDLERS[name];
2032
- if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
2093
+ if (!handler)
2094
+ return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
2033
2095
  try {
2034
2096
  const result = await handler(args || {});
2035
2097
  notifyResourceChanges(name);
@@ -2150,7 +2212,8 @@ async function startServer() {
2150
2212
  const JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "application/vnd.api+json"];
2151
2213
  app.use(async (req, res, next) => {
2152
2214
  const ct = (req.headers["content-type"] || "").toLowerCase();
2153
- if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
2215
+ if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
2216
+ return next();
2154
2217
  try {
2155
2218
  const buf = await rawBody(req, { limit: "10mb" });
2156
2219
  const m = ct.match(/charset\s*=\s*([^\s;]+)/i);
@@ -2171,9 +2234,11 @@ async function startServer() {
2171
2234
  const PUBLIC_PATHS = ["/health"];
2172
2235
  if (apiKey) {
2173
2236
  app.use((req, res, next) => {
2174
- if (PUBLIC_PATHS.includes(req.path)) return next();
2237
+ if (PUBLIC_PATHS.includes(req.path))
2238
+ return next();
2175
2239
  const auth = req.get("Authorization");
2176
- if (auth === `Bearer ${apiKey}`) return next();
2240
+ if (auth === `Bearer ${apiKey}`)
2241
+ return next();
2177
2242
  res.status(401).json({ error: "Unauthorized" });
2178
2243
  });
2179
2244
  }
@@ -2188,7 +2253,8 @@ async function startServer() {
2188
2253
  res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
2189
2254
  res.setHeader("Access-Control-Max-Age", "86400");
2190
2255
  res.setHeader("Vary", "Accept");
2191
- if (req.method === "OPTIONS") return res.status(204).end();
2256
+ if (req.method === "OPTIONS")
2257
+ return res.status(204).end();
2192
2258
  next();
2193
2259
  });
2194
2260
  }
@@ -154,7 +154,7 @@ const cadSendWithResult = edge.func(function() {/*
154
154
  dynamic doc = cad.ActiveDocument;
155
155
  if (doc != null) {
156
156
  // 加载 .lsp 文件执行
157
- doc.SendCommand("\x1b\x1b(load \"" + lispFile.Replace("\\", "\\\\") + "\")\n");
157
+ doc.SendCommand("(load \"" + lispFile.Replace("\\", "\\\\") + "\")\n");
158
158
 
159
159
  int retries = 10;
160
160
  string result = "";
@@ -440,21 +440,29 @@ async function handleMessage(msg) {
440
440
  if (!parenCheck.valid) {
441
441
  return { success: false, error: `括号错误: ${parenCheck.error} (位置 ${parenCheck.pos})` };
442
442
  }
443
- if (!(await waitForIdle(msg.platform || 'AutoCAD'))) {
444
- return { success: false, error: 'CAD is busy, timeout' };
445
- }
446
- log(`send: ${msg.code}`);
447
- return new Promise((resolve, reject) => {
448
- cadSend({ code: msg.code, platform: msg.platform }, (e, r) => {
449
- if (e) {
450
- log(`send error: ${e.message}`);
451
- reject(e);
452
- } else {
443
+ const maxRetries = 3;
444
+ let lastError = null;
445
+ for (let i = 0; i < maxRetries; i++) {
446
+ const isBusy = await waitForIdle(msg.platform || 'AutoCAD');
447
+ if (isBusy) {
448
+ log(`send: ${msg.code}`);
449
+ try {
450
+ const r = await new Promise((resolve, reject) => {
451
+ cadSend({ code: msg.code, platform: msg.platform }, (e, r) => {
452
+ if (e) reject(e);
453
+ else resolve(r);
454
+ });
455
+ });
453
456
  log(`send result: ${JSON.stringify(r)}`);
454
- resolve(r);
457
+ return r;
458
+ } catch (e) {
459
+ log(`send error: ${e.message}`);
460
+ lastError = e;
455
461
  }
456
- });
457
- });
462
+ }
463
+ await new Promise(r => setTimeout(r, 500));
464
+ }
465
+ return { success: false, error: lastError?.message || '发送失败' };
458
466
  }
459
467
  if (msg.type === 'sendResult') {
460
468
  const docCheck = await new Promise((resolve, reject) => {
@@ -470,21 +478,29 @@ async function handleMessage(msg) {
470
478
  if (!parenCheck.valid) {
471
479
  return { success: false, error: `括号错误: ${parenCheck.error} (位置 ${parenCheck.pos})` };
472
480
  }
473
- if (!(await waitForIdle(msg.platform))) {
474
- return { success: false, error: 'CAD is busy, timeout' };
475
- }
476
- log(`sendResult: ${msg.code}`);
477
- return new Promise((resolve, reject) => {
478
- cadSendWithResult({ code: msg.code, platform: msg.platform, encoding: msg.encoding || '' }, (e, r) => {
479
- if (e) {
480
- log(`sendResult error: ${e.message}`);
481
- reject(e);
482
- } else {
481
+ const maxRetriesResult = 3;
482
+ let lastErrorResult = null;
483
+ for (let i = 0; i < maxRetriesResult; i++) {
484
+ const isBusy = await waitForIdle(msg.platform);
485
+ if (isBusy) {
486
+ log(`sendResult: ${msg.code}`);
487
+ try {
488
+ const r = await new Promise((resolve, reject) => {
489
+ cadSendWithResult({ code: msg.code, platform: msg.platform, encoding: msg.encoding || '' }, (e, r) => {
490
+ if (e) reject(e);
491
+ else resolve(r);
492
+ });
493
+ });
483
494
  log(`sendResult result: ${JSON.stringify(r)}`);
484
- resolve(r);
495
+ return r;
496
+ } catch (e) {
497
+ log(`sendResult error: ${e.message}`);
498
+ lastErrorResult = e;
485
499
  }
486
- });
487
- });
500
+ }
501
+ await new Promise(r => setTimeout(r, 500));
502
+ }
503
+ return { success: false, error: lastErrorResult?.message || '发送失败' };
488
504
  }
489
505
  if (msg.type === 'isBusy') {
490
506
  return new Promise((resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlisp/mcp",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "MCP Server for @lisp on CAD",
5
5
  "type": "module",
6
6
  "bin": {