@atlisp/mcp 1.6.8 → 1.6.9

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.
@@ -2,7 +2,6 @@
2
2
 
3
3
  // src/atlisp-mcp.js
4
4
  import path10 from "path";
5
- import fs8 from "fs";
6
5
  import { fileURLToPath as fileURLToPath4 } from "url";
7
6
  import { createRequire } from "module";
8
7
  import express2 from "express";
@@ -23,7 +22,7 @@ var FILE_EXTENSIONS = {
23
22
  "BricsCAD": [".des"]
24
23
  };
25
24
  var SERVER_NAME = "atlisp-mcp-server";
26
- var SERVER_VERSION = "1.6.7";
25
+ var SERVER_VERSION = "1.6.4";
27
26
  var MOCK_PACKAGES = [
28
27
  { name: "base", description: "\u57FA\u7840\u51FD\u6570\u5E93", version: "1.0.0" },
29
28
  { name: "at-pm", description: "\u5DE5\u7A0B\u9879\u76EE\u7BA1\u7406", version: "2.1.0" },
@@ -116,8 +115,7 @@ function parseArgs() {
116
115
  return result;
117
116
  }
118
117
  function loadConfigFile(filePath) {
119
- if (!filePath || !fs.existsSync(filePath))
120
- return null;
118
+ if (!filePath || !fs.existsSync(filePath)) return null;
121
119
  try {
122
120
  const raw = fs.readFileSync(filePath, "utf-8");
123
121
  const parsed = JSON.parse(raw);
@@ -255,8 +253,7 @@ function setupStdoutHandler(w) {
255
253
  const lines = buffer.split("\n");
256
254
  buffer = lines.pop() || "";
257
255
  for (const line of lines) {
258
- if (!line.trim())
259
- continue;
256
+ if (!line.trim()) continue;
260
257
  try {
261
258
  const result = JSON.parse(line);
262
259
  const rid = result.requestId;
@@ -282,8 +279,7 @@ function setupStdoutHandler(w) {
282
279
  }
283
280
  function getWorker(force = false) {
284
281
  if (!worker || !worker.connected || force) {
285
- if (worker)
286
- worker.kill();
282
+ if (worker) worker.kill();
287
283
  worker = spawn("node", [workerPath], {
288
284
  stdio: ["pipe", "pipe", "pipe"]
289
285
  });
@@ -291,8 +287,7 @@ function getWorker(force = false) {
291
287
  const w = worker;
292
288
  w.on("exit", (code) => {
293
289
  console.error("worker exited with code:", code);
294
- if (w !== worker)
295
- return;
290
+ if (w !== worker) return;
296
291
  w.connected = false;
297
292
  for (const [id, { reject, timeout }] of pendingRequests) {
298
293
  clearTimeout(timeout);
@@ -313,8 +308,7 @@ function getWorker(force = false) {
313
308
  return worker;
314
309
  }
315
310
  function startHeartbeat() {
316
- if (heartbeatTimer)
317
- clearInterval(heartbeatTimer);
311
+ if (heartbeatTimer) clearInterval(heartbeatTimer);
318
312
  heartbeatTimer = setInterval(async () => {
319
313
  try {
320
314
  const result = await sendMessage({ type: "ping" });
@@ -359,8 +353,7 @@ var CadConnection = class {
359
353
  return process.platform === "win32";
360
354
  }
361
355
  async connect(platform = null) {
362
- if (!this.isAvailable())
363
- return false;
356
+ if (!this.isAvailable()) return false;
364
357
  try {
365
358
  const msg = platform ? { type: "connect", platform } : { type: "connect" };
366
359
  const result = await sendMessage(msg);
@@ -377,16 +370,13 @@ var CadConnection = class {
377
370
  return false;
378
371
  }
379
372
  async sendCommand(code) {
380
- if (!this.connected)
381
- throw new Error("\u672A\u8FDE\u63A5 CAD");
373
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
382
374
  const result = await sendMessage({ type: "send", code, platform: _platform });
383
- if (result.success)
384
- return true;
375
+ if (result.success) return true;
385
376
  throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
386
377
  }
387
378
  async sendCommandWithResult(code, encoding = null) {
388
- if (!this.connected)
389
- throw new Error("\u672A\u8FDE\u63A5 CAD");
379
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
390
380
  const result = await sendMessage({ type: "sendResult", code, platform: _platform, encoding: encoding || "" });
391
381
  if (result.success) {
392
382
  return result.result || "";
@@ -400,8 +390,7 @@ var CadConnection = class {
400
390
  return this.product;
401
391
  }
402
392
  async isBusy() {
403
- if (!this.connected)
404
- return false;
393
+ if (!this.connected) return false;
405
394
  try {
406
395
  const result = await sendMessage({ type: "isBusy", platform: _platform });
407
396
  return result && result.isBusy;
@@ -410,8 +399,7 @@ var CadConnection = class {
410
399
  }
411
400
  }
412
401
  async hasDoc() {
413
- if (!this.connected)
414
- return { hasDoc: false, docCount: 0 };
402
+ if (!this.connected) return { hasDoc: false, docCount: 0 };
415
403
  try {
416
404
  const result = await sendMessage({ type: "hasdoc", platform: _platform });
417
405
  return result || { hasDoc: false, docCount: 0 };
@@ -420,8 +408,7 @@ var CadConnection = class {
420
408
  }
421
409
  }
422
410
  async newDoc() {
423
- if (!this.connected)
424
- throw new Error("\u672A\u8FDE\u63A5 CAD");
411
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
425
412
  try {
426
413
  const result = await sendMessage({ type: "newdoc", platform: _platform });
427
414
  return result && result.success;
@@ -430,8 +417,7 @@ var CadConnection = class {
430
417
  }
431
418
  }
432
419
  async bringToFront() {
433
- if (!this.connected)
434
- throw new Error("\u672A\u8FDE\u63A5 CAD");
420
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
435
421
  try {
436
422
  const result = await sendMessage({ type: "bringToFront", platform: _platform });
437
423
  return result && result.success;
@@ -440,8 +426,7 @@ var CadConnection = class {
440
426
  }
441
427
  }
442
428
  async getInfo() {
443
- if (!this.connected)
444
- return "CAD \u672A\u8FDE\u63A5";
429
+ if (!this.connected) return "CAD \u672A\u8FDE\u63A5";
445
430
  return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
446
431
  }
447
432
  async disconnect() {
@@ -478,11 +463,9 @@ var MAX_LOG_SIZE = 10 * 1024 * 1024;
478
463
  var MAX_LOG_FILES = 5;
479
464
  var stream = null;
480
465
  function rotateLog() {
481
- if (!fs2.existsSync(DEBUG_FILE))
482
- return;
466
+ if (!fs2.existsSync(DEBUG_FILE)) return;
483
467
  const stat = fs2.statSync(DEBUG_FILE);
484
- if (stat.size < MAX_LOG_SIZE)
485
- return;
468
+ if (stat.size < MAX_LOG_SIZE) return;
486
469
  if (stream) {
487
470
  stream.end();
488
471
  stream = null;
@@ -546,11 +529,9 @@ function ensureRequestLogDir() {
546
529
  }
547
530
  }
548
531
  function rotateRequestLog() {
549
- if (!fs2.existsSync(REQUEST_LOG_FILE))
550
- return;
532
+ if (!fs2.existsSync(REQUEST_LOG_FILE)) return;
551
533
  const stat = fs2.statSync(REQUEST_LOG_FILE);
552
- if (stat.size < 10 * 1024 * 1024)
553
- return;
534
+ if (stat.size < 10 * 1024 * 1024) return;
554
535
  const dir = path3.dirname(REQUEST_LOG_FILE);
555
536
  for (let i = 5; i > 0; i--) {
556
537
  const oldPath = `${REQUEST_LOG_FILE}.${i}`;
@@ -568,8 +549,7 @@ function rotateRequestLog() {
568
549
  }
569
550
  }
570
551
  function logRequest(req) {
571
- if (!config_default.requestLogEnabled)
572
- return;
552
+ if (!config_default.requestLogEnabled) return;
573
553
  try {
574
554
  ensureRequestLogDir();
575
555
  rotateRequestLog();
@@ -586,8 +566,7 @@ function logRequest(req) {
586
566
  }
587
567
  }
588
568
  function logResponse(req, res, duration) {
589
- if (!config_default.requestLogEnabled)
590
- return;
569
+ if (!config_default.requestLogEnabled) return;
591
570
  try {
592
571
  ensureRequestLogDir();
593
572
  const entry = {
@@ -685,14 +664,11 @@ function clearCache(uri) {
685
664
  }
686
665
  }
687
666
  function parseLispList(str) {
688
- if (!str || typeof str !== "string")
689
- return null;
667
+ if (!str || typeof str !== "string") return null;
690
668
  const trimmed = str.trim();
691
- if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
692
- return null;
669
+ if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) return null;
693
670
  const content = trimmed.slice(1, -1).trim();
694
- if (!content)
695
- return [];
671
+ if (!content) return [];
696
672
  const result = [];
697
673
  let depth = 0;
698
674
  let current = "";
@@ -734,44 +710,32 @@ function parseLispList(str) {
734
710
  }
735
711
  current += ch;
736
712
  }
737
- if (current.trim())
738
- result.push(current.trim());
713
+ if (current.trim()) result.push(current.trim());
739
714
  return result.map((item) => {
740
715
  const t = item.trim();
741
- if (t === "nil")
742
- return null;
743
- if (t === "t")
744
- return true;
745
- if (t === "T")
746
- return true;
716
+ if (t === "nil") return null;
717
+ if (t === "t") return true;
718
+ if (t === "T") return true;
747
719
  const num = Number(t);
748
- if (!isNaN(num) && t !== "")
749
- return num;
750
- if (t.startsWith('"') && t.endsWith('"'))
751
- return t.slice(1, -1);
720
+ if (!isNaN(num) && t !== "") return num;
721
+ if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
752
722
  return t;
753
723
  });
754
724
  }
755
725
  function parseLispRecursive(str) {
756
- if (!str || typeof str !== "string")
757
- return null;
726
+ if (!str || typeof str !== "string") return null;
758
727
  str = str.trim();
759
- if (!str)
760
- return null;
728
+ if (!str) return null;
761
729
  let pos = 0;
762
730
  function skipWs() {
763
- while (pos < str.length && /\s/.test(str[pos]))
764
- pos++;
731
+ while (pos < str.length && /\s/.test(str[pos])) pos++;
765
732
  }
766
733
  function parseValue() {
767
734
  skipWs();
768
- if (pos >= str.length)
769
- return null;
735
+ if (pos >= str.length) return null;
770
736
  const ch = str[pos];
771
- if (ch === "(")
772
- return parseList();
773
- if (ch === '"')
774
- return parseString();
737
+ if (ch === "(") return parseList();
738
+ if (ch === '"') return parseString();
775
739
  if (ch === "'") {
776
740
  pos++;
777
741
  return parseValue();
@@ -784,16 +748,11 @@ function parseLispRecursive(str) {
784
748
  while (pos < str.length && str[pos] !== '"') {
785
749
  if (str[pos] === "\\" && pos + 1 < str.length) {
786
750
  pos++;
787
- if (str[pos] === '"')
788
- r += '"';
789
- else if (str[pos] === "n")
790
- r += "\n";
791
- else if (str[pos] === "t")
792
- r += " ";
793
- else if (str[pos] === "\\")
794
- r += "\\";
795
- else
796
- r += str[pos];
751
+ if (str[pos] === '"') r += '"';
752
+ else if (str[pos] === "n") r += "\n";
753
+ else if (str[pos] === "t") r += " ";
754
+ else if (str[pos] === "\\") r += "\\";
755
+ else r += str[pos];
797
756
  } else {
798
757
  r += str[pos];
799
758
  }
@@ -804,16 +763,12 @@ function parseLispRecursive(str) {
804
763
  }
805
764
  function parseAtom() {
806
765
  const start = pos;
807
- while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
808
- pos++;
766
+ while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(") pos++;
809
767
  const atom = str.slice(start, pos);
810
- if (atom === "nil" || atom === "NIL")
811
- return null;
812
- if (atom === "t" || atom === "T")
813
- return true;
768
+ if (atom === "nil" || atom === "NIL") return null;
769
+ if (atom === "t" || atom === "T") return true;
814
770
  const num = Number(atom);
815
- if (!isNaN(num) && atom !== "")
816
- return num;
771
+ if (!isNaN(num) && atom !== "") return num;
817
772
  return atom;
818
773
  }
819
774
  function parseList() {
@@ -821,15 +776,13 @@ function parseLispRecursive(str) {
821
776
  const items = [];
822
777
  while (pos < str.length) {
823
778
  skipWs();
824
- if (pos >= str.length)
825
- break;
779
+ if (pos >= str.length) break;
826
780
  if (str[pos] === ")") {
827
781
  pos++;
828
782
  return items;
829
783
  }
830
784
  const left = parseValue();
831
- if (left === void 0)
832
- break;
785
+ if (left === void 0) break;
833
786
  skipWs();
834
787
  if (str[pos] === "." && (pos + 1 >= str.length || /\s/.test(str[pos + 1]) || str[pos + 1] === ")")) {
835
788
  pos++;
@@ -852,8 +805,7 @@ function parseLispRecursive(str) {
852
805
  return parseValue();
853
806
  }
854
807
  function lispPairsToObject(pairs) {
855
- if (!Array.isArray(pairs))
856
- return pairs;
808
+ if (!Array.isArray(pairs)) return pairs;
857
809
  const obj = {};
858
810
  for (let i = 0; i < pairs.length - 1; i += 2) {
859
811
  const key = pairs[i];
@@ -865,8 +817,7 @@ function lispPairsToObject(pairs) {
865
817
  return obj;
866
818
  }
867
819
  function propertyPairsToObject(pairs) {
868
- if (!Array.isArray(pairs))
869
- return null;
820
+ if (!Array.isArray(pairs)) return null;
870
821
  const obj = {};
871
822
  for (const pair of pairs) {
872
823
  if (Array.isArray(pair) && pair.length >= 2) {
@@ -877,10 +828,8 @@ function propertyPairsToObject(pairs) {
877
828
  }
878
829
  function buildEntityPropertiesCode({ type, layer, bbox }) {
879
830
  const items = [];
880
- if (type)
881
- items.push(`(cons 0 "${type.replace(/"/g, '\\"')}")`);
882
- if (layer)
883
- items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
831
+ if (type) items.push(`(cons 0 "${type.replace(/"/g, '\\"')}")`);
832
+ if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
884
833
  if (bbox) {
885
834
  const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
886
835
  if (parts.length === 4) {
@@ -905,56 +854,14 @@ ${ENTITY_PROPERTIES_LISP}
905
854
  @e:i (1+ @e:i)))
906
855
  (vl-prin1-to-string (list @e:total (reverse @e:ents))))`;
907
856
  }
908
- function buildTextCode({ layer, bbox, offset, limit }) {
909
- const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
910
- if (layer)
911
- items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
912
- if (bbox) {
913
- const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
914
- if (parts.length === 4) {
915
- const [x1, y1, x2, y2] = parts;
916
- items.push(
917
- `'(-4 . "<AND")`,
918
- `'(-4 . ">=,>=,*") (list 10 ${x1} ${y1} 0.0)`,
919
- `'(-4 . "<=,<=,*") (list 10 ${x2} ${y2} 0.0)`,
920
- `'(-4 . "AND>")`
921
- );
922
- }
923
- }
924
- const filterExpr = `(list ${items.join(" ")})`;
925
- return `(progn
926
- (defun @t:props (ent / ed ins)
927
- (setq ed (entget ent) ins (cdr (assoc 10 ed)))
928
- (list
929
- (list "type" (vl-prin1-to-string (cdr (assoc 0 ed))))
930
- (list "handle" (vl-prin1-to-string (cdr (assoc 5 ed))))
931
- (list "layer" (vl-prin1-to-string (cdr (assoc 8 ed))))
932
- (list "color" (if (assoc 62 ed) (cdr (assoc 62 ed)) 256))
933
- (list "linetype" (vl-prin1-to-string (if (assoc 6 ed) (cdr (assoc 6 ed)) "ByLayer")))
934
- (list "text" (vl-prin1-to-string (cdr (assoc 1 ed))))
935
- (list "insert" (list (car ins) (cadr ins) (caddr ins)))
936
- (list "height" (cdr (assoc 40 ed)))
937
- (list "rotation" (cdr (assoc 50 ed)))
938
- (list "style" (vl-prin1-to-string (if (assoc 7 ed) (cdr (assoc 7 ed)) "Standard")))))
939
- (defun @t:run nil
940
- (setq ss (ssget "_X" ${filterExpr}))
941
- (if (null ss)
942
- (list "total" 0 "offset" ${offset} "limit" ${limit})
943
- (progn
944
- (setq total (sslength ss) texts nil i ${offset})
945
- (while (and (< i total) (< (length texts) ${limit}))
946
- (setq texts (append texts (list (@t:props (ssname ss i)))) i (1+ i)))
947
- (list "total" total "offset" ${offset} "limit" ${limit} "texts" texts))))
948
- (@t:run))
949
- `;
950
- }
951
857
  var RESOURCES = [
952
858
  { uri: "atlisp://cad/info", name: "CAD Info", description: "CAD \u8FDE\u63A5\u4FE1\u606F", mimeType: "application/json", subscribable: true },
953
- { uri: "atlisp://dwg/layers", name: "Layers", description: "\u56FE\u5C42\u5217\u8868", mimeType: "application/json", subscribable: true },
954
859
  { uri: "atlisp://dwg/entities", name: "Entities", description: "\u56FE\u5143\u5217\u8868\u3002\u65E0\u53C2\u6570\u65F6\u8FD4\u56DE\u603B\u6570\u548C\u6309\u7C7B\u578B\u7EDF\u8BA1\uFF1B\u6709\u53C2\u6570\u65F6\u8FD4\u56DE filtered \u56FE\u6587\u7684 entity:properties \u5168\u5C5E\u6027 JSON\uFF08ObjectName, Handle, Layer, Color, Center, Radius \u7B49\uFF09\uFF0C\u652F\u6301 ?type=LINE&layer=0&bbox=0,0,100,100", mimeType: "application/json", subscribable: true },
955
- { uri: "atlisp://dwg/texts", name: "Texts", description: "\u6587\u672C\u5B9E\u4F53 key:value \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 },
860
+ { uri: "atlisp://dwg/text-content", name: "Text Content", description: "\u6587\u672C\u5185\u5BB9\u53CA\u4F4D\u7F6E\uFF0C\u7528\u4E8E\u8BED\u4E49\u5206\u6790\u3002\u652F\u6301 ?layer=0&bbox=0,0,100,100&limit=5000&offset=0", mimeType: "application/json", subscribable: true },
956
861
  { uri: "atlisp://dwg/name", name: "DWG Name", description: "\u5F53\u524D DWG \u6587\u4EF6\u540D", mimeType: "application/json", subscribable: true },
957
862
  { uri: "atlisp://dwg/path", name: "DWG Path", description: "\u6587\u4EF6\u5B8C\u6574\u8DEF\u5F84", mimeType: "application/json", subscribable: true },
863
+ { uri: "atlisp://dwg/block-refs", name: "Block References", description: "\u5757\u53C2\u7167\u5217\u8868\u53CA\u5C5E\u6027\u503C\u3001\u52A8\u6001\u5757\u7279\u6027\uFF0C\u652F\u6301 ?blockName=xxx", mimeType: "application/json", subscribable: true },
864
+ { uri: "atlisp://dwg/tbl", name: "Tables", description: "CAD \u8868\u6570\u636E (layer, block, textstyle, dimstyle, linetype, ucs, view, viewport, regapp)\uFF0C\u652F\u6301 ?tbl=layer", mimeType: "application/json", subscribable: true },
958
865
  { uri: "atlisp://cad/dwgs", name: "DWG List", description: "\u6240\u6709\u6253\u5F00\u7684 DWG \u6587\u4EF6\u5217\u8868", mimeType: "application/json", subscribable: true },
959
866
  { uri: "atlisp://packages", name: "Packages", description: "\u5DF2\u5B89\u88C5\u5305\u5217\u8868", mimeType: "application/json", subscribable: true },
960
867
  { uri: "atlisp://platforms", name: "Platforms", description: "\u652F\u6301\u7684\u5E73\u53F0\u4FE1\u606F", mimeType: "application/json", subscribable: false },
@@ -963,23 +870,20 @@ var RESOURCES = [
963
870
  ];
964
871
  function parseQuery(uri) {
965
872
  const qIdx = uri.indexOf("?");
966
- if (qIdx === -1)
967
- return { base: uri, params: {} };
873
+ if (qIdx === -1) return { base: uri, params: {} };
968
874
  const base = uri.substring(0, qIdx);
969
875
  const params = {};
970
876
  uri.substring(qIdx + 1).split("&").forEach((p) => {
971
877
  const eqIdx = p.indexOf("=");
972
878
  const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
973
879
  const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
974
- if (k)
975
- params[k] = decodeURIComponent(v);
880
+ if (k) params[k] = decodeURIComponent(v);
976
881
  });
977
882
  return { base, params };
978
883
  }
979
884
  function parseTemplateUri(uri) {
980
885
  const match = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
981
- if (match)
982
- return { type: "entity", handle: match[1] };
886
+ if (match) return { type: "entity", handle: match[1] };
983
887
  return null;
984
888
  }
985
889
  async function listResources(subscribedUris = []) {
@@ -1000,16 +904,18 @@ async function readResource(uri) {
1000
904
  switch (base) {
1001
905
  case "atlisp://cad/info":
1002
906
  return await getCadInfo();
1003
- case "atlisp://dwg/layers":
1004
- return await getLayers(params.name);
1005
907
  case "atlisp://dwg/entities":
1006
908
  return await getEntities(params);
1007
- case "atlisp://dwg/texts":
1008
- return await getTexts(params);
909
+ case "atlisp://dwg/text-content":
910
+ return await getTextContent(params);
1009
911
  case "atlisp://dwg/name":
1010
912
  return await getDwgName();
1011
913
  case "atlisp://dwg/path":
1012
914
  return await getDwgPath();
915
+ case "atlisp://dwg/block-refs":
916
+ return await getBlockRefs(params);
917
+ case "atlisp://dwg/tbl":
918
+ return await getTables(params);
1013
919
  case "atlisp://cad/dwgs":
1014
920
  return await getDwgList();
1015
921
  case "atlisp://packages":
@@ -1025,10 +931,8 @@ async function readResource(uri) {
1025
931
  }
1026
932
  }
1027
933
  async function getEntityByHandle(handle) {
1028
- if (!cad.connected)
1029
- await cad.connect();
1030
- if (!cad.connected)
1031
- return { error: "CAD \u672A\u8FDE\u63A5" };
934
+ if (!cad.connected) await cad.connect();
935
+ if (!cad.connected) return { error: "CAD \u672A\u8FDE\u63A5" };
1032
936
  const code = `(progn
1033
937
  (vl-load-com)
1034
938
  (if (setq ent (handent "${handle}"))
@@ -1048,8 +952,7 @@ async function getEntityByHandle(handle) {
1048
952
  )`;
1049
953
  try {
1050
954
  const result = await cad.sendCommandWithResult(code);
1051
- if (!result || result === "nil")
1052
- return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
955
+ if (!result || result === "nil") return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
1053
956
  try {
1054
957
  return JSON.parse(result);
1055
958
  } catch {
@@ -1061,8 +964,7 @@ async function getEntityByHandle(handle) {
1061
964
  }
1062
965
  async function getCadInfo() {
1063
966
  const cached = getCached("cad:info");
1064
- if (cached)
1065
- return cached;
967
+ if (cached) return cached;
1066
968
  if (!cad.connected) {
1067
969
  await cad.connect();
1068
970
  }
@@ -1086,65 +988,11 @@ async function getCadInfo() {
1086
988
  setCache("cad:info", result);
1087
989
  return result;
1088
990
  }
1089
- async function getLayers(filterName = null) {
1090
- const cacheKey = filterName ? `dwg:layers:${filterName}` : "dwg:layers:all";
1091
- const cached = getCached(cacheKey);
1092
- if (cached)
1093
- return cached;
1094
- if (!cad.connected)
1095
- await cad.connect();
1096
- if (!cad.connected)
1097
- return [];
1098
- try {
1099
- 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))`;
1100
- const result = await cad.sendCommandWithResult(code);
1101
- if (!result || result === "" || result === "nil") {
1102
- setCache(cacheKey, []);
1103
- return [];
1104
- }
1105
- let layers = [];
1106
- try {
1107
- layers = JSON.parse(result);
1108
- } catch (e) {
1109
- const parsed = parseLispList(result);
1110
- if (parsed) {
1111
- layers = parsed;
1112
- } else {
1113
- layers = [];
1114
- }
1115
- }
1116
- if (!Array.isArray(layers)) {
1117
- if (typeof layers === "number") {
1118
- layers = [[result, layers, 0]];
1119
- } else if (typeof layers === "string") {
1120
- layers = [[layers, 7, 0]];
1121
- }
1122
- }
1123
- const mapped = layers.map((l) => {
1124
- const name = Array.isArray(l) ? l[0] : l;
1125
- const color = Array.isArray(l) && l[1] !== void 0 ? l[1] : 7;
1126
- const flags = Array.isArray(l) && l[2] !== void 0 ? l[2] : 0;
1127
- return {
1128
- name: String(name),
1129
- color,
1130
- locked: (flags & 4) !== 0,
1131
- frozen: (flags & 1) !== 0
1132
- };
1133
- });
1134
- setCache(cacheKey, mapped);
1135
- return mapped;
1136
- } catch (e) {
1137
- setCache(cacheKey, []);
1138
- return [];
1139
- }
1140
- }
1141
991
  async function getEntities(params = {}) {
1142
992
  const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
1143
993
  const cached = getCached(cacheKey);
1144
- if (cached)
1145
- return cached;
1146
- if (!cad.connected)
1147
- await cad.connect();
994
+ if (cached) return cached;
995
+ if (!cad.connected) await cad.connect();
1148
996
  if (!cad.connected) {
1149
997
  const result = { total: 0, entities: [] };
1150
998
  setCache(cacheKey, result);
@@ -1243,27 +1091,48 @@ async function getEntitiesSummary(cacheKey) {
1243
1091
  return result;
1244
1092
  }
1245
1093
  }
1246
- async function getTexts(params = {}) {
1247
- const cacheKey = `dwg:texts:${JSON.stringify(params)}`;
1094
+ function buildTextContentCode({ layer, bbox, offset, limit }) {
1095
+ const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
1096
+ if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
1097
+ if (bbox) {
1098
+ const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
1099
+ if (parts.length === 4) {
1100
+ const [x1, y1, x2, y2] = parts;
1101
+ items.push(
1102
+ `'(-4 . "<AND")`,
1103
+ `'(-4 . ">=,>=,*") (list 10 ${x1} ${y1} 0.0)`,
1104
+ `'(-4 . "<=,<=,*") (list 10 ${x2} ${y2} 0.0)`,
1105
+ `'(-4 . "AND>")`
1106
+ );
1107
+ }
1108
+ }
1109
+ const filterExpr = `(list ${items.join(" ")})`;
1110
+ return `(progn
1111
+ (setq ss (ssget "_X" ${filterExpr}))
1112
+ (if (null ss)
1113
+ (list "total" 0 "offset" ${offset} "limit" ${limit} "texts" nil)
1114
+ (progn
1115
+ (setq total (sslength ss) i ${offset} texts nil)
1116
+ (while (and (< i total) (< (length texts) ${limit}))
1117
+ (setq ent (ssname ss i) ed (entget ent) ins (cdr (assoc 10 ed)))
1118
+ (setq texts (append texts (list (list "text" (vl-prin1-to-string (cdr (assoc 1 ed))) "position" (list (car ins) (cadr ins) (caddr ins))))) i (1+ i)))
1119
+ (list "total" total "offset" ${offset} "limit" ${limit} "texts" texts))))
1120
+ )`;
1121
+ }
1122
+ async function getTextContent(params = {}) {
1123
+ const cacheKey = `dwg:text-content:${JSON.stringify(params)}`;
1248
1124
  const cached = getCached(cacheKey);
1249
- if (cached)
1250
- return cached;
1251
- if (!cad.connected)
1252
- await cad.connect();
1125
+ if (cached) return cached;
1126
+ if (!cad.connected) await cad.connect();
1253
1127
  if (!cad.connected) {
1254
- const result = { total: 0, texts: [] };
1128
+ const result = { total: 0, offset: 0, limit: 5e3, texts: [] };
1255
1129
  setCache(cacheKey, result);
1256
1130
  return result;
1257
1131
  }
1258
1132
  const offset = Math.max(0, parseInt(params.offset) || 0);
1259
1133
  const limit = Math.min(Math.max(1, parseInt(params.limit) || 5e3), 5e3);
1260
1134
  try {
1261
- const code = buildTextCode({
1262
- layer: params.layer || null,
1263
- bbox: params.bbox || null,
1264
- offset,
1265
- limit
1266
- });
1135
+ const code = buildTextContentCode({ layer: params.layer, bbox: params.bbox, offset, limit });
1267
1136
  const resultStr = await cad.sendCommandWithResult(code);
1268
1137
  if (!resultStr || resultStr === "" || resultStr === "nil" || resultStr === "0") {
1269
1138
  const result = { total: 0, offset, limit, texts: [] };
@@ -1271,26 +1140,38 @@ async function getTexts(params = {}) {
1271
1140
  return result;
1272
1141
  }
1273
1142
  const parsed = parseLispRecursive(resultStr);
1274
- const textsIdx = parsed.indexOf("texts");
1275
- const rawTexts = textsIdx !== -1 && Array.isArray(parsed[textsIdx + 1]) ? parsed[textsIdx + 1] : [];
1143
+ if (!parsed || !Array.isArray(parsed)) {
1144
+ const result = { total: 0, offset, limit, texts: [] };
1145
+ setCache(cacheKey, result);
1146
+ return result;
1147
+ }
1276
1148
  const data = lispPairsToObject(parsed);
1277
- data.texts = rawTexts.length > 0 ? rawTexts.map(propertyPairsToObject).filter(Boolean) : [];
1278
- data.offset = offset;
1279
- data.limit = limit;
1149
+ const rawTexts = Array.isArray(data.texts) ? data.texts : [];
1150
+ data.texts = rawTexts.map((item) => {
1151
+ if (!Array.isArray(item)) return null;
1152
+ const obj = {};
1153
+ item.forEach((pair) => {
1154
+ if (Array.isArray(pair) && pair.length >= 2) {
1155
+ if (pair[0] === "text") obj.text = String(pair[1] || "");
1156
+ else if (pair[0] === "position" && Array.isArray(pair[1])) {
1157
+ obj.position = pair[1].map((v) => typeof v === "number" ? v : 0);
1158
+ }
1159
+ }
1160
+ });
1161
+ return obj.text ? obj : null;
1162
+ }).filter(Boolean);
1280
1163
  setCache(cacheKey, data);
1281
1164
  return data;
1282
1165
  } catch (e) {
1283
- log(`getTexts error: ${e.message}`);
1166
+ log(`getTextContent error: ${e.message}`);
1284
1167
  const result = { total: 0, offset, limit, texts: [] };
1285
1168
  setCache(cacheKey, result);
1286
1169
  return result;
1287
1170
  }
1288
1171
  }
1289
1172
  async function getDwgName() {
1290
- if (!cad.connected)
1291
- await cad.connect();
1292
- if (!cad.connected)
1293
- return { name: null };
1173
+ if (!cad.connected) await cad.connect();
1174
+ if (!cad.connected) return { name: null };
1294
1175
  try {
1295
1176
  const code = `(vl-princ-to-string (getvar "dwgname"))`;
1296
1177
  const name = await cad.sendCommandWithResult(code);
@@ -1300,10 +1181,8 @@ async function getDwgName() {
1300
1181
  }
1301
1182
  }
1302
1183
  async function getDwgPath() {
1303
- if (!cad.connected)
1304
- await cad.connect();
1305
- if (!cad.connected)
1306
- return { path: null, name: null };
1184
+ if (!cad.connected) await cad.connect();
1185
+ if (!cad.connected) return { path: null, name: null };
1307
1186
  try {
1308
1187
  const code = `(progn
1309
1188
  (setq prefix (vl-princ-to-string (getvar "dwgprefix")))
@@ -1321,8 +1200,7 @@ async function getDwgPath() {
1321
1200
  }
1322
1201
  if (!parsed) {
1323
1202
  const listResult = parseLispList(result);
1324
- if (listResult && listResult.length >= 2)
1325
- parsed = listResult;
1203
+ if (listResult && listResult.length >= 2) parsed = listResult;
1326
1204
  }
1327
1205
  if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
1328
1206
  return { path: String(parsed[0]), name: String(parsed[1]) };
@@ -1332,15 +1210,257 @@ async function getDwgPath() {
1332
1210
  return { path: null, name: null };
1333
1211
  }
1334
1212
  }
1213
+ function buildBlockRefsCode(filterBlockName) {
1214
+ const filterExpr = filterBlockName ? `(list (cons 2 "${filterBlockName.replace(/"/g, '\\"')}"))` : "nil";
1215
+ return `(progn
1216
+ (vl-load-com)
1217
+ (defun @br:attr (ent / atts)
1218
+ (if (= (type ent) 'VLA-OBJECT)
1219
+ (progn
1220
+ (setq atts (vlax-variant-value (vla-getattributes ent)))
1221
+ (if (safearray-value atts)
1222
+ (mapcar '(lambda (x) (cons (vla-get-tagstring x) (vla-get-textstring x)))
1223
+ (vlax-safearray->list atts))
1224
+ nil))
1225
+ (if (setq att (entnext ent))
1226
+ (progn
1227
+ (setq atts nil)
1228
+ (while (= (cdr (assoc 0 (entget att))) "ATTRIB")
1229
+ (setq atts (cons (cons (cdr (assoc 2 (entget att))) (cdr (assoc 1 (entget att)))) atts))
1230
+ att (entnext att))
1231
+ (reverse atts))
1232
+ nil))))
1233
+
1234
+ (defun @br:dynprops (ent / obj props)
1235
+ (if (= (type ent) 'VLA-OBJECT)
1236
+ (progn
1237
+ (setq obj ent)
1238
+ (if (vlax-property-available-p obj 'isdynamicblock)
1239
+ (if (vla-get-isdynamicblock obj)
1240
+ (progn
1241
+ (setq props (vlax-invoke obj 'getdynamicblockproperties))
1242
+ (mapcar '(lambda (x)
1243
+ (cons (vla-get-propertyname x)
1244
+ (list (cons "value" (vla-get-value x))
1245
+ (cons "readOnly" (vla-get-readonly x))
1246
+ (cons "show" (vla-get-show x)))))
1247
+ (vlax-safearray->list props)))
1248
+ nil)
1249
+ nil))
1250
+ (if (and (setq obj (vlax-ename->vla-object ent))
1251
+ (vlax-property-available-p obj 'isdynamicblock)
1252
+ (vla-get-isdynamicblock obj))
1253
+ (progn
1254
+ (setq props (vlax-invoke obj 'getdynamicblockproperties))
1255
+ (mapcar '(lambda (x)
1256
+ (cons (vla-get-propertyname x)
1257
+ (list (cons "value" (vla-get-value x))
1258
+ (cons "readOnly" (vla-get-readonly x))
1259
+ (cons "show" (vla-get-show x)))))
1260
+ (vlax-safearray->list props)))
1261
+ nil)))
1262
+
1263
+ (defun @br:props (ent / obj blkname result)
1264
+ (setq obj (vlax-ename->vla-object ent))
1265
+ (setq result (list
1266
+ (cons "handle" (cdr (assoc 5 (entget ent))))
1267
+ (cons "layer" (cdr (assoc 8 (entget ent))))
1268
+ (cons "blockName" (vla-get-name obj))
1269
+ (cons "effectiveBlockName" (vla-get-effectivename obj))
1270
+ (cons "insertionPoint" (vlax-safearray->list (vla-get-insertionpoint obj)))
1271
+ (cons "rotation" (vla-get-rotation obj))
1272
+ (cons "scale" (list (vla-get-xscale obj) (vla-get-yscale obj) (vla-get-zscale obj)))
1273
+ (cons "isDynamic" (if (vlax-property-available-p obj 'isdynamicblock) (vla-get-isdynamicblock obj) nil))
1274
+ (cons "attributes" (@br:attr obj))
1275
+ (cons "dynamicProperties" (@br:dynprops obj))))
1276
+ result)
1277
+
1278
+ (setq ss (ssget "_X" (list (cons 0 "INSERT") ${filterExpr})))
1279
+ (if (null ss)
1280
+ (list (cons "total" 0) (cons "blockRefs" nil))
1281
+ (progn
1282
+ (setq total (sslength ss) i 0 refs nil)
1283
+ (while (< i total)
1284
+ (setq refs (cons (@br:props (ssname ss i)) refs) i (1+ i)))
1285
+ (list (cons "total" total) (cons "blockRefs" (reverse refs))))))`;
1286
+ }
1287
+ async function getBlockRefs(params = {}) {
1288
+ const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
1289
+ const cached = getCached(cacheKey);
1290
+ if (cached) return cached;
1291
+ if (!cad.connected) await cad.connect();
1292
+ if (!cad.connected) {
1293
+ const result = { total: 0, blockRefs: [] };
1294
+ setCache(cacheKey, result);
1295
+ return result;
1296
+ }
1297
+ try {
1298
+ const code = buildBlockRefsCode(params.blockName);
1299
+ const resultStr = await cad.sendCommandWithResult(code);
1300
+ if (!resultStr || resultStr === "" || resultStr === "nil") {
1301
+ const result2 = { total: 0, blockRefs: [] };
1302
+ setCache(cacheKey, result2);
1303
+ return result2;
1304
+ }
1305
+ const parsed = parseLispRecursive(resultStr);
1306
+ if (!parsed || !Array.isArray(parsed)) {
1307
+ const result2 = { total: 0, blockRefs: [] };
1308
+ setCache(cacheKey, result2);
1309
+ return result2;
1310
+ }
1311
+ const result = lispPairsToObject(parsed);
1312
+ const blockRefs = Array.isArray(result.blockRefs) ? result.blockRefs : [];
1313
+ const finalResult = {
1314
+ total: typeof result.total === "number" ? result.total : blockRefs.length,
1315
+ blockRefs: blockRefs.map((br) => {
1316
+ const obj = {};
1317
+ if (Array.isArray(br)) {
1318
+ br.forEach((pair) => {
1319
+ if (Array.isArray(pair) && pair.length >= 2) {
1320
+ const key = pair[0];
1321
+ let val = pair[1];
1322
+ if (key === "insertionPoint" && Array.isArray(val)) {
1323
+ val = val.map((v) => typeof v === "number" ? v : 0);
1324
+ } else if (key === "scale" && Array.isArray(val)) {
1325
+ val = val.map((v) => typeof v === "number" ? v : 1);
1326
+ } else if (key === "isDynamic") {
1327
+ val = val === true || val === "true" || val === 1;
1328
+ }
1329
+ obj[key] = val;
1330
+ }
1331
+ });
1332
+ }
1333
+ return obj;
1334
+ })
1335
+ };
1336
+ setCache(cacheKey, finalResult);
1337
+ return finalResult;
1338
+ } catch (e) {
1339
+ log(`getBlockRefs error: ${e.message}`);
1340
+ const result = { total: 0, blockRefs: [] };
1341
+ setCache(cacheKey, result);
1342
+ return result;
1343
+ }
1344
+ }
1345
+ var TBL_INFO = {
1346
+ layer: { name: "\u56FE\u5C42", fields: ["name", "color", "linetype", "frozen", "locked", "on"] },
1347
+ block: { name: "\u5757\u5B9A\u4E49", fields: ["name", "path", "flags"] },
1348
+ textstyle: { name: "\u6587\u5B57\u6837\u5F0F", fields: ["name", "font", "height", "width", "oblique"] },
1349
+ dimstyle: { name: "\u6807\u6CE8\u6837\u5F0F", fields: ["name", "arrow", "textheight", "scale"] },
1350
+ linetype: { name: "\u7EBF\u578B", fields: ["name", "description", "pattern"] },
1351
+ ucs: { name: "UCS", fields: ["name", "origin", "xaxis", "yaxis"] },
1352
+ view: { name: "\u89C6\u56FE", fields: ["name", "center", "height", "width"] },
1353
+ viewport: { name: "\u89C6\u53E3", fields: ["name", "number", "flags"] },
1354
+ regapp: { name: "\u6CE8\u518C\u5E94\u7528", fields: ["name"] },
1355
+ viewport: { name: "\u89C6\u53E3\u914D\u7F6E", fields: ["name", "number"] },
1356
+ plotstyle: { name: "\u6253\u5370\u6837\u5F0F", fields: ["name"] }
1357
+ };
1358
+ function buildTablesCode(tblName) {
1359
+ const validTbls = Object.keys(TBL_INFO).join('","');
1360
+ return `(progn
1361
+ (vl-load-com)
1362
+ (defun @tbl:get (tbl / res)
1363
+ (setq res nil)
1364
+ (while (setq rec (tblnext tbl (null res)))
1365
+ (setq res (cons (list (cdr (assoc 2 rec)) rec) res)))
1366
+ (reverse res))
1367
+ (defun @tbl:get-all nil
1368
+ (list
1369
+ (cons "layer" (@tbl:get "LAYER"))
1370
+ (cons "block" (@tbl:get "BLOCK"))
1371
+ (cons "textstyle" (@tbl:get "STYLE"))
1372
+ (cons "dimstyle" (@tbl:get "DIMSTYLE"))
1373
+ (cons "linetype" (@tbl:get "LTYPE"))
1374
+ (cons "ucs" (@tbl:get "UCS"))
1375
+ (cons "view" (@tbl:get "VIEW"))
1376
+ (cons "regapp" (@tbl:get "REGAPP"))
1377
+ ))
1378
+ (if (member (strcase "${tblName}") (list "${validTbls}"))
1379
+ (list (cons "table" (strcase "${tblName}")) (cons "data" (@tbl:get (strcase "${tblName}"))))
1380
+ (@tbl:get-all)))
1381
+ `;
1382
+ }
1383
+ function parseTableRecord(rec) {
1384
+ if (!Array.isArray(rec) || rec.length < 2) return null;
1385
+ const name = rec[0];
1386
+ const data = rec[1];
1387
+ if (!Array.isArray(data)) return { name };
1388
+ const obj = { name: String(name) };
1389
+ data.forEach((pair) => {
1390
+ if (Array.isArray(pair) && pair.length >= 2) {
1391
+ const key = pair[0];
1392
+ let val = pair[1];
1393
+ if (key === 62) obj.color = typeof val === "number" ? val : 7;
1394
+ else if (key === 6) obj.linetype = String(val);
1395
+ else if (key === 70) obj.flags = typeof val === "number" ? val : 0;
1396
+ else if (key === 1) obj.font = String(val);
1397
+ else if (key === 40) obj.height = typeof val === "number" ? val : 0;
1398
+ else if (key === 41) obj.width = typeof val === "number" ? val : 1;
1399
+ else if (key === 42) obj.oblique = typeof val === "number" ? val : 0;
1400
+ else if (key === 3) obj.description = String(val);
1401
+ else if (key === 10 && Array.isArray(val)) obj.origin = val;
1402
+ else if (key === 11 && Array.isArray(val)) obj.xaxis = val;
1403
+ else if (key === 12 && Array.isArray(val)) obj.yaxis = val;
1404
+ }
1405
+ });
1406
+ return obj;
1407
+ }
1408
+ async function getTables(params = {}) {
1409
+ const tblName = params.tbl || "all";
1410
+ const cacheKey = `dwg:tbl:${tblName}`;
1411
+ const cached = getCached(cacheKey);
1412
+ if (cached) return cached;
1413
+ if (!cad.connected) await cad.connect();
1414
+ if (!cad.connected) return { table: tblName, data: [] };
1415
+ try {
1416
+ const code = buildTablesCode(tblName);
1417
+ const resultStr = await cad.sendCommandWithResult(code);
1418
+ if (!resultStr || resultStr === "" || resultStr === "nil") {
1419
+ const result2 = { table: tblName, data: [] };
1420
+ setCache(cacheKey, result2);
1421
+ return result2;
1422
+ }
1423
+ const parsed = parseLispRecursive(resultStr);
1424
+ if (!parsed || !Array.isArray(parsed)) {
1425
+ const result2 = { table: tblName, data: [] };
1426
+ setCache(cacheKey, result2);
1427
+ return result2;
1428
+ }
1429
+ const isSingleTable = parsed.length >= 2 && parsed[0] === "table";
1430
+ let result;
1431
+ if (isSingleTable) {
1432
+ const data = Array.isArray(parsed[1]) ? parsed[1] : [];
1433
+ const tblData = Array.isArray(parsed[2]) ? parsed[2] : [];
1434
+ result = {
1435
+ table: String(data),
1436
+ data: tblData.map(parseTableRecord).filter(Boolean)
1437
+ };
1438
+ } else {
1439
+ const allData = {};
1440
+ parsed.forEach((item) => {
1441
+ if (Array.isArray(item) && item.length >= 2) {
1442
+ const key = item[0];
1443
+ const vals = Array.isArray(item[1]) ? item[1] : [];
1444
+ allData[key] = vals.map(parseTableRecord).filter(Boolean);
1445
+ }
1446
+ });
1447
+ result = allData;
1448
+ }
1449
+ setCache(cacheKey, result);
1450
+ return result;
1451
+ } catch (e) {
1452
+ log(`getTables error: ${e.message}`);
1453
+ const result = { table: tblName, data: [] };
1454
+ setCache(cacheKey, result);
1455
+ return result;
1456
+ }
1457
+ }
1335
1458
  async function getPackages(filterName = null) {
1336
1459
  const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
1337
1460
  const cached = getCached(cacheKey);
1338
- if (cached)
1339
- return cached;
1340
- if (!cad.connected)
1341
- await cad.connect();
1342
- if (!cad.connected)
1343
- return [];
1461
+ if (cached) return cached;
1462
+ if (!cad.connected) await cad.connect();
1463
+ if (!cad.connected) return [];
1344
1464
  try {
1345
1465
  const code = `(mapcar 'cdr @::*local-pkgs*)`;
1346
1466
  const result = await cad.sendCommandWithResult(code);
@@ -1354,8 +1474,7 @@ async function getPackages(filterName = null) {
1354
1474
  } catch {
1355
1475
  raw = parseLispList(result) || [];
1356
1476
  }
1357
- if (!Array.isArray(raw))
1358
- raw = [];
1477
+ if (!Array.isArray(raw)) raw = [];
1359
1478
  const packages = raw.map((item) => {
1360
1479
  if (Array.isArray(item)) {
1361
1480
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
@@ -1364,20 +1483,13 @@ async function getPackages(filterName = null) {
1364
1483
  const [[key, val]] = Object.entries(entry);
1365
1484
  const k = String(key);
1366
1485
  const v = String(val);
1367
- if (k === ":NAME")
1368
- pkg.name = v;
1369
- else if (k === ":VERSION")
1370
- pkg.version = v;
1371
- else if (k === ":DESCRIPTION")
1372
- pkg.description = v;
1373
- else if (k === ":FULL-NAME")
1374
- pkg.fullName = v;
1375
- else if (k === ":AUTHOR")
1376
- pkg.author = v;
1377
- else if (k === ":CATEGORY")
1378
- pkg.category = v;
1379
- else if (k === ":URL")
1380
- pkg.url = v;
1486
+ if (k === ":NAME") pkg.name = v;
1487
+ else if (k === ":VERSION") pkg.version = v;
1488
+ else if (k === ":DESCRIPTION") pkg.description = v;
1489
+ else if (k === ":FULL-NAME") pkg.fullName = v;
1490
+ else if (k === ":AUTHOR") pkg.author = v;
1491
+ else if (k === ":CATEGORY") pkg.category = v;
1492
+ else if (k === ":URL") pkg.url = v;
1381
1493
  }
1382
1494
  }
1383
1495
  return pkg;
@@ -1388,22 +1500,15 @@ async function getPackages(filterName = null) {
1388
1500
  if (item && typeof item === "object") {
1389
1501
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
1390
1502
  const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
1391
- if (nameVal)
1392
- pkg.name = String(nameVal);
1503
+ if (nameVal) pkg.name = String(nameVal);
1393
1504
  const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
1394
- if (verVal)
1395
- pkg.version = String(verVal);
1505
+ if (verVal) pkg.version = String(verVal);
1396
1506
  const descVal = item.description || item.Description || item.DESCRIPTION || item[":DESCRIPTION"];
1397
- if (descVal)
1398
- pkg.description = String(descVal);
1399
- if (item.fullName || item.full_name)
1400
- pkg.fullName = String(item.fullName || item.full_name);
1401
- if (item.author || item.Author)
1402
- pkg.author = String(item.author || item.Author);
1403
- if (item.category || item.Category)
1404
- pkg.category = String(item.category || item.Category);
1405
- if (item.url || item.Url || item.URL)
1406
- pkg.url = String(item.url || item.Url || item.URL);
1507
+ if (descVal) pkg.description = String(descVal);
1508
+ if (item.fullName || item.full_name) pkg.fullName = String(item.fullName || item.full_name);
1509
+ if (item.author || item.Author) pkg.author = String(item.author || item.Author);
1510
+ if (item.category || item.Category) pkg.category = String(item.category || item.Category);
1511
+ if (item.url || item.Url || item.URL) pkg.url = String(item.url || item.Url || item.URL);
1407
1512
  return pkg;
1408
1513
  }
1409
1514
  return null;
@@ -1429,12 +1534,9 @@ function getPlatforms() {
1429
1534
  async function getDwgList() {
1430
1535
  const cacheKey = "cad:dwgs";
1431
1536
  const cached = getCached(cacheKey);
1432
- if (cached)
1433
- return cached;
1434
- if (!cad.connected)
1435
- await cad.connect();
1436
- if (!cad.connected)
1437
- return [];
1537
+ if (cached) return cached;
1538
+ if (!cad.connected) await cad.connect();
1539
+ if (!cad.connected) return [];
1438
1540
  try {
1439
1541
  const code = `(progn
1440
1542
  (vl-load-com)
@@ -1458,8 +1560,7 @@ async function getDwgList() {
1458
1560
  parsed = listResult;
1459
1561
  }
1460
1562
  }
1461
- if (!Array.isArray(parsed))
1462
- parsed = [];
1563
+ if (!Array.isArray(parsed)) parsed = [];
1463
1564
  const dwgList = parsed.map((item) => {
1464
1565
  if (Array.isArray(item) && item.length >= 2) {
1465
1566
  return { name: String(item[0]), path: String(item[1]) };
@@ -1486,8 +1587,7 @@ function loadStandardsFile(filename) {
1486
1587
  var standardsCache = /* @__PURE__ */ new Map();
1487
1588
  function getCachedStandards(key) {
1488
1589
  const entry = standardsCache.get(key);
1489
- if (entry && Date.now() - entry.timestamp < 3e4)
1490
- return entry.data;
1590
+ if (entry && Date.now() - entry.timestamp < 3e4) return entry.data;
1491
1591
  standardsCache.delete(key);
1492
1592
  return null;
1493
1593
  }
@@ -1496,20 +1596,16 @@ function setCachedStandards(key, data) {
1496
1596
  }
1497
1597
  function getDraftingStandards() {
1498
1598
  const cached = getCachedStandards("drafting");
1499
- if (cached)
1500
- return cached;
1599
+ if (cached) return cached;
1501
1600
  const data = loadStandardsFile("drafting.json");
1502
- if (data)
1503
- setCachedStandards("drafting", data);
1601
+ if (data) setCachedStandards("drafting", data);
1504
1602
  return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
1505
1603
  }
1506
1604
  function getCodingStandards() {
1507
1605
  const cached = getCachedStandards("coding");
1508
- if (cached)
1509
- return cached;
1606
+ if (cached) return cached;
1510
1607
  const data = loadStandardsFile("coding.json");
1511
- if (data)
1512
- setCachedStandards("coding", data);
1608
+ if (data) setCachedStandards("coding", data);
1513
1609
  return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
1514
1610
  }
1515
1611
 
@@ -1724,11 +1820,9 @@ var SseSession = class {
1724
1820
  return lines.join("\n") + "\n\n";
1725
1821
  }
1726
1822
  _setupDrain() {
1727
- if (typeof this.#res.on !== "function")
1728
- return;
1823
+ if (typeof this.#res.on !== "function") return;
1729
1824
  this.#drainHandler = () => {
1730
- if (!this.#active)
1731
- return;
1825
+ if (!this.#active) return;
1732
1826
  if (this.#backpressureBuffer.length > 0) {
1733
1827
  this._drainBuffer();
1734
1828
  }
@@ -1750,8 +1844,7 @@ var SseSession = class {
1750
1844
  }
1751
1845
  }
1752
1846
  _write(content) {
1753
- if (!this.#active)
1754
- return false;
1847
+ if (!this.#active) return false;
1755
1848
  try {
1756
1849
  if (this.#backpressureBuffer.length > 0) {
1757
1850
  this.#backpressureBuffer.push(content);
@@ -1879,8 +1972,7 @@ function persistSessionData(clientId, sessionData) {
1879
1972
  function loadPersistedSessionData(clientId) {
1880
1973
  try {
1881
1974
  const filePath = getSessionStorePath(clientId);
1882
- if (!fs4.existsSync(filePath))
1883
- return null;
1975
+ if (!fs4.existsSync(filePath)) return null;
1884
1976
  const raw = fs4.readFileSync(filePath, "utf-8");
1885
1977
  const store = JSON.parse(raw);
1886
1978
  if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
@@ -2040,8 +2132,7 @@ var SessionTransport = class {
2040
2132
  this._started = true;
2041
2133
  }
2042
2134
  async send(message) {
2043
- if (this._closed)
2044
- return;
2135
+ if (this._closed) return;
2045
2136
  if (this._pendingRequest) {
2046
2137
  const { resolve, reject, timeout } = this._pendingRequest;
2047
2138
  clearTimeout(timeout);
@@ -2050,8 +2141,7 @@ var SessionTransport = class {
2050
2141
  }
2051
2142
  }
2052
2143
  async close() {
2053
- if (this._closed)
2054
- return;
2144
+ if (this._closed) return;
2055
2145
  this._closed = true;
2056
2146
  if (this._pendingRequest) {
2057
2147
  const { reject, timeout } = this._pendingRequest;
@@ -2363,14 +2453,10 @@ ${generateSuggestions(entities, layers)}`
2363
2453
  }
2364
2454
  function generateSuggestions(entities, layers) {
2365
2455
  const suggestions = [];
2366
- if (entities.total > 1e3)
2367
- suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
2368
- if (layers.length > 20)
2369
- suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
2370
- if (entities.byType.LINE && entities.byType.LINE > 500)
2371
- suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
2372
- if (!entities.byType.DIMENSION)
2373
- suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
2456
+ if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
2457
+ if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
2458
+ 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");
2459
+ if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
2374
2460
  return suggestions.length ? suggestions.join("\n") : "- \u56FE\u7EB8\u7ED3\u6784\u826F\u597D";
2375
2461
  }
2376
2462
  async function generateBatchLinesPrompt(args) {
@@ -2915,8 +3001,7 @@ var Metrics = class {
2915
3001
  bucket.sum += value;
2916
3002
  bucket.min = Math.min(bucket.min, value);
2917
3003
  bucket.max = Math.max(bucket.max, value);
2918
- if (!bucket.values)
2919
- bucket.values = [];
3004
+ if (!bucket.values) bucket.values = [];
2920
3005
  bucket.values.push(value);
2921
3006
  this.histograms.set(key, bucket);
2922
3007
  }
@@ -3007,33 +3092,33 @@ var RESOURCE_TEMPLATES = [
3007
3092
  mimeType: "application/json"
3008
3093
  },
3009
3094
  {
3010
- uriTemplate: "atlisp://dwg/entities",
3011
- name: "Entities Summary",
3012
- description: "\u8FD4\u56DE\u56FE\u5143\u603B\u6570\u548C\u6309\u7C7B\u578B\u7EDF\u8BA1\u5217\u8868",
3095
+ uriTemplate: "atlisp://dwg/entities?type={type}",
3096
+ name: "Entities by Type",
3097
+ description: "\u6309\u7C7B\u578B\u67E5\u8BE2\u5B9E\u4F53\u5217\u8868",
3013
3098
  mimeType: "application/json"
3014
3099
  },
3015
3100
  {
3016
- uriTemplate: "atlisp://dwg/entities?type={type}&layer={layer}&bbox={bbox}",
3017
- name: "Filtered Entities",
3018
- description: "\u6309 type/layer/bbox \u8FC7\u6EE4\u56FE\u5143\uFF0C\u8FD4\u56DE entity:properties \u5168\u5C5E\u6027 JSON\uFF08ObjectName, Handle, Layer, Color, Center, Radius \u7B49\uFF09",
3101
+ uriTemplate: "atlisp://packages?search={query}",
3102
+ name: "Package Search",
3103
+ description: "\u641C\u7D22 @lisp \u5305",
3019
3104
  mimeType: "application/json"
3020
3105
  },
3021
3106
  {
3022
- uriTemplate: "atlisp://dwg/layers?name={name}",
3023
- name: "Layer by Name",
3024
- description: "\u6309\u540D\u79F0\u67E5\u8BE2\u56FE\u5C42",
3107
+ uriTemplate: "atlisp://dwg/block-refs?blockName={blockName}",
3108
+ name: "Block References",
3109
+ description: "\u83B7\u53D6\u5757\u53C2\u7167\u5217\u8868\uFF0C\u652F\u6301\u6309\u5757\u540D\u8FC7\u6EE4",
3025
3110
  mimeType: "application/json"
3026
3111
  },
3027
3112
  {
3028
- uriTemplate: "atlisp://packages?search={query}",
3029
- name: "Package Search",
3030
- description: "\u641C\u7D22 @lisp \u5305",
3113
+ uriTemplate: "atlisp://dwg/tbl?tbl={tbl}",
3114
+ name: "CAD Tables",
3115
+ description: "\u83B7\u53D6 CAD \u8868\u6570\u636E (layer, block, textstyle, dimstyle, linetype, ucs, view, regapp)",
3031
3116
  mimeType: "application/json"
3032
3117
  },
3033
3118
  {
3034
- uriTemplate: "atlisp://dwg/texts?layer={layer}&offset={offset}&limit={limit}",
3035
- name: "Text Entities",
3036
- description: "\u5206\u9875\u83B7\u53D6\u6587\u672C\u5B9E\u4F53",
3119
+ uriTemplate: "atlisp://dwg/text-content?bbox={bbox}&layer={layer}&offset={offset}&limit={limit}",
3120
+ name: "Text Content",
3121
+ description: "\u6587\u672C\u5185\u5BB9\u53CA\u4F4D\u7F6E\uFF0C\u7528\u4E8E\u8BED\u4E49\u5206\u6790",
3037
3122
  mimeType: "application/json"
3038
3123
  }
3039
3124
  ];
@@ -3155,8 +3240,7 @@ async function evalLisp(code, withResult = false, encoding = null) {
3155
3240
  return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3156
3241
  }
3157
3242
  const trimmed = (code || "").trim();
3158
- if (!trimmed)
3159
- return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3243
+ if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3160
3244
  try {
3161
3245
  if (withResult) {
3162
3246
  const result = await cad.sendCommandWithResult(trimmed, encoding);
@@ -3176,17 +3260,14 @@ async function getCadInfo2() {
3176
3260
  if (!cad.connected) {
3177
3261
  await cad.connect();
3178
3262
  }
3179
- if (!cad.connected)
3180
- return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3263
+ if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3181
3264
  const info = await cad.getInfo();
3182
3265
  return { content: [{ type: "text", text: info }] };
3183
3266
  }
3184
3267
  async function atCommand(command) {
3185
- if (!cad.connected)
3186
- return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3268
+ if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3187
3269
  const trimmed = (command || "").trim();
3188
- if (!trimmed)
3189
- return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3270
+ if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3190
3271
  await cad.sendCommand(trimmed + "\n");
3191
3272
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
3192
3273
  }
@@ -3194,8 +3275,7 @@ async function newDocument() {
3194
3275
  if (!cad.connected) {
3195
3276
  await cad.connect();
3196
3277
  }
3197
- if (!cad.connected)
3198
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3278
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3199
3279
  const result = await cad.newDoc();
3200
3280
  if (result) {
3201
3281
  return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
@@ -3206,8 +3286,7 @@ async function bringToFront() {
3206
3286
  if (!cad.connected) {
3207
3287
  await cad.connect();
3208
3288
  }
3209
- if (!cad.connected)
3210
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3289
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3211
3290
  const result = await cad.bringToFront();
3212
3291
  if (result) {
3213
3292
  return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
@@ -3218,8 +3297,7 @@ async function installAtlisp() {
3218
3297
  if (!cad.connected) {
3219
3298
  await cad.connect();
3220
3299
  }
3221
- if (!cad.connected)
3222
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3300
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3223
3301
  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))))`;
3224
3302
  await cad.sendCommand(installCode + "\n");
3225
3303
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
@@ -3228,12 +3306,10 @@ async function listFunctionsInCad() {
3228
3306
  if (!cad.connected) {
3229
3307
  await cad.connect();
3230
3308
  }
3231
- if (!cad.connected)
3232
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3309
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3233
3310
  try {
3234
3311
  const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
3235
- if (result)
3236
- return { content: [{ type: "text", text: result }] };
3312
+ if (result) return { content: [{ type: "text", text: result }] };
3237
3313
  return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
3238
3314
  } catch (e) {
3239
3315
  return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
@@ -3288,8 +3364,7 @@ async function initAtlisp() {
3288
3364
  if (!cad.connected) {
3289
3365
  await cad.connect();
3290
3366
  }
3291
- if (!cad.connected)
3292
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3367
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3293
3368
  const code = `(if (null @::load-module)
3294
3369
  (progn
3295
3370
  (vl-load-com)
@@ -3329,15 +3404,12 @@ async function fetchPackages() {
3329
3404
  return cachedPackages || MOCK_PACKAGES;
3330
3405
  }
3331
3406
  function flattenPackages(data) {
3332
- if (Array.isArray(data))
3333
- return data;
3334
- if (data && Array.isArray(data.packages))
3335
- return data.packages;
3407
+ if (Array.isArray(data)) return data;
3408
+ if (data && Array.isArray(data.packages)) return data.packages;
3336
3409
  return [];
3337
3410
  }
3338
3411
  async function listPackages() {
3339
- if (!cad.connected)
3340
- await cad.connect();
3412
+ if (!cad.connected) await cad.connect();
3341
3413
  if (!cad.connected) {
3342
3414
  const data2 = await fetchPackages();
3343
3415
  const items2 = flattenPackages(data2);
@@ -3345,8 +3417,7 @@ async function listPackages() {
3345
3417
  return { content: [{ type: "text", text: text2 }] };
3346
3418
  }
3347
3419
  const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
3348
- if (result && result !== "nil")
3349
- return { content: [{ type: "text", text: result }] };
3420
+ if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
3350
3421
  const data = await fetchPackages();
3351
3422
  const items = flattenPackages(data);
3352
3423
  const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
@@ -3366,12 +3437,10 @@ async function searchPackages(query) {
3366
3437
  for (const p of items) {
3367
3438
  const name = (p.name || "").toLowerCase();
3368
3439
  const desc = (p.description || "").toLowerCase();
3369
- if (name.includes(q) || desc.includes(q))
3370
- results.push(p);
3440
+ if (name.includes(q) || desc.includes(q)) results.push(p);
3371
3441
  }
3372
3442
  } else {
3373
- for (const p of items)
3374
- results.push(p);
3443
+ for (const p of items) results.push(p);
3375
3444
  }
3376
3445
  if (results.length === 0) {
3377
3446
  return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
@@ -3423,8 +3492,7 @@ function writeCacheToDisk(data) {
3423
3492
  }
3424
3493
  async function fetchFunctions() {
3425
3494
  const diskCache = readCacheFromDisk();
3426
- if (diskCache)
3427
- return diskCache;
3495
+ if (diskCache) return diskCache;
3428
3496
  try {
3429
3497
  const response = await fetch(FUNCTIONS_URL, { headers: { "User-Agent": "atlisp-mcp" } });
3430
3498
  if (response.ok) {
@@ -3444,8 +3512,7 @@ async function getFunctionUsage(funcName, packageName) {
3444
3512
  if (data) {
3445
3513
  const funcs = Object.values(data.all_functions || {});
3446
3514
  const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
3447
- if (func)
3448
- results.push(func);
3515
+ if (func) results.push(func);
3449
3516
  }
3450
3517
  if (results.length === 0 && FUNCTIONS_DIR) {
3451
3518
  try {
@@ -3454,8 +3521,7 @@ async function getFunctionUsage(funcName, packageName) {
3454
3521
  const raw = fs6.readFileSync(path8.join(FUNCTIONS_DIR, file), "utf-8");
3455
3522
  const data2 = JSON.parse(raw);
3456
3523
  const func = data2.functions?.find((f2) => f2.name === funcName);
3457
- if (func)
3458
- results.push(func);
3524
+ if (func) results.push(func);
3459
3525
  }
3460
3526
  } catch {
3461
3527
  }
@@ -3523,8 +3589,7 @@ async function getEntity(handle) {
3523
3589
  if (!cad.connected) {
3524
3590
  await cad.connect();
3525
3591
  }
3526
- if (!cad.connected)
3527
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3592
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3528
3593
  const code = `(progn
3529
3594
  (vl-load-com)
3530
3595
  (if (setq ent (handent "${handle}"))
@@ -3556,8 +3621,7 @@ async function setEntityProperty(handle, property, value) {
3556
3621
  if (!cad.connected) {
3557
3622
  await cad.connect();
3558
3623
  }
3559
- if (!cad.connected)
3560
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3624
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3561
3625
  let propCode = "";
3562
3626
  switch (property) {
3563
3627
  case "layer":
@@ -3600,8 +3664,7 @@ async function deleteEntity(handle) {
3600
3664
  if (!cad.connected) {
3601
3665
  await cad.connect();
3602
3666
  }
3603
- if (!cad.connected)
3604
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3667
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3605
3668
  const code = `(progn
3606
3669
  (vl-load-com)
3607
3670
  (if (setq ent (handent "${handle}"))
@@ -3626,15 +3689,12 @@ async function selectEntities(filter) {
3626
3689
  if (!cad.connected) {
3627
3690
  await cad.connect();
3628
3691
  }
3629
- if (!cad.connected)
3630
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3692
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3631
3693
  let filterCode = "nil";
3632
3694
  if (filter && (filter.type || filter.layer)) {
3633
3695
  const items = [];
3634
- if (filter.type)
3635
- items.push(`'(0 . "${filter.type}")`);
3636
- if (filter.layer)
3637
- items.push(`'(8 . "${filter.layer}")`);
3696
+ if (filter.type) items.push(`'(0 . "${filter.type}")`);
3697
+ if (filter.layer) items.push(`'(8 . "${filter.layer}")`);
3638
3698
  filterCode = `(list ${items.join(" ")})`;
3639
3699
  }
3640
3700
  const code = `(progn
@@ -3666,8 +3726,7 @@ async function createLayer(name, color = 7, linetype = "Continuous") {
3666
3726
  if (!cad.connected) {
3667
3727
  await cad.connect();
3668
3728
  }
3669
- if (!cad.connected)
3670
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3729
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3671
3730
  const code = `(progn
3672
3731
  (vl-load-com)
3673
3732
  (if (not (tblsearch "LAYER" "${name}"))
@@ -3703,8 +3762,7 @@ async function deleteLayer(name) {
3703
3762
  if (!cad.connected) {
3704
3763
  await cad.connect();
3705
3764
  }
3706
- if (!cad.connected)
3707
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3765
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3708
3766
  const code = `(progn
3709
3767
  (vl-load-com)
3710
3768
  (cond
@@ -3738,8 +3796,7 @@ async function setLayerProperty(name, property, value) {
3738
3796
  if (!cad.connected) {
3739
3797
  await cad.connect();
3740
3798
  }
3741
- if (!cad.connected)
3742
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3799
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3743
3800
  let propCode = "";
3744
3801
  switch (property) {
3745
3802
  case "color":
@@ -3787,8 +3844,7 @@ async function setCurrentLayer(name) {
3787
3844
  if (!cad.connected) {
3788
3845
  await cad.connect();
3789
3846
  }
3790
- if (!cad.connected)
3791
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3847
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3792
3848
  const code = `(progn
3793
3849
  (vl-load-com)
3794
3850
  (if (tblsearch "LAYER" "${name}")
@@ -3815,8 +3871,7 @@ async function createBlock(name, entities) {
3815
3871
  if (!cad.connected) {
3816
3872
  await cad.connect();
3817
3873
  }
3818
- if (!cad.connected)
3819
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3874
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3820
3875
  const code = `(progn
3821
3876
  (vl-load-com)
3822
3877
  (if (not (tblsearch "BLOCK" "${name}"))
@@ -3853,8 +3908,7 @@ async function insertBlock(blockName, point, scale = 1, rotation = 0) {
3853
3908
  if (!cad.connected) {
3854
3909
  await cad.connect();
3855
3910
  }
3856
- if (!cad.connected)
3857
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3911
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3858
3912
  const coords = Array.isArray(point) ? point : point.split(",").map((s) => parseFloat(s.trim()));
3859
3913
  if (coords.length < 2) {
3860
3914
  return { content: [{ type: "text", text: "\u63D2\u5165\u70B9\u683C\u5F0F\u9519\u8BEF\uFF0C\u9700\u8981 x,y \u6216 [x,y,z]" }], isError: true };
@@ -3884,8 +3938,7 @@ async function getBlocks() {
3884
3938
  if (!cad.connected) {
3885
3939
  await cad.connect();
3886
3940
  }
3887
- if (!cad.connected)
3888
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3941
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3889
3942
  const code = `(progn
3890
3943
  (vl-load-com)
3891
3944
  (setq blocks nil)
@@ -3908,8 +3961,7 @@ async function explodeBlock(handle) {
3908
3961
  if (!cad.connected) {
3909
3962
  await cad.connect();
3910
3963
  }
3911
- if (!cad.connected)
3912
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3964
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3913
3965
  const code = `(progn
3914
3966
  (vl-load-com)
3915
3967
  (if (setq ent (handent "${handle}"))
@@ -3936,8 +3988,7 @@ async function openDwg(filePath) {
3936
3988
  if (!cad.connected) {
3937
3989
  await cad.connect();
3938
3990
  }
3939
- if (!cad.connected)
3940
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3991
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3941
3992
  const normalizedPath = filePath.replace(/\\/g, "\\\\");
3942
3993
  const code = `(progn
3943
3994
  (vl-load-com)
@@ -3974,8 +4025,7 @@ async function saveDwg(filePath = null) {
3974
4025
  if (!cad.connected) {
3975
4026
  await cad.connect();
3976
4027
  }
3977
- if (!cad.connected)
3978
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4028
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3979
4029
  const code = filePath ? `(progn
3980
4030
  (vl-load-com)
3981
4031
  (command "._SAVEAS" "${filePath.replace(/\\/g, "\\\\")}")
@@ -3999,8 +4049,7 @@ async function exportPdf(outputPath, layout = "Model") {
3999
4049
  if (!cad.connected) {
4000
4050
  await cad.connect();
4001
4051
  }
4002
- if (!cad.connected)
4003
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4052
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4004
4053
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4005
4054
  const code = `(progn
4006
4055
  (vl-load-com)
@@ -4028,8 +4077,7 @@ async function closeDwg(save = false) {
4028
4077
  if (!cad.connected) {
4029
4078
  await cad.connect();
4030
4079
  }
4031
- if (!cad.connected)
4032
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4080
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4033
4081
  const code = `(progn
4034
4082
  (vl-load-com)
4035
4083
  (if ${save ? "T" : "nil"}
@@ -4051,8 +4099,7 @@ async function createDimension(type, points, style = {}) {
4051
4099
  if (!cad.connected) {
4052
4100
  await cad.connect();
4053
4101
  }
4054
- if (!cad.connected)
4055
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4102
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4056
4103
  let dimCode = "";
4057
4104
  const validTypes = ["ALIGNED", "LINEAR", "ORDINATE", "RADIAL", "DIAMETER", "ANGULAR"];
4058
4105
  const dimType = (type || "ALIGNED").toUpperCase();
@@ -4094,8 +4141,7 @@ async function getDimensionValue(handle) {
4094
4141
  if (!cad.connected) {
4095
4142
  await cad.connect();
4096
4143
  }
4097
- if (!cad.connected)
4098
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4144
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4099
4145
  const code = `(progn
4100
4146
  (vl-load-com)
4101
4147
  (if (setq ent (handent "${handle}"))
@@ -4126,8 +4172,7 @@ async function createHatch(patternName, boundary, scale = 1, angle = 0) {
4126
4172
  if (!cad.connected) {
4127
4173
  await cad.connect();
4128
4174
  }
4129
- if (!cad.connected)
4130
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4175
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4131
4176
  const code = `(progn
4132
4177
  (vl-load-com)
4133
4178
  (command "._BHATCH" "p" "${patternName}" "s" "s" "sc" ${scale} "an" ${angle} "")
@@ -4147,17 +4192,12 @@ async function setHatchProperties(handle, props) {
4147
4192
  if (!cad.connected) {
4148
4193
  await cad.connect();
4149
4194
  }
4150
- if (!cad.connected)
4151
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4195
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4152
4196
  let propCode = "";
4153
- if (props.pattern)
4154
- propCode += `(command "._HATCHEDIT" "${handle}" "p" "${props.pattern}")`;
4155
- if (props.scale)
4156
- propCode += `(command "._HATCHEDIT" "${handle}" "s" ${props.scale})`;
4157
- if (props.angle)
4158
- propCode += `(command "._HATCHEDIT" "${handle}" "an" ${props.angle})`;
4159
- if (props.color)
4160
- propCode += `(command "._HATCHEDIT" "${handle}" "c" ${props.color})`;
4197
+ if (props.pattern) propCode += `(command "._HATCHEDIT" "${handle}" "p" "${props.pattern}")`;
4198
+ if (props.scale) propCode += `(command "._HATCHEDIT" "${handle}" "s" ${props.scale})`;
4199
+ if (props.angle) propCode += `(command "._HATCHEDIT" "${handle}" "an" ${props.angle})`;
4200
+ if (props.color) propCode += `(command "._HATCHEDIT" "${handle}" "c" ${props.color})`;
4161
4201
  const code = `(progn
4162
4202
  (vl-load-com)
4163
4203
  ${propCode}
@@ -4174,8 +4214,7 @@ async function getBlockAttributes(blockHandle) {
4174
4214
  if (!cad.connected) {
4175
4215
  await cad.connect();
4176
4216
  }
4177
- if (!cad.connected)
4178
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4217
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4179
4218
  const code = `(progn
4180
4219
  (vl-load-com)
4181
4220
  (if (setq ent (handent "${blockHandle}"))
@@ -4204,8 +4243,7 @@ async function setBlockAttribute(blockHandle, tag, value) {
4204
4243
  if (!cad.connected) {
4205
4244
  await cad.connect();
4206
4245
  }
4207
- if (!cad.connected)
4208
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4246
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4209
4247
  const code = `(progn
4210
4248
  (vl-load-com)
4211
4249
  (if (setq ent (handent "${blockHandle}"))
@@ -4241,8 +4279,7 @@ async function zoomToExtents() {
4241
4279
  if (!cad.connected) {
4242
4280
  await cad.connect();
4243
4281
  }
4244
- if (!cad.connected)
4245
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4282
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4246
4283
  const code = `(progn
4247
4284
  (vl-load-com)
4248
4285
  (command "._ZOOM" "E")
@@ -4259,8 +4296,7 @@ async function zoomToWindow(p1, p2) {
4259
4296
  if (!cad.connected) {
4260
4297
  await cad.connect();
4261
4298
  }
4262
- if (!cad.connected)
4263
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4299
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4264
4300
  const code = `(command "._ZOOM" "W" (list ${p1}) (list ${p2}))`;
4265
4301
  try {
4266
4302
  await cad.sendCommand(code + "\n");
@@ -4273,8 +4309,7 @@ async function createNamedView(viewName, center = null) {
4273
4309
  if (!cad.connected) {
4274
4310
  await cad.connect();
4275
4311
  }
4276
- if (!cad.connected)
4277
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4312
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4278
4313
  const code = center ? `(command ".-VIEW" "S" "${viewName}" "C" (list ${center}))` : `(command ".-VIEW" "S" "${viewName}")`;
4279
4314
  try {
4280
4315
  await cad.sendCommand(code + "\n");
@@ -4287,8 +4322,7 @@ async function restoreNamedView(viewName) {
4287
4322
  if (!cad.connected) {
4288
4323
  await cad.connect();
4289
4324
  }
4290
- if (!cad.connected)
4291
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4325
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4292
4326
  const code = `(command ".-VIEW" "R" "${viewName}")`;
4293
4327
  try {
4294
4328
  await cad.sendCommand(code + "\n");
@@ -4301,8 +4335,7 @@ async function listNamedViews() {
4301
4335
  if (!cad.connected) {
4302
4336
  await cad.connect();
4303
4337
  }
4304
- if (!cad.connected)
4305
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4338
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4306
4339
  const code = `(progn
4307
4340
  (vl-load-com)
4308
4341
  (setq views nil)
@@ -4322,8 +4355,7 @@ async function exportDxf(outputPath, version2 = "R2018") {
4322
4355
  if (!cad.connected) {
4323
4356
  await cad.connect();
4324
4357
  }
4325
- if (!cad.connected)
4326
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4358
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4327
4359
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4328
4360
  const versionMap = {
4329
4361
  "R2018": "AC1027",
@@ -4354,8 +4386,7 @@ async function exportDwf(outputPath) {
4354
4386
  if (!cad.connected) {
4355
4387
  await cad.connect();
4356
4388
  }
4357
- if (!cad.connected)
4358
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4389
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4359
4390
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4360
4391
  const code = `(progn
4361
4392
  (vl-load-com)
@@ -4376,8 +4407,7 @@ async function batchSetLayer(handles, layerName) {
4376
4407
  if (!cad.connected) {
4377
4408
  await cad.connect();
4378
4409
  }
4379
- if (!cad.connected)
4380
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4410
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4381
4411
  if (!Array.isArray(handles) || handles.length === 0) {
4382
4412
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
4383
4413
  }
@@ -4402,8 +4432,7 @@ async function createUcs(name, origin = "0,0,0", xAxis = "1,0,0", yAxis = "0,1,0
4402
4432
  if (!cad.connected) {
4403
4433
  await cad.connect();
4404
4434
  }
4405
- if (!cad.connected)
4406
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4435
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4407
4436
  const code = `(progn
4408
4437
  (vl-load-com)
4409
4438
  (if (not (tblsearch "UCS" "${name}"))
@@ -4434,8 +4463,7 @@ async function setUcs(name) {
4434
4463
  if (!cad.connected) {
4435
4464
  await cad.connect();
4436
4465
  }
4437
- if (!cad.connected)
4438
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4466
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4439
4467
  const code = `(progn
4440
4468
  (vl-load-com)
4441
4469
  (if (tblsearch "UCS" "${name}")
@@ -4460,8 +4488,7 @@ async function listUcs() {
4460
4488
  if (!cad.connected) {
4461
4489
  await cad.connect();
4462
4490
  }
4463
- if (!cad.connected)
4464
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4491
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4465
4492
  const code = `(progn
4466
4493
  (vl-load-com)
4467
4494
  (setq ucsList nil)
@@ -4484,8 +4511,7 @@ async function deleteUcs(name) {
4484
4511
  if (!cad.connected) {
4485
4512
  await cad.connect();
4486
4513
  }
4487
- if (!cad.connected)
4488
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4514
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4489
4515
  const code = `(progn
4490
4516
  (vl-load-com)
4491
4517
  (if (tblsearch "UCS" "${name}")
@@ -4510,8 +4536,7 @@ async function getCurrentUcs() {
4510
4536
  if (!cad.connected) {
4511
4537
  await cad.connect();
4512
4538
  }
4513
- if (!cad.connected)
4514
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4539
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4515
4540
  const code = `(progn
4516
4541
  (vl-load-com)
4517
4542
  (vla-get-activeutilities (vla-get-document (vla-get-application (vlax-get-acad-object))))
@@ -4528,8 +4553,7 @@ async function createLayout(name) {
4528
4553
  if (!cad.connected) {
4529
4554
  await cad.connect();
4530
4555
  }
4531
- if (!cad.connected)
4532
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4556
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4533
4557
  const code = `(progn
4534
4558
  (vl-load-com)
4535
4559
  (if (not (tblsearch "LAYOUT" "${name}"))
@@ -4557,8 +4581,7 @@ async function setLayout(name) {
4557
4581
  if (!cad.connected) {
4558
4582
  await cad.connect();
4559
4583
  }
4560
- if (!cad.connected)
4561
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4584
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4562
4585
  const code = `(progn
4563
4586
  (vl-load-com)
4564
4587
  (vlax-for layout (vla-get-layouts (vla-get-activedocument (vla-get-application (vlax-get-acad-object))))
@@ -4588,8 +4611,7 @@ async function listLayouts() {
4588
4611
  if (!cad.connected) {
4589
4612
  await cad.connect();
4590
4613
  }
4591
- if (!cad.connected)
4592
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4614
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4593
4615
  const code = `(progn
4594
4616
  (vl-load-com)
4595
4617
  (setq layouts nil)
@@ -4612,8 +4634,7 @@ async function deleteLayout(name) {
4612
4634
  if (!cad.connected) {
4613
4635
  await cad.connect();
4614
4636
  }
4615
- if (!cad.connected)
4616
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4637
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4617
4638
  if (name === "Model" || name === "\u6A21\u578B") {
4618
4639
  return { content: [{ type: "text", text: "\u65E0\u6CD5\u5220\u9664\u6A21\u578B\u7A7A\u95F4" }], isError: true };
4619
4640
  }
@@ -4641,8 +4662,7 @@ async function getCurrentLayout() {
4641
4662
  if (!cad.connected) {
4642
4663
  await cad.connect();
4643
4664
  }
4644
- if (!cad.connected)
4645
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4665
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4646
4666
  const code = `(vl-prin1-to-string (getvar "CTAB"))`;
4647
4667
  try {
4648
4668
  const result = await cad.sendCommandWithResult(code);
@@ -4655,8 +4675,7 @@ async function renameLayout(oldName, newName) {
4655
4675
  if (!cad.connected) {
4656
4676
  await cad.connect();
4657
4677
  }
4658
- if (!cad.connected)
4659
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4678
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4660
4679
  const code = `(progn
4661
4680
  (vl-load-com)
4662
4681
  (if (tblsearch "LAYOUT" "${oldName}")
@@ -4683,8 +4702,7 @@ async function plotToPdf(outputPath, layout = "Model", style = {}) {
4683
4702
  if (!cad.connected) {
4684
4703
  await cad.connect();
4685
4704
  }
4686
- if (!cad.connected)
4687
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4705
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4688
4706
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4689
4707
  const paperSize = style.paperSize || "A4";
4690
4708
  const plotScale = style.plotScale || "1:1";
@@ -4717,8 +4735,7 @@ async function plotToPrinter(printerName, layout = "Model") {
4717
4735
  if (!cad.connected) {
4718
4736
  await cad.connect();
4719
4737
  }
4720
- if (!cad.connected)
4721
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4738
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4722
4739
  const code = `(progn
4723
4740
  (vl-load-com)
4724
4741
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
@@ -4744,8 +4761,7 @@ async function createGroup(name, handles) {
4744
4761
  if (!cad.connected) {
4745
4762
  await cad.connect();
4746
4763
  }
4747
- if (!cad.connected)
4748
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4764
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4749
4765
  if (!Array.isArray(handles) || handles.length === 0) {
4750
4766
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
4751
4767
  }
@@ -4771,8 +4787,7 @@ async function deleteGroup(name) {
4771
4787
  if (!cad.connected) {
4772
4788
  await cad.connect();
4773
4789
  }
4774
- if (!cad.connected)
4775
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4790
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4776
4791
  const code = `(progn
4777
4792
  (vl-load-com)
4778
4793
  (if (tblsearch "GROUP" "${name}")
@@ -4797,8 +4812,7 @@ async function listGroups() {
4797
4812
  if (!cad.connected) {
4798
4813
  await cad.connect();
4799
4814
  }
4800
- if (!cad.connected)
4801
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4815
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4802
4816
  const code = `(progn
4803
4817
  (vl-load-com)
4804
4818
  (setq groups nil)
@@ -4818,8 +4832,7 @@ async function getGroupEntities(groupName) {
4818
4832
  if (!cad.connected) {
4819
4833
  await cad.connect();
4820
4834
  }
4821
- if (!cad.connected)
4822
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4835
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4823
4836
  const code = `(progn
4824
4837
  (vl-load-com)
4825
4838
  (if (tblsearch "GROUP" "${groupName}")
@@ -4857,8 +4870,7 @@ async function measureDistance(p1, p2) {
4857
4870
  if (!cad.connected) {
4858
4871
  await cad.connect();
4859
4872
  }
4860
- if (!cad.connected)
4861
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4873
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4862
4874
  const code = `(progn
4863
4875
  (vl-load-com)
4864
4876
  (setq pt1 (list ${p1}) pt2 (list ${p2}))
@@ -4882,8 +4894,7 @@ async function measureArea(points) {
4882
4894
  if (!cad.connected) {
4883
4895
  await cad.connect();
4884
4896
  }
4885
- if (!cad.connected)
4886
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4897
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4887
4898
  const pts = Array.isArray(points) ? points : points.split(/[\s,]+/).filter(Boolean);
4888
4899
  if (pts.length < 3) {
4889
4900
  return { content: [{ type: "text", text: "\u81F3\u5C11\u9700\u8981 3 \u4E2A\u70B9" }], isError: true };
@@ -4920,8 +4931,7 @@ async function getEntityInfo(handle) {
4920
4931
  if (!cad.connected) {
4921
4932
  await cad.connect();
4922
4933
  }
4923
- if (!cad.connected)
4924
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4934
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4925
4935
  const code = `(progn
4926
4936
  (vl-load-com)
4927
4937
  (if (setq ent (handent "${handle}"))
@@ -4956,8 +4966,7 @@ async function ensureConnected() {
4956
4966
  if (!cad.connected) {
4957
4967
  await cad.connect();
4958
4968
  }
4959
- if (!cad.connected)
4960
- throw new Error("CAD \u672A\u8FDE\u63A5");
4969
+ if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
4961
4970
  }
4962
4971
  function parseHandleList(handles) {
4963
4972
  if (typeof handles === "string") {
@@ -5198,8 +5207,7 @@ async function ensureConnected2() {
5198
5207
  if (!cad.connected) {
5199
5208
  await cad.connect();
5200
5209
  }
5201
- if (!cad.connected)
5202
- throw new Error("CAD \u672A\u8FDE\u63A5");
5210
+ if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5203
5211
  }
5204
5212
  async function getXdata(handle, appName = "ACAD") {
5205
5213
  await ensureConnected2();
@@ -5405,11 +5413,10 @@ async function searchByXdata(appName, key, value) {
5405
5413
  async function exportXdataToFile(handle, filePath) {
5406
5414
  await ensureConnected2();
5407
5415
  const xdata = await getAllEntityXdata(handle);
5408
- if (!xdata.success)
5409
- return xdata;
5416
+ if (!xdata.success) return xdata;
5410
5417
  try {
5411
- const fs9 = await import("fs");
5412
- fs9.writeFileSync(filePath, JSON.stringify(xdata.xdata, null, 2));
5418
+ const fs8 = await import("fs");
5419
+ fs8.writeFileSync(filePath, JSON.stringify(xdata.xdata, null, 2));
5413
5420
  return { handle, filePath, success: true };
5414
5421
  } catch (e) {
5415
5422
  return { error: e.message, success: false };
@@ -5418,8 +5425,8 @@ async function exportXdataToFile(handle, filePath) {
5418
5425
  async function importXdataFromFile(handle, filePath, appName) {
5419
5426
  await ensureConnected2();
5420
5427
  try {
5421
- const fs9 = await import("fs");
5422
- const data = fs9.readFileSync(filePath, "utf8");
5428
+ const fs8 = await import("fs");
5429
+ const data = fs8.readFileSync(filePath, "utf8");
5423
5430
  const xdata = JSON.parse(data);
5424
5431
  if (appName && xdata[appName]) {
5425
5432
  return await setXdata(handle, appName, xdata[appName]);
@@ -5439,8 +5446,7 @@ async function ensureConnected3() {
5439
5446
  if (!cad.connected) {
5440
5447
  await cad.connect();
5441
5448
  }
5442
- if (!cad.connected)
5443
- throw new Error("CAD \u672A\u8FDE\u63A5");
5449
+ if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5444
5450
  }
5445
5451
  async function createSheetSet(name, description = "") {
5446
5452
  await ensureConnected3();
@@ -5641,14 +5647,11 @@ async function ensureConnected4() {
5641
5647
  if (!cad.connected) {
5642
5648
  await cad.connect();
5643
5649
  }
5644
- if (!cad.connected)
5645
- throw new Error("CAD \u672A\u8FDE\u63A5");
5650
+ if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5646
5651
  }
5647
5652
  function parsePoint(point) {
5648
- if (Array.isArray(point))
5649
- return point.join(" ");
5650
- if (typeof point === "string")
5651
- return point;
5653
+ if (Array.isArray(point)) return point.join(" ");
5654
+ if (typeof point === "string") return point;
5652
5655
  return "0,0,0";
5653
5656
  }
5654
5657
  async function createBox(center, length, width, height) {
@@ -5908,8 +5911,7 @@ async function ensureConnected5() {
5908
5911
  if (!cad.connected) {
5909
5912
  await cad.connect();
5910
5913
  }
5911
- if (!cad.connected)
5912
- throw new Error("CAD \u672A\u8FDE\u63A5");
5914
+ if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5913
5915
  }
5914
5916
  async function createDimensionStyle(name, color = "bylayer", arrow = "ClosedFilled", textStyle = "") {
5915
5917
  await ensureConnected5();
@@ -6135,8 +6137,7 @@ async function ensureConnected6() {
6135
6137
  if (!cad.connected) {
6136
6138
  await cad.connect();
6137
6139
  }
6138
- if (!cad.connected)
6139
- throw new Error("CAD \u672A\u8FDE\u63A5");
6140
+ if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
6140
6141
  }
6141
6142
  async function attachPdf(point, pdfPath, scale = 1, rotation = 0) {
6142
6143
  await ensureConnected6();
@@ -6576,8 +6577,7 @@ function validateToolArgs(name, args) {
6576
6577
  const baseType = type.replace("?", "");
6577
6578
  const val = args[key];
6578
6579
  if (val === void 0 || val === null) {
6579
- if (isOptional)
6580
- continue;
6580
+ if (isOptional) continue;
6581
6581
  throw new Error(`Missing required argument: ${key}`);
6582
6582
  }
6583
6583
  const actualType = typeof args[key];
@@ -6622,8 +6622,7 @@ ${CAD_PLATFORMS.join("\n")}
6622
6622
  },
6623
6623
  import_funlib: async (a) => {
6624
6624
  const data = await loadAtlibFunctionLib();
6625
- if (!data)
6626
- return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
6625
+ if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
6627
6626
  if (a.format === "list") {
6628
6627
  const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
6629
6628
  return { content: [{ type: "text", text: items.join("\n") }] };
@@ -8377,25 +8376,27 @@ var tools = [
8377
8376
  ];
8378
8377
  function notifyResourceChanges(toolName) {
8379
8378
  const resourceMap = {
8380
- connect_cad: ["atlisp://cad/info", "atlisp://dwg/layers", "atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://packages"],
8381
- new_document: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/layers", "atlisp://dwg/entities", "atlisp://dwg/texts"],
8379
+ connect_cad: ["atlisp://cad/info", "atlisp://dwg/tbl", "atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://packages"],
8380
+ new_document: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/tbl", "atlisp://dwg/entities", "atlisp://dwg/text-content"],
8382
8381
  install_package: ["atlisp://packages"],
8383
8382
  install_atlisp: ["atlisp://packages", "atlisp://cad/info"],
8384
8383
  init_atlisp: ["atlisp://packages", "atlisp://cad/info"],
8385
- create_layer: ["atlisp://dwg/layers"],
8386
- delete_layer: ["atlisp://dwg/layers"],
8387
- set_layer: ["atlisp://dwg/layers"],
8388
- set_current_layer: ["atlisp://dwg/layers"],
8389
- create_block: ["atlisp://dwg/blocks"],
8390
- open_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/layers", "atlisp://dwg/entities"],
8384
+ create_layer: ["atlisp://dwg/tbl"],
8385
+ delete_layer: ["atlisp://dwg/tbl"],
8386
+ set_layer: ["atlisp://dwg/tbl"],
8387
+ set_current_layer: ["atlisp://dwg/tbl"],
8388
+ create_block: ["atlisp://dwg/block-refs", "atlisp://dwg/tbl"],
8389
+ open_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/tbl", "atlisp://dwg/entities", "atlisp://dwg/block-refs", "atlisp://dwg/text-content"],
8391
8390
  save_dwg: ["atlisp://dwg/name", "atlisp://dwg/path"],
8392
8391
  export_pdf: [],
8393
- close_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs"],
8394
- batch_delete: ["atlisp://dwg/entities"],
8395
- batch_explode: ["atlisp://dwg/entities"],
8392
+ close_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/block-refs", "atlisp://dwg/text-content"],
8393
+ delete_entity: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
8394
+ batch_delete: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
8395
+ batch_explode: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
8396
+ explode_block: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
8396
8397
  batch_set_color: ["atlisp://dwg/entities"],
8397
8398
  batch_set_linetype: ["atlisp://dwg/entities"],
8398
- batch_move: ["atlisp://dwg/entities", "atlisp://dwg/layers"],
8399
+ batch_move: ["atlisp://dwg/entities", "atlisp://dwg/tbl"],
8399
8400
  batch_rename: ["atlisp://dwg/entities"],
8400
8401
  batch_create_group: ["atlisp://dwg/groups"],
8401
8402
  batch_add_to_group: ["atlisp://dwg/groups"],
@@ -8421,10 +8422,10 @@ function notifyResourceChanges(toolName) {
8421
8422
  thicken_surface: ["atlisp://dwg/entities"],
8422
8423
  create_region: ["atlisp://dwg/entities"],
8423
8424
  create_loft_surface: ["atlisp://dwg/entities"],
8424
- create_dimension_style: [],
8425
- create_text_style: [],
8426
- create_linetype: [],
8427
- load_linetype: [],
8425
+ create_dimension_style: ["atlisp://dwg/tbl"],
8426
+ create_text_style: ["atlisp://dwg/tbl"],
8427
+ create_linetype: ["atlisp://dwg/tbl"],
8428
+ load_linetype: ["atlisp://dwg/tbl"],
8428
8429
  attach_pdf: ["atlisp://dwg/entities"],
8429
8430
  detach_pdf: ["atlisp://dwg/entities"],
8430
8431
  import_dxf: ["atlisp://dwg/entities"],
@@ -8446,8 +8447,7 @@ function notifyResourceChanges(toolName) {
8446
8447
  }
8447
8448
  async function handleToolCall(name, args) {
8448
8449
  const handler = TOOL_HANDLERS[name];
8449
- if (!handler)
8450
- return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8450
+ if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8451
8451
  try {
8452
8452
  validateToolArgs(name, args || {});
8453
8453
  const result = await handler(args || {});
@@ -8507,12 +8507,10 @@ var RateLimiter = class {
8507
8507
  this.keyLimits = /* @__PURE__ */ new Map();
8508
8508
  }
8509
8509
  getKeyLimit(apiKey2) {
8510
- if (!apiKey2)
8511
- return this.defaultLimit;
8510
+ if (!apiKey2) return this.defaultLimit;
8512
8511
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8513
8512
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8514
- if (found)
8515
- return found.limit;
8513
+ if (found) return found.limit;
8516
8514
  }
8517
8515
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8518
8516
  return config_default.apiKeyRateLimit || 1e3;
@@ -8520,12 +8518,10 @@ var RateLimiter = class {
8520
8518
  return this.defaultLimit;
8521
8519
  }
8522
8520
  getKeyInfo(apiKey2) {
8523
- if (!apiKey2)
8524
- return { name: "anonymous", limit: this.defaultLimit };
8521
+ if (!apiKey2) return { name: "anonymous", limit: this.defaultLimit };
8525
8522
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8526
8523
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8527
- if (found)
8528
- return { name: found.name || apiKey2, limit: found.limit };
8524
+ if (found) return { name: found.name || apiKey2, limit: found.limit };
8529
8525
  }
8530
8526
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8531
8527
  return { name: "admin", limit: config_default.apiKeyRateLimit || 1e3 };
@@ -8621,8 +8617,7 @@ var JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "applicati
8621
8617
  function createJsonBodyParser() {
8622
8618
  return async (req, res, next) => {
8623
8619
  const ct = (req.headers["content-type"] || "").toLowerCase();
8624
- if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
8625
- return next();
8620
+ if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
8626
8621
  try {
8627
8622
  const chunks = [];
8628
8623
  for await (const chunk of req) {
@@ -8655,11 +8650,9 @@ function createAuthMiddleware() {
8655
8650
  const PUBLIC_PATHS = ["/health"];
8656
8651
  return (req, res, next) => {
8657
8652
  if (apiKey) {
8658
- if (PUBLIC_PATHS.includes(req.path))
8659
- return next();
8653
+ if (PUBLIC_PATHS.includes(req.path)) return next();
8660
8654
  const auth = req.get("Authorization");
8661
- if (auth === `Bearer ${apiKey}`)
8662
- return next();
8655
+ if (auth === `Bearer ${apiKey}`) return next();
8663
8656
  return res.status(401).json({ error: "Unauthorized" });
8664
8657
  }
8665
8658
  next();
@@ -8667,16 +8660,14 @@ function createAuthMiddleware() {
8667
8660
  }
8668
8661
  function createCorsMiddleware() {
8669
8662
  return (req, res, next) => {
8670
- if (!enableCors)
8671
- return next();
8663
+ if (!enableCors) return next();
8672
8664
  res.setHeader("Access-Control-Allow-Origin", corsOrigin);
8673
8665
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, CONNECT");
8674
8666
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, mcp-session-id, last-event-id");
8675
8667
  res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
8676
8668
  res.setHeader("Access-Control-Max-Age", "86400");
8677
8669
  res.setHeader("Vary", "Accept");
8678
- if (req.method === "OPTIONS")
8679
- return res.status(204).end();
8670
+ if (req.method === "OPTIONS") return res.status(204).end();
8680
8671
  next();
8681
8672
  };
8682
8673
  }
@@ -9088,8 +9079,7 @@ For more info: https://atlisp.cn
9088
9079
  }
9089
9080
  }
9090
9081
  }
9091
- if (config_default.apiKey)
9092
- log("API Key authentication enabled");
9082
+ if (config_default.apiKey) log("API Key authentication enabled");
9093
9083
  async function initCadConnection() {
9094
9084
  log("Attempting to connect to CAD on startup...");
9095
9085
  try {