@atlisp/mcp 1.4.2 → 1.4.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.
Files changed (2) hide show
  1. package/dist/atlisp-mcp.js +283 -220
  2. package/package.json +1 -1
@@ -36,7 +36,8 @@ var SessionTransport = class {
36
36
  this._started = true;
37
37
  }
38
38
  async send(message) {
39
- if (this._closed) return;
39
+ if (this._closed)
40
+ return;
40
41
  if (this._pendingRequest) {
41
42
  const { resolve, reject, timeout } = this._pendingRequest;
42
43
  clearTimeout(timeout);
@@ -45,7 +46,8 @@ var SessionTransport = class {
45
46
  }
46
47
  }
47
48
  async close() {
48
- if (this._closed) return;
49
+ if (this._closed)
50
+ return;
49
51
  this._closed = true;
50
52
  if (this._pendingRequest) {
51
53
  const { reject, timeout } = this._pendingRequest;
@@ -119,7 +121,7 @@ var FILE_EXTENSIONS = {
119
121
  "BricsCAD": [".des"]
120
122
  };
121
123
  var SERVER_NAME = "atlisp-mcp-server";
122
- var SERVER_VERSION = "1.4.1";
124
+ var SERVER_VERSION = "1.4.4";
123
125
  var MOCK_PACKAGES = [
124
126
  { name: "base", description: "\u57FA\u7840\u51FD\u6570\u5E93", version: "1.0.0" },
125
127
  { name: "at-pm", description: "\u5DE5\u7A0B\u9879\u76EE\u7BA1\u7406", version: "2.1.0" },
@@ -237,7 +239,8 @@ function setupStdoutHandler(w) {
237
239
  const lines = buffer.split("\n");
238
240
  buffer = lines.pop() || "";
239
241
  for (const line of lines) {
240
- if (!line.trim()) continue;
242
+ if (!line.trim())
243
+ continue;
241
244
  try {
242
245
  const result = JSON.parse(line);
243
246
  const rid = result.requestId;
@@ -263,7 +266,8 @@ function setupStdoutHandler(w) {
263
266
  }
264
267
  function getWorker(force = false) {
265
268
  if (!worker || !worker.connected || force) {
266
- if (worker) worker.kill();
269
+ if (worker)
270
+ worker.kill();
267
271
  worker = spawn("node", [workerPath], {
268
272
  stdio: ["pipe", "pipe", "pipe"]
269
273
  });
@@ -271,7 +275,8 @@ function getWorker(force = false) {
271
275
  const w = worker;
272
276
  w.on("exit", (code) => {
273
277
  console.error("worker exited with code:", code);
274
- if (w !== worker) return;
278
+ if (w !== worker)
279
+ return;
275
280
  w.connected = false;
276
281
  for (const [id, { reject, timeout }] of pendingRequests) {
277
282
  clearTimeout(timeout);
@@ -292,7 +297,8 @@ function getWorker(force = false) {
292
297
  return worker;
293
298
  }
294
299
  function startHeartbeat() {
295
- if (heartbeatTimer) clearInterval(heartbeatTimer);
300
+ if (heartbeatTimer)
301
+ clearInterval(heartbeatTimer);
296
302
  heartbeatTimer = setInterval(async () => {
297
303
  try {
298
304
  const result = await sendMessage({ type: "ping" });
@@ -337,7 +343,8 @@ var CadConnection = class {
337
343
  return process.platform === "win32";
338
344
  }
339
345
  async connect(platform = null) {
340
- if (!this.isAvailable()) return false;
346
+ if (!this.isAvailable())
347
+ return false;
341
348
  try {
342
349
  const msg = platform ? { type: "connect", platform } : { type: "connect" };
343
350
  const result = await sendMessage(msg);
@@ -354,13 +361,16 @@ var CadConnection = class {
354
361
  return false;
355
362
  }
356
363
  async sendCommand(code) {
357
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
364
+ if (!this.connected)
365
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
358
366
  const result = await sendMessage({ type: "send", code, platform: _platform });
359
- if (result.success) return true;
367
+ if (result.success)
368
+ return true;
360
369
  throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
361
370
  }
362
371
  async sendCommandWithResult(code, encoding = null) {
363
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
372
+ if (!this.connected)
373
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
364
374
  const result = await sendMessage({ type: "sendResult", code, platform: _platform, encoding: encoding || "" });
365
375
  if (result.success) {
366
376
  return result.result || "";
@@ -374,7 +384,8 @@ var CadConnection = class {
374
384
  return this.product;
375
385
  }
376
386
  async isBusy() {
377
- if (!this.connected) return false;
387
+ if (!this.connected)
388
+ return false;
378
389
  try {
379
390
  const result = await sendMessage({ type: "isBusy", platform: _platform });
380
391
  return result && result.isBusy;
@@ -383,7 +394,8 @@ var CadConnection = class {
383
394
  }
384
395
  }
385
396
  async hasDoc() {
386
- if (!this.connected) return { hasDoc: false, docCount: 0 };
397
+ if (!this.connected)
398
+ return { hasDoc: false, docCount: 0 };
387
399
  try {
388
400
  const result = await sendMessage({ type: "hasdoc", platform: _platform });
389
401
  return result || { hasDoc: false, docCount: 0 };
@@ -392,7 +404,8 @@ var CadConnection = class {
392
404
  }
393
405
  }
394
406
  async newDoc() {
395
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
407
+ if (!this.connected)
408
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
396
409
  try {
397
410
  const result = await sendMessage({ type: "newdoc", platform: _platform });
398
411
  return result && result.success;
@@ -401,7 +414,8 @@ var CadConnection = class {
401
414
  }
402
415
  }
403
416
  async bringToFront() {
404
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
417
+ if (!this.connected)
418
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
405
419
  try {
406
420
  const result = await sendMessage({ type: "bringToFront", platform: _platform });
407
421
  return result && result.success;
@@ -410,7 +424,8 @@ var CadConnection = class {
410
424
  }
411
425
  }
412
426
  async getInfo() {
413
- if (!this.connected) return "CAD \u672A\u8FDE\u63A5";
427
+ if (!this.connected)
428
+ return "CAD \u672A\u8FDE\u63A5";
414
429
  return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
415
430
  }
416
431
  async disconnect() {
@@ -447,9 +462,11 @@ var MAX_LOG_SIZE = 10 * 1024 * 1024;
447
462
  var MAX_LOG_FILES = 5;
448
463
  var stream = null;
449
464
  function rotateLog() {
450
- if (!fs.existsSync(DEBUG_FILE)) return;
465
+ if (!fs.existsSync(DEBUG_FILE))
466
+ return;
451
467
  const stat = fs.statSync(DEBUG_FILE);
452
- if (stat.size < MAX_LOG_SIZE) return;
468
+ if (stat.size < MAX_LOG_SIZE)
469
+ return;
453
470
  if (stream) {
454
471
  stream.end();
455
472
  stream = null;
@@ -511,7 +528,8 @@ async function evalLisp(code, withResult = false, encoding = null) {
511
528
  return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
512
529
  }
513
530
  const trimmed = (code || "").trim();
514
- if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
531
+ if (!trimmed)
532
+ return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
515
533
  try {
516
534
  if (withResult) {
517
535
  const result = await cad.sendCommandWithResult(trimmed, encoding);
@@ -531,14 +549,17 @@ async function getCadInfo() {
531
549
  if (!cad.connected) {
532
550
  await cad.connect();
533
551
  }
534
- if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
552
+ if (!cad.connected)
553
+ return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
535
554
  const info = await cad.getInfo();
536
555
  return { content: [{ type: "text", text: info }] };
537
556
  }
538
557
  async function atCommand(command) {
539
- if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
558
+ if (!cad.connected)
559
+ return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
540
560
  const trimmed = (command || "").trim();
541
- if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
561
+ if (!trimmed)
562
+ return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
542
563
  await cad.sendCommand(trimmed + "\n");
543
564
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
544
565
  }
@@ -546,7 +567,8 @@ async function newDocument() {
546
567
  if (!cad.connected) {
547
568
  await cad.connect();
548
569
  }
549
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
570
+ if (!cad.connected)
571
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
550
572
  const result = await cad.newDoc();
551
573
  if (result) {
552
574
  return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
@@ -557,7 +579,8 @@ async function bringToFront() {
557
579
  if (!cad.connected) {
558
580
  await cad.connect();
559
581
  }
560
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
582
+ if (!cad.connected)
583
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
561
584
  const result = await cad.bringToFront();
562
585
  if (result) {
563
586
  return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
@@ -568,7 +591,8 @@ async function installAtlisp() {
568
591
  if (!cad.connected) {
569
592
  await cad.connect();
570
593
  }
571
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
594
+ if (!cad.connected)
595
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
572
596
  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))))`;
573
597
  await cad.sendCommand(installCode + "\n");
574
598
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
@@ -577,10 +601,12 @@ async function listFunctionsInCad() {
577
601
  if (!cad.connected) {
578
602
  await cad.connect();
579
603
  }
580
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
604
+ if (!cad.connected)
605
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
581
606
  try {
582
607
  const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
583
- if (result) return { content: [{ type: "text", text: result }] };
608
+ if (result)
609
+ return { content: [{ type: "text", text: result }] };
584
610
  return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
585
611
  } catch (e) {
586
612
  return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
@@ -635,7 +661,8 @@ async function initAtlisp() {
635
661
  if (!cad.connected) {
636
662
  await cad.connect();
637
663
  }
638
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
664
+ if (!cad.connected)
665
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
639
666
  const code = `(if (null @::load-module)
640
667
  (progn
641
668
  (vl-load-com)
@@ -675,12 +702,15 @@ async function fetchPackages() {
675
702
  return cachedPackages || MOCK_PACKAGES;
676
703
  }
677
704
  function flattenPackages(data) {
678
- if (Array.isArray(data)) return data;
679
- if (data && Array.isArray(data.packages)) return data.packages;
705
+ if (Array.isArray(data))
706
+ return data;
707
+ if (data && Array.isArray(data.packages))
708
+ return data.packages;
680
709
  return [];
681
710
  }
682
711
  async function listPackages() {
683
- if (!cad.connected) await cad.connect();
712
+ if (!cad.connected)
713
+ await cad.connect();
684
714
  if (!cad.connected) {
685
715
  const data2 = await fetchPackages();
686
716
  const items2 = flattenPackages(data2);
@@ -688,7 +718,8 @@ async function listPackages() {
688
718
  return { content: [{ type: "text", text: text2 }] };
689
719
  }
690
720
  const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
691
- if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
721
+ if (result && result !== "nil")
722
+ return { content: [{ type: "text", text: result }] };
692
723
  const data = await fetchPackages();
693
724
  const items = flattenPackages(data);
694
725
  const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
@@ -708,10 +739,12 @@ async function searchPackages(query) {
708
739
  for (const p of items) {
709
740
  const name = (p.name || "").toLowerCase();
710
741
  const desc = (p.description || "").toLowerCase();
711
- if (name.includes(q) || desc.includes(q)) results.push(p);
742
+ if (name.includes(q) || desc.includes(q))
743
+ results.push(p);
712
744
  }
713
745
  } else {
714
- for (const p of items) results.push(p);
746
+ for (const p of items)
747
+ results.push(p);
715
748
  }
716
749
  if (results.length === 0) {
717
750
  return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
@@ -763,7 +796,8 @@ function writeCacheToDisk(data) {
763
796
  }
764
797
  async function fetchFunctions() {
765
798
  const diskCache = readCacheFromDisk();
766
- if (diskCache) return diskCache;
799
+ if (diskCache)
800
+ return diskCache;
767
801
  try {
768
802
  const response = await fetch(FUNCTIONS_URL, { headers: { "User-Agent": "atlisp-mcp" } });
769
803
  if (response.ok) {
@@ -783,7 +817,8 @@ async function getFunctionUsage(funcName, packageName) {
783
817
  if (data) {
784
818
  const funcs = Object.values(data.all_functions || {});
785
819
  const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
786
- if (func) results.push(func);
820
+ if (func)
821
+ results.push(func);
787
822
  }
788
823
  if (results.length === 0 && FUNCTIONS_DIR) {
789
824
  try {
@@ -792,7 +827,8 @@ async function getFunctionUsage(funcName, packageName) {
792
827
  const raw = fs2.readFileSync(path3.join(FUNCTIONS_DIR, file), "utf-8");
793
828
  const data2 = JSON.parse(raw);
794
829
  const func = data2.functions?.find((f2) => f2.name === funcName);
795
- if (func) results.push(func);
830
+ if (func)
831
+ results.push(func);
796
832
  }
797
833
  } catch {
798
834
  }
@@ -886,11 +922,14 @@ function clearCache(uri) {
886
922
  }
887
923
  }
888
924
  function parseLispList(str) {
889
- if (!str || typeof str !== "string") return null;
925
+ if (!str || typeof str !== "string")
926
+ return null;
890
927
  const trimmed = str.trim();
891
- if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) return null;
928
+ if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
929
+ return null;
892
930
  const content = trimmed.slice(1, -1).trim();
893
- if (!content) return [];
931
+ if (!content)
932
+ return [];
894
933
  const result = [];
895
934
  let depth = 0;
896
935
  let current = "";
@@ -932,32 +971,44 @@ function parseLispList(str) {
932
971
  }
933
972
  current += ch;
934
973
  }
935
- if (current.trim()) result.push(current.trim());
974
+ if (current.trim())
975
+ result.push(current.trim());
936
976
  return result.map((item) => {
937
977
  const t = item.trim();
938
- if (t === "nil") return null;
939
- if (t === "t") return true;
940
- if (t === "T") return true;
978
+ if (t === "nil")
979
+ return null;
980
+ if (t === "t")
981
+ return true;
982
+ if (t === "T")
983
+ return true;
941
984
  const num = Number(t);
942
- if (!isNaN(num) && t !== "") return num;
943
- if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
985
+ if (!isNaN(num) && t !== "")
986
+ return num;
987
+ if (t.startsWith('"') && t.endsWith('"'))
988
+ return t.slice(1, -1);
944
989
  return t;
945
990
  });
946
991
  }
947
992
  function parseLispRecursive(str) {
948
- if (!str || typeof str !== "string") return null;
993
+ if (!str || typeof str !== "string")
994
+ return null;
949
995
  str = str.trim();
950
- if (!str) return null;
996
+ if (!str)
997
+ return null;
951
998
  let pos = 0;
952
999
  function skipWs() {
953
- while (pos < str.length && /\s/.test(str[pos])) pos++;
1000
+ while (pos < str.length && /\s/.test(str[pos]))
1001
+ pos++;
954
1002
  }
955
1003
  function parseValue() {
956
1004
  skipWs();
957
- if (pos >= str.length) return null;
1005
+ if (pos >= str.length)
1006
+ return null;
958
1007
  const ch = str[pos];
959
- if (ch === "(") return parseList();
960
- if (ch === '"') return parseString();
1008
+ if (ch === "(")
1009
+ return parseList();
1010
+ if (ch === '"')
1011
+ return parseString();
961
1012
  if (ch === "'") {
962
1013
  pos++;
963
1014
  return parseValue();
@@ -970,11 +1021,16 @@ function parseLispRecursive(str) {
970
1021
  while (pos < str.length && str[pos] !== '"') {
971
1022
  if (str[pos] === "\\" && pos + 1 < str.length) {
972
1023
  pos++;
973
- if (str[pos] === '"') r += '"';
974
- else if (str[pos] === "n") r += "\n";
975
- else if (str[pos] === "t") r += " ";
976
- else if (str[pos] === "\\") r += "\\";
977
- else r += str[pos];
1024
+ if (str[pos] === '"')
1025
+ r += '"';
1026
+ else if (str[pos] === "n")
1027
+ r += "\n";
1028
+ else if (str[pos] === "t")
1029
+ r += " ";
1030
+ else if (str[pos] === "\\")
1031
+ r += "\\";
1032
+ else
1033
+ r += str[pos];
978
1034
  } else {
979
1035
  r += str[pos];
980
1036
  }
@@ -985,12 +1041,16 @@ function parseLispRecursive(str) {
985
1041
  }
986
1042
  function parseAtom() {
987
1043
  const start = pos;
988
- while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(") pos++;
1044
+ while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
1045
+ pos++;
989
1046
  const atom = str.slice(start, pos);
990
- if (atom === "nil" || atom === "NIL") return null;
991
- if (atom === "t" || atom === "T") return true;
1047
+ if (atom === "nil" || atom === "NIL")
1048
+ return null;
1049
+ if (atom === "t" || atom === "T")
1050
+ return true;
992
1051
  const num = Number(atom);
993
- if (!isNaN(num) && atom !== "") return num;
1052
+ if (!isNaN(num) && atom !== "")
1053
+ return num;
994
1054
  return atom;
995
1055
  }
996
1056
  function parseList() {
@@ -998,13 +1058,15 @@ function parseLispRecursive(str) {
998
1058
  const items = [];
999
1059
  while (pos < str.length) {
1000
1060
  skipWs();
1001
- if (pos >= str.length) break;
1061
+ if (pos >= str.length)
1062
+ break;
1002
1063
  if (str[pos] === ")") {
1003
1064
  pos++;
1004
1065
  return items;
1005
1066
  }
1006
1067
  const left = parseValue();
1007
- if (left === void 0) break;
1068
+ if (left === void 0)
1069
+ break;
1008
1070
  skipWs();
1009
1071
  if (str[pos] === "." && (pos + 1 >= str.length || /\s/.test(str[pos + 1]) || str[pos + 1] === ")")) {
1010
1072
  pos++;
@@ -1025,7 +1087,8 @@ function parseLispRecursive(str) {
1025
1087
  return parseValue();
1026
1088
  }
1027
1089
  function lispPairsToObject(pairs) {
1028
- if (!Array.isArray(pairs)) return pairs;
1090
+ if (!Array.isArray(pairs))
1091
+ return pairs;
1029
1092
  const obj = {};
1030
1093
  for (let i = 0; i < pairs.length - 1; i += 2) {
1031
1094
  const key = pairs[i];
@@ -1036,36 +1099,18 @@ function lispPairsToObject(pairs) {
1036
1099
  }
1037
1100
  return obj;
1038
1101
  }
1039
- var ENTITY_SCHEMAS = {
1040
- LINE: { fields: ["x1", "y1", "z1", "x2", "y2", "z2", "length"], strings: [] },
1041
- CIRCLE: { fields: ["cx", "cy", "cz", "radius"], strings: [] },
1042
- ARC: { fields: ["cx", "cy", "cz", "radius", "startAngle", "endAngle"], strings: [] },
1043
- LWPOLYLINE: { fields: ["vertices", "closed"], strings: [] },
1044
- TEXT: { fields: ["x", "y", "z", "text", "height", "rotation"], strings: ["text"] },
1045
- MTEXT: { fields: ["x", "y", "z", "text", "height", "rotation"], strings: ["text"] },
1046
- ATTRIB: { fields: ["x", "y", "z", "text", "height", "rotation"], strings: ["text"] },
1047
- TCH_TEXT: { fields: ["x", "y", "z", "text", "height", "rotation"], strings: ["text"] },
1048
- INSERT: { fields: ["x", "y", "z", "blockName", "rotation", "scaleX", "scaleY"], strings: ["blockName"] },
1049
- POINT: { fields: ["x", "y", "z"], strings: [] }
1050
- };
1051
1102
  function parseEntity(arr) {
1052
- if (!Array.isArray(arr) || arr.length < 5) return null;
1053
- const [type, handle, layer, color, linetype, ...rest] = arr;
1054
- const schema = ENTITY_SCHEMAS[String(type)] || { fields: [], strings: [] };
1055
- const props = {};
1056
- schema.fields.forEach((name, i) => {
1057
- if (i < rest.length) {
1058
- let val = rest[i];
1059
- if (schema.strings.includes(name) && val !== null && val !== void 0) val = String(val);
1060
- props[name] = val;
1061
- }
1062
- });
1063
- return { type: String(type), handle: String(handle), layer: String(layer), color, linetype: String(linetype), ...props };
1103
+ if (!Array.isArray(arr) || arr.length < 5)
1104
+ return null;
1105
+ const [type, handle, layer, color, linetype] = arr;
1106
+ return { type: String(type), handle: String(handle), layer: String(layer), color, linetype: String(linetype) };
1064
1107
  }
1065
- function buildEntityCode({ type, layer, bbox, offset, limit }) {
1108
+ function buildEntityCode({ type, layer, bbox }) {
1066
1109
  const items = [];
1067
- if (type) items.push(`(cons 0 "${type.replace(/"/g, '\\"')}")`);
1068
- if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
1110
+ if (type)
1111
+ items.push(`(cons 0 "${type.replace(/"/g, '\\"')}")`);
1112
+ if (layer)
1113
+ items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
1069
1114
  if (bbox) {
1070
1115
  const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
1071
1116
  if (parts.length === 4) {
@@ -1081,55 +1126,22 @@ function buildEntityCode({ type, layer, bbox, offset, limit }) {
1081
1126
  const filterExpr = items.length ? `(list ${items.join(" ")})` : "nil";
1082
1127
  const ssgetExpr = items.length ? `(ssget "_X" ${filterExpr})` : '(ssget "_X")';
1083
1128
  return `(progn
1084
- (defun @e:props (ent / ed typ result item s e c verts closed ins)
1085
- (setq ed (entget ent) typ (cdr (assoc 0 ed)))
1086
- (setq result (list (vl-prin1-to-string (cdr (assoc 5 ed))) (vl-prin1-to-string (cdr (assoc 8 ed)))
1087
- (if (setq item (assoc 62 ed)) (cdr item) "ByLayer")
1088
- (vl-prin1-to-string (if (setq item (assoc 6 ed)) (cdr item) "ByLayer"))))
1089
- (cond
1090
- ((= typ "LINE")
1091
- (setq s (cdr (assoc 10 ed)) e (cdr (assoc 11 ed)))
1092
- (append result (list (car s) (cadr s) (caddr s) (car e) (cadr e) (caddr e) (distance s e))))
1093
- ((= typ "CIRCLE")
1094
- (setq c (cdr (assoc 10 ed)))
1095
- (append result (list (car c) (cadr c) (caddr c) (cdr (assoc 40 ed)))))
1096
- ((= typ "ARC")
1097
- (setq c (cdr (assoc 10 ed)))
1098
- (append result (list (car c) (cadr c) (caddr c) (cdr (assoc 40 ed)) (cdr (assoc 50 ed)) (cdr (assoc 51 ed)))))
1099
- ((= typ "LWPOLYLINE")
1100
- (setq verts nil closed nil)
1101
- (foreach g ed
1102
- (if (= (car g) 10) (setq verts (append verts (list (list (cadr g) (caddr g))))))
1103
- (if (= (car g) 70) (setq closed (= (logand (cdr g) 1) 1))))
1104
- (append result (list verts (if closed "T" nil))))
1105
- ((= typ "TEXT")
1106
- (setq ins (cdr (assoc 10 ed)))
1107
- (append result (list (car ins) (cadr ins) (caddr ins) (vl-prin1-to-string (cdr (assoc 1 ed))) (cdr (assoc 40 ed)) (cdr (assoc 50 ed))))))
1108
- ((= typ "MTEXT")
1109
- (setq ins (cdr (assoc 10 ed)))
1110
- (append result (list (car ins) (cadr ins) (caddr ins) (vl-prin1-to-string (cdr (assoc 1 ed))) (cdr (assoc 40 ed)) (cdr (assoc 50 ed))))))
1111
- ((= typ "INSERT")
1112
- (setq ins (cdr (assoc 10 ed)))
1113
- (append result (list (car ins) (cadr ins) (caddr ins) (vl-prin1-to-string (cdr (assoc 2 ed))) (cdr (assoc 50 ed)) (cdr (assoc 41 ed)) (cdr (assoc 42 ed))))))
1114
- ((= typ "POINT")
1115
- (setq p (cdr (assoc 10 ed)))
1116
- (append result (list (car p) (cadr p) (caddr p))))
1117
- (t result)))
1118
- (defun @e:run nil
1119
- (setq ss ${ssgetExpr})
1120
- (if (null ss)
1121
- (list "total" 0 "offset" ${offset} "limit" ${limit})
1122
- (progn
1123
- (setq total (sslength ss) entities nil i ${offset})
1124
- (while (and (< i total) (< (length entities) ${limit}))
1125
- (setq entities (append entities (list (@e:props (ssname ss i)))) i (1+ i)))
1126
- (list "total" total "offset" ${offset} "limit" ${limit} "entities" entities))))
1127
- (@e:run))
1128
- `;
1129
+ (vl-load-com)
1130
+ (defun @e:dp (ent / ed typ gc is)
1131
+ (setq ed (entget ent) typ (cdr (assoc 0 ed)) gc (assoc 62 ed) is (assoc 6 ed))
1132
+ (list typ (cdr (assoc 5 ed)) (cdr (assoc 8 ed))
1133
+ (if gc (cdr gc) 256)
1134
+ (if is (cdr is) "ByLayer")))
1135
+ (setq @e:total (if (setq @e:ss ${ssgetExpr}) (sslength @e:ss) 0)
1136
+ @e:ents nil @e:i 0)
1137
+ (while (and @e:ss (< @e:i @e:total)(< (length @e:ents) 100))
1138
+ (setq @e:ents (cons (@e:dp (ssname @e:ss @e:i)) @e:ents) @e:i (1+ @e:i)))
1139
+ (vl-prin1-to-string (list @e:total (reverse @e:ents))))`;
1129
1140
  }
1130
1141
  function buildTextCode({ layer, bbox, offset, limit }) {
1131
1142
  const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
1132
- if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
1143
+ if (layer)
1144
+ items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
1133
1145
  if (bbox) {
1134
1146
  const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
1135
1147
  if (parts.length === 4) {
@@ -1168,8 +1180,8 @@ function buildTextCode({ layer, bbox, offset, limit }) {
1168
1180
  var RESOURCES = [
1169
1181
  { uri: "atlisp://cad/info", name: "CAD Info", description: "CAD \u8FDE\u63A5\u4FE1\u606F", mimeType: "application/json", subscribable: true },
1170
1182
  { uri: "atlisp://dwg/layers", name: "Layers", description: "\u56FE\u5C42\u5217\u8868", mimeType: "application/json", subscribable: true },
1171
- { uri: "atlisp://dwg/entities", name: "Entities", description: "\u5B9E\u4F53\u5C5E\u6027\u5217\u8868\uFF0C\u652F\u6301 ?type=LINE&layer=0&bbox=0,0,100,100&limit=100&offset=0", mimeType: "application/json", subscribable: true },
1172
- { uri: "atlisp://dwg/texts", name: "Texts", description: "\u6587\u672C\u5B9E\u4F53\u5185\u5BB9\u5217\u8868 (TEXT/MTEXT/ATTRIB/TCH_TEXT)\uFF0C\u652F\u6301 ?layer=0&bbox=0,0,100,100&limit=500&offset=0", mimeType: "application/json", subscribable: true },
1183
+ { uri: "atlisp://dwg/entities", name: "Entities", description: "\u56FE\u5143\u5217\u8868\uFF0C\u8FD4\u56DE\u603B\u6570\u548C\u524D100\u4E2A\u56FE\u5143\uFF08\u7C7B\u578B\u3001\u53E5\u67C4\u3001\u56FE\u5C42\u3001\u989C\u8272\u3001\u7EBF\u578B\uFF09\uFF0C\u652F\u6301 ?type=LINE&layer=0&bbox=0,0,100,100 \u8FC7\u6EE4", mimeType: "application/json", subscribable: true },
1184
+ { uri: "atlisp://dwg/texts", name: "Texts", description: "\u6587\u672C\u5B9E\u4F53\u5185\u5BB9\u5217\u8868 (TEXT/MTEXT/ATTRIB/TCH_TEXT)\uFF0C\u652F\u6301 ?layer=0&bbox=0,0,100,100&limit=5000&offset=0", mimeType: "application/json", subscribable: true },
1173
1185
  { uri: "atlisp://dwg/name", name: "DWG Name", description: "\u5F53\u524D DWG \u6587\u4EF6\u540D", mimeType: "application/json", subscribable: true },
1174
1186
  { uri: "atlisp://dwg/path", name: "DWG Path", description: "\u6587\u4EF6\u5B8C\u6574\u8DEF\u5F84", mimeType: "application/json", subscribable: true },
1175
1187
  { uri: "atlisp://cad/dwgs", name: "DWG List", description: "\u6240\u6709\u6253\u5F00\u7684 DWG \u6587\u4EF6\u5217\u8868", mimeType: "application/json", subscribable: true },
@@ -1180,14 +1192,16 @@ var RESOURCES = [
1180
1192
  ];
1181
1193
  function parseQuery(uri) {
1182
1194
  const qIdx = uri.indexOf("?");
1183
- if (qIdx === -1) return { base: uri, params: {} };
1195
+ if (qIdx === -1)
1196
+ return { base: uri, params: {} };
1184
1197
  const base = uri.substring(0, qIdx);
1185
1198
  const params = {};
1186
1199
  uri.substring(qIdx + 1).split("&").forEach((p) => {
1187
1200
  const eqIdx = p.indexOf("=");
1188
1201
  const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
1189
1202
  const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
1190
- if (k) params[k] = decodeURIComponent(v);
1203
+ if (k)
1204
+ params[k] = decodeURIComponent(v);
1191
1205
  });
1192
1206
  return { base, params };
1193
1207
  }
@@ -1231,7 +1245,8 @@ async function readResource(uri) {
1231
1245
  }
1232
1246
  async function getCadInfo2() {
1233
1247
  const cached = getCached("cad:info");
1234
- if (cached) return cached;
1248
+ if (cached)
1249
+ return cached;
1235
1250
  if (!cad.connected) {
1236
1251
  await cad.connect();
1237
1252
  }
@@ -1258,11 +1273,14 @@ async function getCadInfo2() {
1258
1273
  async function getLayers(filterName = null) {
1259
1274
  const cacheKey = filterName ? `dwg:layers:${filterName}` : "dwg:layers:all";
1260
1275
  const cached = getCached(cacheKey);
1261
- if (cached) return cached;
1262
- if (!cad.connected) await cad.connect();
1263
- if (!cad.connected) return [];
1276
+ if (cached)
1277
+ return cached;
1278
+ if (!cad.connected)
1279
+ await cad.connect();
1280
+ if (!cad.connected)
1281
+ return [];
1264
1282
  try {
1265
- 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))`;
1283
+ const code = filterName ? `(vl-prin1-to-string (cdr (assoc 2 (tblnext "LAYER" T))))` : `(progn (setq res nil)(while (setq e (tblnext "LAYER" (null res)))(setq res (cons (list (vl-prin1-to-string (cdr (assoc 2 e))) (cdr (assoc 62 e)) (cdr (assoc 70 e))) res))) (reverse res))`;
1266
1284
  const result = await cad.sendCommandWithResult(code);
1267
1285
  if (!result || result === "" || result === "nil") {
1268
1286
  setCache(cacheKey, []);
@@ -1307,46 +1325,42 @@ async function getLayers(filterName = null) {
1307
1325
  async function getEntities(params = {}) {
1308
1326
  const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
1309
1327
  const cached = getCached(cacheKey);
1310
- if (cached) return cached;
1311
- if (!cad.connected) await cad.connect();
1328
+ if (cached)
1329
+ return cached;
1330
+ if (!cad.connected)
1331
+ await cad.connect();
1312
1332
  if (!cad.connected) {
1313
1333
  const result = { total: 0, entities: [] };
1314
1334
  setCache(cacheKey, result);
1315
1335
  return result;
1316
1336
  }
1317
- const offset = Math.max(0, parseInt(params.offset) || 0);
1318
- const limit = Math.min(Math.max(1, parseInt(params.limit) || 100), 1e3);
1319
1337
  try {
1320
1338
  const code = buildEntityCode({
1321
1339
  type: params.type || null,
1322
1340
  layer: params.layer || null,
1323
- bbox: params.bbox || null,
1324
- offset,
1325
- limit
1341
+ bbox: params.bbox || null
1326
1342
  });
1327
1343
  const resultStr = await cad.sendCommandWithResult(code);
1328
- if (!resultStr || resultStr === "" || resultStr === "nil" || resultStr === "0") {
1329
- const result = { total: 0, offset, limit, entities: [] };
1330
- setCache(cacheKey, result);
1331
- return result;
1344
+ if (!resultStr || resultStr === "" || resultStr === "nil") {
1345
+ const result2 = { total: 0, entities: [] };
1346
+ setCache(cacheKey, result2);
1347
+ return result2;
1332
1348
  }
1349
+ let total = 0;
1350
+ let entities = [];
1333
1351
  const parsed = parseLispRecursive(resultStr);
1334
- if (!parsed || !Array.isArray(parsed)) {
1335
- const result = { total: 0, offset, limit, entities: [] };
1336
- setCache(cacheKey, result);
1337
- return result;
1352
+ if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
1353
+ total = typeof parsed[0] === "number" ? parsed[0] : 0;
1354
+ const rawEntities = Array.isArray(parsed[1]) ? parsed[1] : [];
1355
+ entities = rawEntities.map(parseEntity).filter(Boolean);
1338
1356
  }
1339
- const entitiesIdx = parsed.indexOf("entities");
1340
- const rawEntities = entitiesIdx !== -1 && Array.isArray(parsed[entitiesIdx + 1]) ? parsed[entitiesIdx + 1] : [];
1341
- const data = lispPairsToObject(parsed);
1342
- data.entities = rawEntities.length > 0 ? rawEntities.map(parseEntity).filter(Boolean) : [];
1343
- data.offset = offset;
1344
- data.limit = limit;
1345
- setCache(cacheKey, data);
1346
- return data;
1357
+ const result = { total, entities };
1358
+ log(`getEntities: total=${total}, returned=${entities.length}`);
1359
+ setCache(cacheKey, result);
1360
+ return result;
1347
1361
  } catch (e) {
1348
1362
  log(`getEntities error: ${e.message}`);
1349
- const result = { total: 0, offset, limit, entities: [] };
1363
+ const result = { total: 0, entities: [] };
1350
1364
  setCache(cacheKey, result);
1351
1365
  return result;
1352
1366
  }
@@ -1354,15 +1368,17 @@ async function getEntities(params = {}) {
1354
1368
  async function getTexts(params = {}) {
1355
1369
  const cacheKey = `dwg:texts:${JSON.stringify(params)}`;
1356
1370
  const cached = getCached(cacheKey);
1357
- if (cached) return cached;
1358
- if (!cad.connected) await cad.connect();
1371
+ if (cached)
1372
+ return cached;
1373
+ if (!cad.connected)
1374
+ await cad.connect();
1359
1375
  if (!cad.connected) {
1360
1376
  const result = { total: 0, texts: [] };
1361
1377
  setCache(cacheKey, result);
1362
1378
  return result;
1363
1379
  }
1364
1380
  const offset = Math.max(0, parseInt(params.offset) || 0);
1365
- const limit = Math.min(Math.max(1, parseInt(params.limit) || 500), 5e3);
1381
+ const limit = Math.min(Math.max(1, parseInt(params.limit) || 5e3), 5e3);
1366
1382
  try {
1367
1383
  const code = buildTextCode({
1368
1384
  layer: params.layer || null,
@@ -1393,8 +1409,10 @@ async function getTexts(params = {}) {
1393
1409
  }
1394
1410
  }
1395
1411
  async function getDwgName() {
1396
- if (!cad.connected) await cad.connect();
1397
- if (!cad.connected) return { name: null };
1412
+ if (!cad.connected)
1413
+ await cad.connect();
1414
+ if (!cad.connected)
1415
+ return { name: null };
1398
1416
  try {
1399
1417
  const code = `(vl-princ-to-string (getvar "dwgname"))`;
1400
1418
  const name = await cad.sendCommandWithResult(code);
@@ -1404,8 +1422,10 @@ async function getDwgName() {
1404
1422
  }
1405
1423
  }
1406
1424
  async function getDwgPath() {
1407
- if (!cad.connected) await cad.connect();
1408
- if (!cad.connected) return { path: null, name: null };
1425
+ if (!cad.connected)
1426
+ await cad.connect();
1427
+ if (!cad.connected)
1428
+ return { path: null, name: null };
1409
1429
  try {
1410
1430
  const code = `(progn
1411
1431
  (setq prefix (vl-princ-to-string (getvar "dwgprefix")))
@@ -1423,7 +1443,8 @@ async function getDwgPath() {
1423
1443
  }
1424
1444
  if (!parsed) {
1425
1445
  const listResult = parseLispList(result);
1426
- if (listResult && listResult.length >= 2) parsed = listResult;
1446
+ if (listResult && listResult.length >= 2)
1447
+ parsed = listResult;
1427
1448
  }
1428
1449
  if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
1429
1450
  return { path: String(parsed[0]), name: String(parsed[1]) };
@@ -1436,9 +1457,12 @@ async function getDwgPath() {
1436
1457
  async function getPackages(filterName = null) {
1437
1458
  const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
1438
1459
  const cached = getCached(cacheKey);
1439
- if (cached) return cached;
1440
- if (!cad.connected) await cad.connect();
1441
- if (!cad.connected) return [];
1460
+ if (cached)
1461
+ return cached;
1462
+ if (!cad.connected)
1463
+ await cad.connect();
1464
+ if (!cad.connected)
1465
+ return [];
1442
1466
  try {
1443
1467
  const code = `(mapcar 'cdr @::*local-pkgs*)`;
1444
1468
  const result = await cad.sendCommandWithResult(code);
@@ -1452,7 +1476,8 @@ async function getPackages(filterName = null) {
1452
1476
  } catch {
1453
1477
  raw = parseLispList(result) || [];
1454
1478
  }
1455
- if (!Array.isArray(raw)) raw = [];
1479
+ if (!Array.isArray(raw))
1480
+ raw = [];
1456
1481
  const packages = raw.map((item) => {
1457
1482
  if (Array.isArray(item)) {
1458
1483
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
@@ -1461,13 +1486,20 @@ async function getPackages(filterName = null) {
1461
1486
  const [[key, val]] = Object.entries(entry);
1462
1487
  const k = String(key);
1463
1488
  const v = String(val);
1464
- if (k === ":NAME") pkg.name = v;
1465
- else if (k === ":VERSION") pkg.version = v;
1466
- else if (k === ":DESCRIPTION") pkg.description = v;
1467
- else if (k === ":FULL-NAME") pkg.fullName = v;
1468
- else if (k === ":AUTHOR") pkg.author = v;
1469
- else if (k === ":CATEGORY") pkg.category = v;
1470
- else if (k === ":URL") pkg.url = v;
1489
+ if (k === ":NAME")
1490
+ pkg.name = v;
1491
+ else if (k === ":VERSION")
1492
+ pkg.version = v;
1493
+ else if (k === ":DESCRIPTION")
1494
+ pkg.description = v;
1495
+ else if (k === ":FULL-NAME")
1496
+ pkg.fullName = v;
1497
+ else if (k === ":AUTHOR")
1498
+ pkg.author = v;
1499
+ else if (k === ":CATEGORY")
1500
+ pkg.category = v;
1501
+ else if (k === ":URL")
1502
+ pkg.url = v;
1471
1503
  }
1472
1504
  }
1473
1505
  return pkg;
@@ -1478,15 +1510,22 @@ async function getPackages(filterName = null) {
1478
1510
  if (item && typeof item === "object") {
1479
1511
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
1480
1512
  const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
1481
- if (nameVal) pkg.name = String(nameVal);
1513
+ if (nameVal)
1514
+ pkg.name = String(nameVal);
1482
1515
  const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
1483
- if (verVal) pkg.version = String(verVal);
1516
+ if (verVal)
1517
+ pkg.version = String(verVal);
1484
1518
  const descVal = item.description || item.Description || item.DESCRIPTION || item[":DESCRIPTION"];
1485
- if (descVal) pkg.description = String(descVal);
1486
- if (item.fullName || item.full_name) pkg.fullName = String(item.fullName || item.full_name);
1487
- if (item.author || item.Author) pkg.author = String(item.author || item.Author);
1488
- if (item.category || item.Category) pkg.category = String(item.category || item.Category);
1489
- if (item.url || item.Url || item.URL) pkg.url = String(item.url || item.Url || item.URL);
1519
+ if (descVal)
1520
+ pkg.description = String(descVal);
1521
+ if (item.fullName || item.full_name)
1522
+ pkg.fullName = String(item.fullName || item.full_name);
1523
+ if (item.author || item.Author)
1524
+ pkg.author = String(item.author || item.Author);
1525
+ if (item.category || item.Category)
1526
+ pkg.category = String(item.category || item.Category);
1527
+ if (item.url || item.Url || item.URL)
1528
+ pkg.url = String(item.url || item.Url || item.URL);
1490
1529
  return pkg;
1491
1530
  }
1492
1531
  return null;
@@ -1512,9 +1551,12 @@ function getPlatforms() {
1512
1551
  async function getDwgList() {
1513
1552
  const cacheKey = "cad:dwgs";
1514
1553
  const cached = getCached(cacheKey);
1515
- if (cached) return cached;
1516
- if (!cad.connected) await cad.connect();
1517
- if (!cad.connected) return [];
1554
+ if (cached)
1555
+ return cached;
1556
+ if (!cad.connected)
1557
+ await cad.connect();
1558
+ if (!cad.connected)
1559
+ return [];
1518
1560
  try {
1519
1561
  const code = `(progn
1520
1562
  (vl-load-com)
@@ -1538,7 +1580,8 @@ async function getDwgList() {
1538
1580
  parsed = listResult;
1539
1581
  }
1540
1582
  }
1541
- if (!Array.isArray(parsed)) parsed = [];
1583
+ if (!Array.isArray(parsed))
1584
+ parsed = [];
1542
1585
  const dwgList = parsed.map((item) => {
1543
1586
  if (Array.isArray(item) && item.length >= 2) {
1544
1587
  return { name: String(item[0]), path: String(item[1]) };
@@ -1565,7 +1608,8 @@ function loadStandardsFile(filename) {
1565
1608
  var standardsCache = /* @__PURE__ */ new Map();
1566
1609
  function getCachedStandards(key) {
1567
1610
  const entry = standardsCache.get(key);
1568
- if (entry && Date.now() - entry.timestamp < 3e4) return entry.data;
1611
+ if (entry && Date.now() - entry.timestamp < 3e4)
1612
+ return entry.data;
1569
1613
  standardsCache.delete(key);
1570
1614
  return null;
1571
1615
  }
@@ -1574,16 +1618,20 @@ function setCachedStandards(key, data) {
1574
1618
  }
1575
1619
  function getDraftingStandards() {
1576
1620
  const cached = getCachedStandards("drafting");
1577
- if (cached) return cached;
1621
+ if (cached)
1622
+ return cached;
1578
1623
  const data = loadStandardsFile("drafting.json");
1579
- if (data) setCachedStandards("drafting", data);
1624
+ if (data)
1625
+ setCachedStandards("drafting", data);
1580
1626
  return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
1581
1627
  }
1582
1628
  function getCodingStandards() {
1583
1629
  const cached = getCachedStandards("coding");
1584
- if (cached) return cached;
1630
+ if (cached)
1631
+ return cached;
1585
1632
  const data = loadStandardsFile("coding.json");
1586
- if (data) setCachedStandards("coding", data);
1633
+ if (data)
1634
+ setCachedStandards("coding", data);
1587
1635
  return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
1588
1636
  }
1589
1637
 
@@ -1837,10 +1885,14 @@ ${generateSuggestions(entities, layers)}`
1837
1885
  }
1838
1886
  function generateSuggestions(entities, layers) {
1839
1887
  const suggestions = [];
1840
- if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
1841
- if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
1842
- 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");
1843
- if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
1888
+ if (entities.total > 1e3)
1889
+ suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
1890
+ if (layers.length > 20)
1891
+ suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
1892
+ if (entities.byType.LINE && entities.byType.LINE > 500)
1893
+ suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
1894
+ if (!entities.byType.DIMENSION)
1895
+ suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
1844
1896
  return suggestions.length ? suggestions.join("\n") : "- \u56FE\u7EB8\u7ED3\u6784\u826F\u597D";
1845
1897
  }
1846
1898
  async function generateBatchLinesPrompt(args) {
@@ -2568,9 +2620,11 @@ var SseSession = class {
2568
2620
  return lines.join("\n") + "\n\n";
2569
2621
  }
2570
2622
  _setupDrain() {
2571
- if (typeof this.#res.on !== "function") return;
2623
+ if (typeof this.#res.on !== "function")
2624
+ return;
2572
2625
  this.#drainHandler = () => {
2573
- if (!this.#active) return;
2626
+ if (!this.#active)
2627
+ return;
2574
2628
  if (this.#backpressureBuffer.length > 0) {
2575
2629
  this._drainBuffer();
2576
2630
  }
@@ -2592,7 +2646,8 @@ var SseSession = class {
2592
2646
  }
2593
2647
  }
2594
2648
  _write(content) {
2595
- if (!this.#active) return false;
2649
+ if (!this.#active)
2650
+ return false;
2596
2651
  try {
2597
2652
  if (this.#backpressureBuffer.length > 0) {
2598
2653
  this.#backpressureBuffer.push(content);
@@ -2720,7 +2775,8 @@ function persistSessionData(clientId, sessionData) {
2720
2775
  function loadPersistedSessionData(clientId) {
2721
2776
  try {
2722
2777
  const filePath = getSessionStorePath(clientId);
2723
- if (!fs5.existsSync(filePath)) return null;
2778
+ if (!fs5.existsSync(filePath))
2779
+ return null;
2724
2780
  const raw = fs5.readFileSync(filePath, "utf-8");
2725
2781
  const store = JSON.parse(raw);
2726
2782
  if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
@@ -2909,7 +2965,8 @@ var SERVER_CAPABILITIES = {
2909
2965
  prompts: {}
2910
2966
  };
2911
2967
  var { port, host, transport, apiKey, rateLimitWindow, rateLimitMax } = config_default;
2912
- if (apiKey) log("API Key authentication enabled");
2968
+ if (apiKey)
2969
+ log("API Key authentication enabled");
2913
2970
  var mcpLimiter = rateLimit({
2914
2971
  windowMs: rateLimitWindow,
2915
2972
  max: rateLimitMax,
@@ -2994,7 +3051,8 @@ ${CAD_PLATFORMS.join("\n")}
2994
3051
  },
2995
3052
  import_funlib: async (a) => {
2996
3053
  const data = await loadAtlibFunctionLib();
2997
- if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
3054
+ if (!data)
3055
+ return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
2998
3056
  if (a.format === "list") {
2999
3057
  const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
3000
3058
  return { content: [{ type: "text", text: items.join("\n") }] };
@@ -3183,7 +3241,8 @@ var tools = [
3183
3241
  ];
3184
3242
  async function handleToolCall(name, args) {
3185
3243
  const handler = TOOL_HANDLERS[name];
3186
- if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
3244
+ if (!handler)
3245
+ return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
3187
3246
  try {
3188
3247
  const result = await handler(args || {});
3189
3248
  notifyResourceChanges(name);
@@ -3306,7 +3365,8 @@ async function startServer() {
3306
3365
  const JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "application/vnd.api+json"];
3307
3366
  app.use(async (req, res, next) => {
3308
3367
  const ct = (req.headers["content-type"] || "").toLowerCase();
3309
- if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
3368
+ if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
3369
+ return next();
3310
3370
  try {
3311
3371
  const buf = await rawBody(req, { limit: "10mb" });
3312
3372
  const m = ct.match(/charset\s*=\s*([^\s;]+)/i);
@@ -3327,9 +3387,11 @@ async function startServer() {
3327
3387
  const PUBLIC_PATHS = ["/health"];
3328
3388
  if (apiKey) {
3329
3389
  app.use((req, res, next) => {
3330
- if (PUBLIC_PATHS.includes(req.path)) return next();
3390
+ if (PUBLIC_PATHS.includes(req.path))
3391
+ return next();
3331
3392
  const auth = req.get("Authorization");
3332
- if (auth === `Bearer ${apiKey}`) return next();
3393
+ if (auth === `Bearer ${apiKey}`)
3394
+ return next();
3333
3395
  res.status(401).json({ error: "Unauthorized" });
3334
3396
  });
3335
3397
  }
@@ -3344,7 +3406,8 @@ async function startServer() {
3344
3406
  res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
3345
3407
  res.setHeader("Access-Control-Max-Age", "86400");
3346
3408
  res.setHeader("Vary", "Accept");
3347
- if (req.method === "OPTIONS") return res.status(204).end();
3409
+ if (req.method === "OPTIONS")
3410
+ return res.status(204).end();
3348
3411
  next();
3349
3412
  });
3350
3413
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlisp/mcp",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "MCP Server for @lisp on CAD",
5
5
  "type": "module",
6
6
  "bin": {