@atlisp/mcp 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/atlisp-mcp.js +375 -615
  2. package/package.json +1 -1
@@ -70,8 +70,7 @@ function parseArgs() {
70
70
  return result;
71
71
  }
72
72
  function loadConfigFile(filePath) {
73
- if (!filePath || !fs.existsSync(filePath))
74
- return null;
73
+ if (!filePath || !fs.existsSync(filePath)) return null;
75
74
  try {
76
75
  const raw = fs.readFileSync(filePath, "utf-8");
77
76
  const parsed = JSON.parse(raw);
@@ -227,8 +226,7 @@ function onDocumentChanged(callback) {
227
226
  _docChangeCallbacks.push(callback);
228
227
  }
229
228
  function emitDocumentChanged(info) {
230
- if (info.docName === _activeDocName)
231
- return;
229
+ if (info.docName === _activeDocName) return;
232
230
  _activeDocName = info.docName || "";
233
231
  for (const cb of _docChangeCallbacks) {
234
232
  try {
@@ -287,8 +285,7 @@ function setupStdoutHandler(w) {
287
285
  const lines = buffer.split("\n");
288
286
  buffer = lines.pop() || "";
289
287
  for (const line of lines) {
290
- if (!line.trim())
291
- continue;
288
+ if (!line.trim()) continue;
292
289
  try {
293
290
  const result = JSON.parse(line);
294
291
  const rid = result.requestId;
@@ -316,8 +313,7 @@ function setupStdoutHandler(w) {
316
313
  }
317
314
  function getWorker(force = false) {
318
315
  if (!worker || !worker.connected || force) {
319
- if (worker)
320
- worker.kill();
316
+ if (worker) worker.kill();
321
317
  worker = spawn("node", [workerPath], {
322
318
  stdio: ["pipe", "pipe", "pipe"]
323
319
  });
@@ -325,8 +321,7 @@ function getWorker(force = false) {
325
321
  const w = worker;
326
322
  w.on("exit", (code) => {
327
323
  console.error("worker exited with code:", code);
328
- if (w !== worker)
329
- return;
324
+ if (w !== worker) return;
330
325
  w.connected = false;
331
326
  for (const [id, { reject, timeout }] of pendingRequests) {
332
327
  clearTimeout(timeout);
@@ -347,8 +342,7 @@ function getWorker(force = false) {
347
342
  return worker;
348
343
  }
349
344
  function startHeartbeat() {
350
- if (heartbeatTimer)
351
- clearInterval(heartbeatTimer);
345
+ if (heartbeatTimer) clearInterval(heartbeatTimer);
352
346
  heartbeatTimer = setInterval(async () => {
353
347
  try {
354
348
  const result = await sendMessage({ type: "ping" });
@@ -449,16 +443,13 @@ var init_cad = __esm({
449
443
  return null;
450
444
  }
451
445
  async _process() {
452
- if (this.#processing)
453
- return;
446
+ if (this.#processing) return;
454
447
  this.#processing = true;
455
448
  while (this._hasPending()) {
456
449
  const cmd = this._dequeue();
457
- if (!cmd)
458
- continue;
450
+ if (!cmd) continue;
459
451
  const dedupKey = this._dedupKey(cmd);
460
- if (dedupKey)
461
- this.#dedupMap.delete(dedupKey);
452
+ if (dedupKey) this.#dedupMap.delete(dedupKey);
462
453
  try {
463
454
  const result = await sendMessage(cmd);
464
455
  cmd.resolve(result);
@@ -473,8 +464,7 @@ var init_cad = __esm({
473
464
  }
474
465
  _dequeue() {
475
466
  for (const q of this.#queues) {
476
- if (q.length > 0)
477
- return q.shift();
467
+ if (q.length > 0) return q.shift();
478
468
  }
479
469
  return null;
480
470
  }
@@ -502,8 +492,7 @@ var init_cad = __esm({
502
492
  return process.platform === "win32";
503
493
  }
504
494
  async connect(platform = null) {
505
- if (!this.isAvailable())
506
- return false;
495
+ if (!this.isAvailable()) return false;
507
496
  try {
508
497
  const msg = platform ? { type: "connect", platform } : { type: "connect" };
509
498
  const result = await sendMessage(msg);
@@ -527,8 +516,7 @@ var init_cad = __esm({
527
516
  return false;
528
517
  }
529
518
  async sendCommand(code) {
530
- if (!this.connected)
531
- throw new Error("\u672A\u8FDE\u63A5 CAD");
519
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
532
520
  return new Promise((resolve, reject) => {
533
521
  commandQueue.enqueue({
534
522
  type: "send",
@@ -538,14 +526,12 @@ var init_cad = __esm({
538
526
  reject
539
527
  }, PRIORITY_NORMAL);
540
528
  }).then((result) => {
541
- if (result.success)
542
- return true;
529
+ if (result.success) return true;
543
530
  throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
544
531
  });
545
532
  }
546
533
  async sendCommandWithResult(code, encoding = null) {
547
- if (!this.connected)
548
- throw new Error("\u672A\u8FDE\u63A5 CAD");
534
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
549
535
  return new Promise((resolve, reject) => {
550
536
  commandQueue.enqueue({
551
537
  type: "sendResult",
@@ -556,8 +542,7 @@ var init_cad = __esm({
556
542
  reject
557
543
  }, PRIORITY_NORMAL);
558
544
  }).then((result) => {
559
- if (result.success)
560
- return result.result || "";
545
+ if (result.success) return result.result || "";
561
546
  throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
562
547
  });
563
548
  }
@@ -568,8 +553,7 @@ var init_cad = __esm({
568
553
  return this.product;
569
554
  }
570
555
  async isBusy() {
571
- if (!this.connected)
572
- return false;
556
+ if (!this.connected) return false;
573
557
  try {
574
558
  const result = await sendMessage({ type: "isBusy", platform: _platform });
575
559
  return result && result.isBusy;
@@ -578,8 +562,7 @@ var init_cad = __esm({
578
562
  }
579
563
  }
580
564
  async hasDoc() {
581
- if (!this.connected)
582
- return { hasDoc: false, docCount: 0 };
565
+ if (!this.connected) return { hasDoc: false, docCount: 0 };
583
566
  try {
584
567
  const result = await sendMessage({ type: "hasdoc", platform: _platform });
585
568
  return result || { hasDoc: false, docCount: 0 };
@@ -588,8 +571,7 @@ var init_cad = __esm({
588
571
  }
589
572
  }
590
573
  async newDoc() {
591
- if (!this.connected)
592
- throw new Error("\u672A\u8FDE\u63A5 CAD");
574
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
593
575
  try {
594
576
  const result = await sendMessage({ type: "newdoc", platform: _platform });
595
577
  return result && result.success;
@@ -598,8 +580,7 @@ var init_cad = __esm({
598
580
  }
599
581
  }
600
582
  async bringToFront() {
601
- if (!this.connected)
602
- throw new Error("\u672A\u8FDE\u63A5 CAD");
583
+ if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
603
584
  try {
604
585
  const result = await sendMessage({ type: "bringToFront", platform: _platform });
605
586
  return result && result.success;
@@ -608,8 +589,7 @@ var init_cad = __esm({
608
589
  }
609
590
  }
610
591
  async getActiveDocInfo() {
611
- if (!this.connected)
612
- return { docName: "", docPath: "", docCount: 0 };
592
+ if (!this.connected) return { docName: "", docPath: "", docCount: 0 };
613
593
  try {
614
594
  const result = await sendMessage({ type: "getActiveDocInfo", platform: _platform });
615
595
  return result || { docName: "", docPath: "", docCount: 0 };
@@ -618,8 +598,7 @@ var init_cad = __esm({
618
598
  }
619
599
  }
620
600
  async getInfo() {
621
- if (!this.connected)
622
- return "CAD \u672A\u8FDE\u63A5";
601
+ if (!this.connected) return "CAD \u672A\u8FDE\u63A5";
623
602
  return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
624
603
  }
625
604
  async disconnect() {
@@ -664,16 +643,14 @@ __export(renderer_exports, {
664
643
  renderTemplate: () => renderTemplate
665
644
  });
666
645
  function escapeLispString2(str) {
667
- if (typeof str !== "string")
668
- return "";
646
+ if (typeof str !== "string") return "";
669
647
  return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
670
648
  }
671
649
  function resolvePath(obj, path12) {
672
650
  const parts = path12.split(/[.\[\]]/g).filter(Boolean);
673
651
  let val = obj;
674
652
  for (const p of parts) {
675
- if (val == null)
676
- return void 0;
653
+ if (val == null) return void 0;
677
654
  val = val[p];
678
655
  }
679
656
  return val;
@@ -682,11 +659,9 @@ function renderTemplate(template, args) {
682
659
  return template.replace(PARAM_RE, (match, rawExpr, expr) => {
683
660
  const path12 = rawExpr || expr;
684
661
  const val = resolvePath(args, path12);
685
- if (val == null)
686
- return "";
662
+ if (val == null) return "";
687
663
  const strVal = String(val);
688
- if (rawExpr)
689
- return strVal;
664
+ if (rawExpr) return strVal;
690
665
  return escapeLispString2(strVal);
691
666
  });
692
667
  }
@@ -745,9 +720,8 @@ import express2 from "express";
745
720
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
746
721
 
747
722
  // src/logger.js
748
- init_config();
749
723
  import fs2 from "fs";
750
- import fsp from "fs/promises";
724
+ init_config();
751
725
  import path3 from "path";
752
726
  import os2 from "os";
753
727
  var DEBUG_FILE = config_default.debugFile || path3.join(os2.tmpdir(), "mcp-server-debug.log");
@@ -756,11 +730,9 @@ var MAX_LOG_FILES = 5;
756
730
  var stream = null;
757
731
  function rotateLog() {
758
732
  try {
759
- if (!fs2.existsSync(DEBUG_FILE))
760
- return;
733
+ if (!fs2.existsSync(DEBUG_FILE)) return;
761
734
  const stat = fs2.statSync(DEBUG_FILE);
762
- if (stat.size < MAX_LOG_SIZE)
763
- return;
735
+ if (stat.size < MAX_LOG_SIZE) return;
764
736
  if (stream) {
765
737
  stream.end();
766
738
  stream = null;
@@ -834,11 +806,9 @@ function ensureRequestLogDir() {
834
806
  }
835
807
  function rotateRequestLog() {
836
808
  try {
837
- if (!fs2.existsSync(REQUEST_LOG_FILE))
838
- return;
809
+ if (!fs2.existsSync(REQUEST_LOG_FILE)) return;
839
810
  const stat = fs2.statSync(REQUEST_LOG_FILE);
840
- if (stat.size < 10 * 1024 * 1024)
841
- return;
811
+ if (stat.size < 10 * 1024 * 1024) return;
842
812
  if (requestStream) {
843
813
  requestStream.end();
844
814
  requestStream = null;
@@ -863,8 +833,7 @@ function rotateRequestLog() {
863
833
  }
864
834
  }
865
835
  function logRequest(req) {
866
- if (!config_default.requestLogEnabled)
867
- return;
836
+ if (!config_default.requestLogEnabled) return;
868
837
  try {
869
838
  ensureRequestLogDir();
870
839
  rotateRequestLog();
@@ -885,8 +854,7 @@ function logRequest(req) {
885
854
  }
886
855
  }
887
856
  function logResponse(req, res, duration) {
888
- if (!config_default.requestLogEnabled)
889
- return;
857
+ if (!config_default.requestLogEnabled) return;
890
858
  try {
891
859
  ensureRequestLogDir();
892
860
  if (!requestStream) {
@@ -942,36 +910,27 @@ var TBL_QUERIES = {
942
910
  (setq @d nil)
943
911
  (vlax-for e (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
944
912
  (if (not (and (vlax-property-available-p e 'isfoundation) (vlax-get e 'isfoundation)))
945
- (setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 (if (and (vlax-property-available-p e 'isxref) (vlax-get e 'isxref)) 1 0))) @d))))
913
+ (setq @d (cons (@:get-props e '("Name" "Count" "Handle" "ObjectName" "IsXRef" "IsXRefOverlay" "IsDynamicBlock" "HasAttributes" "HasExtensionDictionary" "Path" "Description" "Layout" "BlockScope")) @d))))
946
914
  (list (cons 'table 'block) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
947
915
  style: { name: "style", lisp: `(progn
948
916
  (setq @d nil)
949
917
  (vlax-for e (vla-get-textstyles (vla-get-activedocument (vlax-get-acad-object)))
950
- (setq @d (cons (list
951
- (cons 2 (vla-get-name e))
952
- (cons 1 (vla-get-fontfile e))
953
- (cons 3 (vla-get-bigfontfile e))
954
- (cons 40 (vla-get-height e))
955
- (cons 41 (vla-get-width e))
956
- (cons 42 (/ (* 180.0 (vla-get-obliqueangle e)) pi))
957
- (cons 70 (vla-get-textgenerationflag e))
958
- ) @d)))
918
+ (setq @d (cons (@:get-props e '("Name" "FontFile" "BigFontFile" "Height" "Width" "ObliqueAngle" "TextGenerationFlag" "Handle" "ObjectName")) @d)))
959
919
  (list (cons 'table 'style) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
960
920
  dimstyle: { name: "dimstyle", lisp: `(progn
961
921
  (setq @d nil)
962
922
  (vlax-for e (vla-get-dimstyles (vla-get-activedocument (vlax-get-acad-object)))
963
- (setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 0)) @d)))
923
+ (setq @d (cons (@:get-props e '("Name" "Handle" "ObjectName")) @d)))
964
924
  (list (cons 'table 'dimstyle) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
965
925
  ltype: { name: "linetype", lisp: `(progn
966
926
  (setq @d nil)
967
927
  (vlax-for e (vla-get-linetypes (vla-get-activedocument (vlax-get-acad-object)))
968
- (setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 0)) @d)))
928
+ (setq @d (cons (@:get-props e '("Name" "Description" "PatternLength" "Handle" "ObjectName")) @d)))
969
929
  (list (cons 'table 'linetype) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` }
970
930
  };
971
931
  var TBL_KEY_ALIAS = {
972
932
  textstyle: "style",
973
933
  textstyles: "style",
974
- ltype: "linetype",
975
934
  linetype: "ltype"
976
935
  };
977
936
 
@@ -1074,27 +1033,21 @@ async function ensureCadConnected() {
1074
1033
  }
1075
1034
  }
1076
1035
  function escapeLispString(str) {
1077
- if (typeof str !== "string")
1078
- return "";
1036
+ if (typeof str !== "string") return "";
1079
1037
  return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1080
1038
  }
1081
1039
  function tryNumber(val) {
1082
- if (typeof val === "number")
1083
- return val;
1040
+ if (typeof val === "number") return val;
1084
1041
  const n = Number(val);
1085
- if (!isNaN(n) && val !== "")
1086
- return n;
1042
+ if (!isNaN(n) && val !== "") return n;
1087
1043
  return val;
1088
1044
  }
1089
1045
  function parseLispList(str) {
1090
- if (!str || typeof str !== "string")
1091
- return null;
1046
+ if (!str || typeof str !== "string") return null;
1092
1047
  const trimmed = str.trim();
1093
- if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
1094
- return null;
1048
+ if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) return null;
1095
1049
  const content = trimmed.slice(1, -1).trim();
1096
- if (!content)
1097
- return [];
1050
+ if (!content) return [];
1098
1051
  const result = [];
1099
1052
  let depth = 0;
1100
1053
  let current = "";
@@ -1136,39 +1089,29 @@ function parseLispList(str) {
1136
1089
  }
1137
1090
  current += ch;
1138
1091
  }
1139
- if (current.trim())
1140
- result.push(current.trim());
1092
+ if (current.trim()) result.push(current.trim());
1141
1093
  return result.map((item) => {
1142
1094
  const t = item.trim();
1143
- if (t === "nil" || t === "NIL")
1144
- return null;
1145
- if (t === "t" || t === "T")
1146
- return true;
1147
- if (t.startsWith('"') && t.endsWith('"'))
1148
- return t.slice(1, -1);
1095
+ if (t === "nil" || t === "NIL") return null;
1096
+ if (t === "t" || t === "T") return true;
1097
+ if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
1149
1098
  return tryNumber(t);
1150
1099
  });
1151
1100
  }
1152
1101
  function parseLispRecursive(str) {
1153
- if (!str || typeof str !== "string")
1154
- return null;
1102
+ if (!str || typeof str !== "string") return null;
1155
1103
  str = str.trim();
1156
- if (!str)
1157
- return null;
1104
+ if (!str) return null;
1158
1105
  let pos = 0;
1159
1106
  function skipWs() {
1160
- while (pos < str.length && /\s/.test(str[pos]))
1161
- pos++;
1107
+ while (pos < str.length && /\s/.test(str[pos])) pos++;
1162
1108
  }
1163
1109
  function parseValue() {
1164
1110
  skipWs();
1165
- if (pos >= str.length)
1166
- return null;
1111
+ if (pos >= str.length) return null;
1167
1112
  const ch = str[pos];
1168
- if (ch === "(")
1169
- return parseList();
1170
- if (ch === '"')
1171
- return parseString();
1113
+ if (ch === "(") return parseList();
1114
+ if (ch === '"') return parseString();
1172
1115
  if (ch === "'") {
1173
1116
  pos++;
1174
1117
  return parseValue();
@@ -1181,16 +1124,11 @@ function parseLispRecursive(str) {
1181
1124
  while (pos < str.length && str[pos] !== '"') {
1182
1125
  if (str[pos] === "\\" && pos + 1 < str.length) {
1183
1126
  pos++;
1184
- if (str[pos] === '"')
1185
- r += '"';
1186
- else if (str[pos] === "n")
1187
- r += "\n";
1188
- else if (str[pos] === "t")
1189
- r += " ";
1190
- else if (str[pos] === "\\")
1191
- r += "\\";
1192
- else
1193
- r += str[pos];
1127
+ if (str[pos] === '"') r += '"';
1128
+ else if (str[pos] === "n") r += "\n";
1129
+ else if (str[pos] === "t") r += " ";
1130
+ else if (str[pos] === "\\") r += "\\";
1131
+ else r += str[pos];
1194
1132
  } else {
1195
1133
  r += str[pos];
1196
1134
  }
@@ -1201,13 +1139,10 @@ function parseLispRecursive(str) {
1201
1139
  }
1202
1140
  function parseAtom() {
1203
1141
  const start = pos;
1204
- while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
1205
- pos++;
1142
+ while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(") pos++;
1206
1143
  const atom = str.slice(start, pos);
1207
- if (atom === "nil" || atom === "NIL")
1208
- return null;
1209
- if (atom === "t" || atom === "T")
1210
- return true;
1144
+ if (atom === "nil" || atom === "NIL") return null;
1145
+ if (atom === "t" || atom === "T") return true;
1211
1146
  return tryNumber(atom);
1212
1147
  }
1213
1148
  function parseList() {
@@ -1215,15 +1150,13 @@ function parseLispRecursive(str) {
1215
1150
  const items = [];
1216
1151
  while (pos < str.length) {
1217
1152
  skipWs();
1218
- if (pos >= str.length)
1219
- break;
1153
+ if (pos >= str.length) break;
1220
1154
  if (str[pos] === ")") {
1221
1155
  pos++;
1222
1156
  return items;
1223
1157
  }
1224
1158
  const left = parseValue();
1225
- if (left === void 0)
1226
- break;
1159
+ if (left === void 0) break;
1227
1160
  skipWs();
1228
1161
  if (str[pos] === "." && (pos + 1 >= str.length || /\s/.test(str[pos + 1]) || str[pos + 1] === ")")) {
1229
1162
  pos++;
@@ -1245,19 +1178,6 @@ function parseLispRecursive(str) {
1245
1178
  }
1246
1179
  return parseValue();
1247
1180
  }
1248
- function lispPairsToObject(pairs) {
1249
- if (!Array.isArray(pairs))
1250
- return pairs;
1251
- const obj = {};
1252
- for (let i = 0; i < pairs.length - 1; i += 2) {
1253
- const key = pairs[i];
1254
- const val = pairs[i + 1];
1255
- if (typeof key === "string" || typeof key === "number") {
1256
- obj[String(key)] = Array.isArray(val) ? lispPairsToObject(val) : val;
1257
- }
1258
- }
1259
- return obj;
1260
- }
1261
1181
 
1262
1182
  // src/handlers/resource-readers.js
1263
1183
  var ENTITY_PROPERTIES_LISP = `
@@ -1313,8 +1233,7 @@ var ENTITY_PROPERTIES_LISP = `
1313
1233
  result)
1314
1234
  `;
1315
1235
  function propertyPairsToObject(pairs) {
1316
- if (!Array.isArray(pairs))
1317
- return null;
1236
+ if (!Array.isArray(pairs)) return null;
1318
1237
  const obj = {};
1319
1238
  for (const pair of pairs) {
1320
1239
  if (Array.isArray(pair) && pair.length >= 2) {
@@ -1325,10 +1244,8 @@ function propertyPairsToObject(pairs) {
1325
1244
  }
1326
1245
  function buildEntityPropertiesCode({ type, layer, bbox }) {
1327
1246
  const items = [];
1328
- if (type)
1329
- items.push(`(cons 0 "${escapeLispString(type)}")`);
1330
- if (layer)
1331
- items.push(`(cons 8 "${escapeLispString(layer)}")`);
1247
+ if (type) items.push(`(cons 0 "${escapeLispString(type)}")`);
1248
+ if (layer) items.push(`(cons 8 "${escapeLispString(layer)}")`);
1332
1249
  if (bbox) {
1333
1250
  const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
1334
1251
  if (parts.length === 4) {
@@ -1354,10 +1271,8 @@ ${ENTITY_PROPERTIES_LISP}
1354
1271
  (vl-prin1-to-string (list @e:total (reverse @e:ents))))`;
1355
1272
  }
1356
1273
  async function getEntityByHandle(handle) {
1357
- if (!cad.connected)
1358
- await cad.connect();
1359
- if (!cad.connected)
1360
- return { error: "CAD \u672A\u8FDE\u63A5" };
1274
+ if (!cad.connected) await cad.connect();
1275
+ if (!cad.connected) return { error: "CAD \u672A\u8FDE\u63A5" };
1361
1276
  const code = `(progn
1362
1277
  (vl-load-com)
1363
1278
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -1377,8 +1292,7 @@ async function getEntityByHandle(handle) {
1377
1292
  )`;
1378
1293
  try {
1379
1294
  const result = await cad.sendCommandWithResult(code);
1380
- if (!result || result === "nil")
1381
- return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
1295
+ if (!result || result === "nil") return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
1382
1296
  try {
1383
1297
  return JSON.parse(result);
1384
1298
  } catch {
@@ -1390,8 +1304,7 @@ async function getEntityByHandle(handle) {
1390
1304
  }
1391
1305
  async function getCadInfo() {
1392
1306
  const cached = getCached("cad:info");
1393
- if (cached)
1394
- return cached;
1307
+ if (cached) return cached;
1395
1308
  if (!cad.connected) {
1396
1309
  await cad.connect();
1397
1310
  }
@@ -1416,10 +1329,8 @@ async function getCadInfo() {
1416
1329
  async function getEntities(params = {}) {
1417
1330
  const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
1418
1331
  const cached = getCached(cacheKey);
1419
- if (cached)
1420
- return cached;
1421
- if (!cad.connected)
1422
- await cad.connect();
1332
+ if (cached) return cached;
1333
+ if (!cad.connected) await cad.connect();
1423
1334
  if (!cad.connected) {
1424
1335
  return { total: 0, entities: [] };
1425
1336
  }
@@ -1507,9 +1418,14 @@ async function getEntitiesSummary(cacheKey) {
1507
1418
  }
1508
1419
  }
1509
1420
  function buildTextContentCode({ layer, bbox, offset, limit }) {
1510
- const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
1511
- if (layer)
1512
- items.push(`(cons 8 "${escapeLispString(layer)}")`);
1421
+ const items = [
1422
+ `'(-4 . "<OR")`,
1423
+ `'(0 . "TEXT")`,
1424
+ `'(0 . "MTEXT")`,
1425
+ `'(0 . "ATTRIB")`,
1426
+ `'(-4 . "OR>")`
1427
+ ];
1428
+ if (layer) items.push(`(cons 8 "${escapeLispString(layer)}")`);
1513
1429
  if (bbox) {
1514
1430
  const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
1515
1431
  if (parts.length === 4) {
@@ -1524,6 +1440,7 @@ function buildTextContentCode({ layer, bbox, offset, limit }) {
1524
1440
  }
1525
1441
  const filterExpr = `(list ${items.join(" ")})`;
1526
1442
  return `(progn
1443
+ (vl-load-com)
1527
1444
  (setq ss (ssget "_X" ${filterExpr}))
1528
1445
  (if (null ss)
1529
1446
  (list "total" 0 "offset" ${offset} "limit" ${limit} "texts" nil)
@@ -1533,15 +1450,13 @@ function buildTextContentCode({ layer, bbox, offset, limit }) {
1533
1450
  (setq ent (ssname ss i) ed (entget ent) ins (cdr (assoc 10 ed)))
1534
1451
  (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)))
1535
1452
  (list "total" total "offset" ${offset} "limit" ${limit} "texts" texts))))
1536
- )`;
1453
+ `;
1537
1454
  }
1538
1455
  async function getTextContent(params = {}) {
1539
1456
  const cacheKey = `dwg:text-content:${JSON.stringify(params)}`;
1540
1457
  const cached = getCached(cacheKey);
1541
- if (cached)
1542
- return cached;
1543
- if (!cad.connected)
1544
- await cad.connect();
1458
+ if (cached) return cached;
1459
+ if (!cad.connected) await cad.connect();
1545
1460
  if (!cad.connected) {
1546
1461
  return { total: 0, offset: 0, limit: 5e3, texts: [] };
1547
1462
  }
@@ -1550,42 +1465,47 @@ async function getTextContent(params = {}) {
1550
1465
  try {
1551
1466
  const code = buildTextContentCode({ layer: params.layer, bbox: params.bbox, offset, limit });
1552
1467
  const resultStr = await cad.sendCommandWithResult(code);
1553
- if (!resultStr || resultStr === "" || resultStr === "nil" || resultStr === "0") {
1554
- return { total: 0, offset, limit, texts: [] };
1555
- }
1468
+ log(`[DEBUG text-content] resultStr length=${resultStr?.length} first300=${resultStr?.substring(0, 300)}`);
1556
1469
  const parsed = parseLispRecursive(resultStr);
1557
1470
  if (!parsed || !Array.isArray(parsed)) {
1558
- return { total: 0, offset, limit, texts: [] };
1471
+ throw new Error(`text-content: \u89E3\u6790 Lisp \u7ED3\u679C\u5931\u8D25: raw="${String(resultStr).substring(0, 500)}"`);
1472
+ }
1473
+ const data = {};
1474
+ let rawTexts = [];
1475
+ for (let i = 0; i < parsed.length - 1; i += 2) {
1476
+ const key = parsed[i];
1477
+ const val = parsed[i + 1];
1478
+ if (typeof key === "string" || typeof key === "number") {
1479
+ if (key === "texts" && Array.isArray(val)) {
1480
+ rawTexts = val;
1481
+ } else {
1482
+ data[String(key)] = val;
1483
+ }
1484
+ }
1559
1485
  }
1560
- const data = lispPairsToObject(parsed);
1561
- const rawTexts = Array.isArray(data.texts) ? data.texts : [];
1562
1486
  data.texts = rawTexts.map((item) => {
1563
- if (!Array.isArray(item))
1564
- return null;
1487
+ if (!Array.isArray(item)) return null;
1565
1488
  const obj = {};
1566
- item.forEach((pair) => {
1567
- if (Array.isArray(pair) && pair.length >= 2) {
1568
- if (pair[0] === "text")
1569
- obj.text = String(pair[1] || "");
1570
- else if (pair[0] === "position" && Array.isArray(pair[1])) {
1571
- obj.position = pair[1].map((v) => typeof v === "number" ? v : 0);
1572
- }
1489
+ for (let i = 0; i < item.length - 1; i += 2) {
1490
+ const key = item[i];
1491
+ const val = item[i + 1];
1492
+ if (key === "text") obj.text = String(val || "");
1493
+ else if (key === "position") {
1494
+ obj.position = Array.isArray(val) ? val.map((v) => typeof v === "number" ? v : 0) : [];
1573
1495
  }
1574
- });
1496
+ }
1575
1497
  return obj.text ? obj : null;
1576
1498
  }).filter(Boolean);
1577
1499
  setCache(cacheKey, data);
1578
1500
  return data;
1579
1501
  } catch (e) {
1580
1502
  log(`getTextContent error: ${e.message}`);
1581
- return { total: 0, offset, limit, texts: [] };
1503
+ throw e;
1582
1504
  }
1583
1505
  }
1584
1506
  async function getDwgName() {
1585
- if (!cad.connected)
1586
- await cad.connect();
1587
- if (!cad.connected)
1588
- return { name: null };
1507
+ if (!cad.connected) await cad.connect();
1508
+ if (!cad.connected) return { name: null };
1589
1509
  try {
1590
1510
  const code = `(vl-princ-to-string (getvar "dwgname"))`;
1591
1511
  const name = await cad.sendCommandWithResult(code);
@@ -1595,10 +1515,8 @@ async function getDwgName() {
1595
1515
  }
1596
1516
  }
1597
1517
  async function getDwgPath() {
1598
- if (!cad.connected)
1599
- await cad.connect();
1600
- if (!cad.connected)
1601
- return { path: null, name: null };
1518
+ if (!cad.connected) await cad.connect();
1519
+ if (!cad.connected) return { path: null, name: null };
1602
1520
  try {
1603
1521
  const code = `(progn
1604
1522
  (setq prefix (vl-princ-to-string (getvar "dwgprefix")))
@@ -1617,8 +1535,7 @@ async function getDwgPath() {
1617
1535
  }
1618
1536
  if (!parsed) {
1619
1537
  const listResult = parseLispList(result);
1620
- if (listResult && listResult.length >= 2)
1621
- parsed = listResult;
1538
+ if (listResult && listResult.length >= 2) parsed = listResult;
1622
1539
  }
1623
1540
  if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
1624
1541
  return { path: String(parsed[0]), name: String(parsed[1]) };
@@ -1629,100 +1546,71 @@ async function getDwgPath() {
1629
1546
  }
1630
1547
  }
1631
1548
  function buildBlockRefsCode(filterBlockName) {
1632
- const filterExpr = filterBlockName ? `(list (cons 2 "${escapeLispString(filterBlockName)}"))` : "nil";
1549
+ const filterItems = ['(cons 0 "INSERT")'];
1550
+ if (filterBlockName) {
1551
+ filterItems.push(`(cons 2 "${escapeLispString(filterBlockName)}")`);
1552
+ }
1553
+ const filterCode = `(list ${filterItems.join(" ")})`;
1633
1554
  return `(progn
1634
1555
  (vl-load-com)
1635
- (defun @br:attr (ent / atts)
1636
- (if (= (type ent) 'VLA-OBJECT)
1637
- (progn
1638
- (setq atts (vlax-variant-value (vla-getattributes ent)))
1639
- (if (safearray-value atts)
1640
- (mapcar '(lambda (x) (cons (vla-get-tagstring x) (vla-get-textstring x)))
1641
- (vlax-safearray->list atts))
1642
- nil))
1643
- (if (setq att (entnext ent))
1644
- (progn
1645
- (setq atts nil)
1646
- (while (= (cdr (assoc 0 (entget att))) "ATTRIB")
1647
- (setq atts (cons (cons (cdr (assoc 2 (entget att))) (cdr (assoc 1 (entget att)))) atts))
1648
- att (entnext att))
1649
- (reverse atts))
1650
- nil))))
1651
1556
 
1652
- (defun @br:dynprops (ent / obj props)
1653
- (if (= (type ent) 'VLA-OBJECT)
1654
- (progn
1655
- (setq obj ent)
1656
- (if (vlax-property-available-p obj 'isdynamicblock)
1657
- (if (vla-get-isdynamicblock obj)
1658
- (progn
1659
- (setq props (vlax-invoke obj 'getdynamicblockproperties))
1660
- (mapcar '(lambda (x)
1661
- (cons (vla-get-propertyname x)
1662
- (list (cons "value" (vla-get-value x))
1663
- (cons "readOnly" (vla-get-readonly x))
1664
- (cons "show" (vla-get-show x)))))
1665
- (vlax-safearray->list props)))
1666
- nil)
1667
- nil))
1668
- (if (and (setq obj (vlax-ename->vla-object ent))
1669
- (vlax-property-available-p obj 'isdynamicblock)
1670
- (vla-get-isdynamicblock obj))
1671
- (progn
1672
- (setq props (vlax-invoke obj 'getdynamicblockproperties))
1673
- (mapcar '(lambda (x)
1674
- (cons (vla-get-propertyname x)
1675
- (list (cons "value" (vla-get-value x))
1676
- (cons "readOnly" (vla-get-readonly x))
1677
- (cons "show" (vla-get-show x)))))
1678
- (vlax-safearray->list props)))
1679
- nil)))
1557
+ (defun @br:try-fn (fn arg / r)
1558
+ (setq r (vl-catch-all-apply (function (lambda () (apply fn (list arg))))))
1559
+ (if (vl-catch-all-error-p r) nil r))
1680
1560
 
1681
- (defun @br:props (ent / obj blkname result)
1682
- (setq obj (vlax-ename->vla-object ent))
1683
- (setq result (list
1684
- (cons "handle" (cdr (assoc 5 (entget ent))))
1685
- (cons "layer" (cdr (assoc 8 (entget ent))))
1686
- (cons "blockName" (vla-get-name obj))
1687
- (cons "effectiveBlockName" (vla-get-effectivename obj))
1688
- (cons "insertionPoint" (vlax-safearray->list (vla-get-insertionpoint obj)))
1689
- (cons "rotation" (vla-get-rotation obj))
1690
- (cons "scale" (list (vla-get-xscale obj) (vla-get-yscale obj) (vla-get-zscale obj)))
1691
- (cons "isDynamic" (if (vlax-property-available-p obj 'isdynamicblock) (vla-get-isdynamicblock obj) nil))
1692
- (cons "attributes" (@br:attr obj))
1693
- (cons "dynamicProperties" (@br:dynprops obj))))
1694
- result)
1561
+ (defun @br:props (ent / ed r p2 p10 p50 p41 p42 p43)
1562
+ (setq ed (entget ent)
1563
+ p10 (cdr (assoc 10 ed))
1564
+ p50 (cdr (assoc 50 ed))
1565
+ p41 (cdr (assoc 41 ed))
1566
+ p42 (cdr (assoc 42 ed))
1567
+ p43 (cdr (assoc 43 ed)))
1568
+ (setq r (vl-catch-all-apply
1569
+ (function (lambda ()
1570
+ (list
1571
+ (cons "handle" (cdr (assoc 5 ed)))
1572
+ (cons "layer" (cdr (assoc 8 ed)))
1573
+ (cons "blockName" (cdr (assoc 2 ed)))
1574
+ (cons "effectiveBlockName" (cdr (assoc 2 ed)))
1575
+ (cons "insertionPoint" (list (car p10) (cadr p10) (caddr p10)))
1576
+ (cons "rotation" p50)
1577
+ (cons "scale" (list p41 p42 p43))
1578
+ (cons "attributes" (@br:try-fn 'block:get-attributes ent))
1579
+ (cons "dynamicProperties" (@br:try-fn 'block:get-properties ent)))))))
1580
+ (if (vl-catch-all-error-p r) (list (cons "handle" (cdr (assoc 5 ed)))) r))
1695
1581
 
1696
- (setq ss (ssget "_X" (list (cons 0 "INSERT") ${filterExpr})))
1582
+ (setq ss (ssget "_X" ${filterCode}))
1697
1583
  (if (null ss)
1698
1584
  (list (cons "total" 0) (cons "blockRefs" nil))
1699
1585
  (progn
1700
1586
  (setq total (sslength ss) i 0 refs nil)
1701
1587
  (while (< i total)
1702
- (setq refs (cons (@br:props (ssname ss i)) refs) i (1+ i)))
1703
- (list (cons "total" total) (cons "blockRefs" (reverse refs))))))`;
1588
+ (setq r (@br:props (ssname ss i)))
1589
+ (if r (setq refs (cons r refs)))
1590
+ (setq i (1+ i)))
1591
+ (list (cons "total" total) (cons "blockRefs" (list (reverse refs)))))))`;
1704
1592
  }
1705
1593
  async function getBlockRefs(params = {}) {
1706
1594
  const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
1707
1595
  const cached = getCached(cacheKey);
1708
- if (cached)
1709
- return cached;
1710
- if (!cad.connected)
1711
- await cad.connect();
1596
+ if (cached) return cached;
1597
+ if (!cad.connected) await cad.connect();
1712
1598
  if (!cad.connected) {
1713
1599
  return { total: 0, blockRefs: [] };
1714
1600
  }
1715
1601
  try {
1716
1602
  const code = buildBlockRefsCode(params.blockName);
1717
1603
  const resultStr = await cad.sendCommandWithResult(code);
1718
- if (!resultStr || resultStr === "" || resultStr === "nil") {
1719
- return { total: 0, blockRefs: [] };
1720
- }
1721
1604
  const parsed = parseLispRecursive(resultStr);
1722
1605
  if (!parsed || !Array.isArray(parsed)) {
1723
- return { total: 0, blockRefs: [] };
1606
+ throw new Error(`block-refs: \u89E3\u6790 Lisp \u7ED3\u679C\u5931\u8D25: raw="${String(resultStr).substring(0, 500)}"`);
1607
+ }
1608
+ const result = {};
1609
+ for (const pair of parsed) {
1610
+ if (Array.isArray(pair) && pair.length >= 2) {
1611
+ result[String(pair[0])] = pair[1];
1612
+ }
1724
1613
  }
1725
- const result = lispPairsToObject(parsed);
1726
1614
  const blockRefs = Array.isArray(result.blockRefs) ? result.blockRefs : [];
1727
1615
  const finalResult = {
1728
1616
  total: typeof result.total === "number" ? result.total : blockRefs.length,
@@ -1732,13 +1620,25 @@ async function getBlockRefs(params = {}) {
1732
1620
  br.forEach((pair) => {
1733
1621
  if (Array.isArray(pair) && pair.length >= 2) {
1734
1622
  const key = pair[0];
1735
- let val = pair[1];
1623
+ let val = pair.length === 2 ? pair[1] : pair.slice(1);
1736
1624
  if (key === "insertionPoint" && Array.isArray(val)) {
1737
1625
  val = val.map((v) => typeof v === "number" ? v : 0);
1738
1626
  } else if (key === "scale" && Array.isArray(val)) {
1739
1627
  val = val.map((v) => typeof v === "number" ? v : 1);
1740
1628
  } else if (key === "isDynamic") {
1741
1629
  val = val === true || val === "true" || val === 1;
1630
+ } else if (key === "attributes" && Array.isArray(val)) {
1631
+ const o = {};
1632
+ val.forEach((p) => {
1633
+ if (Array.isArray(p) && p.length >= 2) o[String(p[0])] = p[1];
1634
+ });
1635
+ val = o;
1636
+ } else if (key === "dynamicProperties" && Array.isArray(val)) {
1637
+ const o = {};
1638
+ val.forEach((p) => {
1639
+ if (Array.isArray(p) && p.length >= 2) o[String(p[0])] = p[1];
1640
+ });
1641
+ val = o;
1742
1642
  }
1743
1643
  obj[key] = val;
1744
1644
  }
@@ -1751,51 +1651,67 @@ async function getBlockRefs(params = {}) {
1751
1651
  return finalResult;
1752
1652
  } catch (e) {
1753
1653
  log(`getBlockRefs error: ${e.message}`);
1754
- return { total: 0, blockRefs: [] };
1654
+ throw e;
1755
1655
  }
1756
1656
  }
1657
+ var VLA_HELPER_LISP = `(defun @:get-props (obj prop-names / result p p-sym val)
1658
+ (setq result nil)
1659
+ (foreach p prop-names
1660
+ (setq p-sym (read p))
1661
+ (if (vlax-property-available-p obj p-sym)
1662
+ (progn
1663
+ (setq val (vl-catch-all-apply 'vlax-get (list obj p-sym)))
1664
+ (if (not (vl-catch-all-error-p val))
1665
+ (progn
1666
+ (cond
1667
+ ((= (type val) 'VLA-OBJECT) (setq val (strcat "@" (vla-get-objectname val))))
1668
+ ((or (= (type val) 'STR) (= (type val) 'SAFEARRAY) (listp val)) (setq val (vl-prin1-to-string val))))
1669
+ (setq result (cons (cons p val) result)))))))
1670
+ (reverse result))`;
1757
1671
  function buildTablesCode(tblName) {
1758
1672
  const raw = tblName.toLowerCase();
1759
1673
  const key = TBL_KEY_ALIAS[raw] || raw;
1760
1674
  const query = TBL_QUERIES[key];
1675
+ const isVlaTable = key !== "layer";
1761
1676
  if (query) {
1677
+ if (isVlaTable) {
1678
+ return `(progn (vl-load-com) ${VLA_HELPER_LISP} ${query.lisp})`;
1679
+ }
1762
1680
  return `(progn (vl-load-com) ${query.lisp})`;
1763
1681
  }
1764
- const parts = Object.values(TBL_QUERIES).map((q) => q.lisp);
1765
- return `(progn (vl-load-com) (list ${parts.join(" ")}))`;
1682
+ const parts = Object.values(TBL_QUERIES).map((q) => `(vl-catch-all-apply '(lambda () ${q.lisp}))`);
1683
+ return `(progn (vl-load-com) ${VLA_HELPER_LISP} (list ${parts.join(" ")}))`;
1766
1684
  }
1767
- function parseTableRecord(rec) {
1768
- if (!rec || !Array.isArray(rec))
1769
- return null;
1685
+ function parseTableRecord(rec, tableName) {
1686
+ if (!rec || !Array.isArray(rec)) return null;
1770
1687
  const obj = {};
1688
+ const isLayer = tableName === "layer";
1771
1689
  for (const pair of rec) {
1772
1690
  if (Array.isArray(pair) && pair.length >= 2) {
1773
1691
  const key = String(pair[0]);
1774
1692
  const val = pair[1];
1775
- if (key === "2")
1776
- obj.name = String(val);
1777
- else if (key === "62")
1778
- obj.color = typeof val === "number" ? val : 7;
1779
- else if (key === "6")
1780
- obj.linetype = String(val);
1781
- else if (key === "70") {
1782
- obj.flags = typeof val === "number" ? val : 0;
1783
- obj.frozen = (val & 1) !== 0;
1784
- obj.locked = (val & 4) !== 0;
1785
- } else if (key === "60")
1786
- obj.on = val === 0;
1787
- else if (key === "1")
1788
- obj.font = String(val);
1789
- else if (key === "40")
1790
- obj.height = typeof val === "number" ? val : 0;
1791
- else if (key === "41")
1792
- obj.width = typeof val === "number" ? val : 1;
1793
- else if (key === "42")
1794
- obj.oblique = typeof val === "number" ? val : 0;
1795
- else if (key === "3")
1796
- obj.bigfont = String(val);
1797
- else if (key === "50")
1798
- obj.flags = typeof val === "number" ? val : 0;
1693
+ const isDxfCode = typeof pair[0] === "number";
1694
+ if (isDxfCode) {
1695
+ if (key === "2") obj.name = String(val);
1696
+ else if (key === "62") obj.color = typeof val === "number" ? val : 7;
1697
+ else if (key === "6") obj.linetype = String(val);
1698
+ else if (key === "70") {
1699
+ obj.flags = typeof val === "number" ? val : 0;
1700
+ if (isLayer) {
1701
+ obj.frozen = (val & 1) !== 0;
1702
+ obj.locked = (val & 4) !== 0;
1703
+ }
1704
+ } else if (key === "60") obj.on = val === 0;
1705
+ else if (key === "1") obj.font = String(val);
1706
+ else if (key === "40") obj.height = typeof val === "number" ? val : 0;
1707
+ else if (key === "41") obj.width = typeof val === "number" ? val : 1;
1708
+ else if (key === "42") obj.oblique = typeof val === "number" ? val : 0;
1709
+ else if (key === "3") obj.bigfont = String(val);
1710
+ else if (key === "50") obj.flags = typeof val === "number" ? val : 0;
1711
+ } else {
1712
+ if (key === "Name") obj.name = val;
1713
+ obj[key] = val;
1714
+ }
1799
1715
  }
1800
1716
  }
1801
1717
  return obj.name ? obj : null;
@@ -1804,12 +1720,9 @@ async function getTables(params = {}) {
1804
1720
  const tblName = params.tbl || params.type || "all";
1805
1721
  const cacheKey = `dwg:tbl:${tblName}`;
1806
1722
  const cached = getCached(cacheKey);
1807
- if (cached)
1808
- return cached;
1809
- if (!cad.connected)
1810
- await cad.connect();
1811
- if (!cad.connected)
1812
- return { table: tblName, data: [] };
1723
+ if (cached) return cached;
1724
+ if (!cad.connected) await cad.connect();
1725
+ if (!cad.connected) return { table: tblName, data: [] };
1813
1726
  try {
1814
1727
  const code = buildTablesCode(tblName);
1815
1728
  const resultStr = await cad.sendCommandWithResult(code);
@@ -1828,10 +1741,9 @@ async function getTables(params = {}) {
1828
1741
  for (const item of parsed) {
1829
1742
  if (Array.isArray(item) && item.length >= 2) {
1830
1743
  const key = String(item[0]).toUpperCase();
1831
- if (key === "TOTAL")
1832
- total = typeof item[1] === "number" ? item[1] : 0;
1744
+ if (key === "TOTAL") total = typeof item[1] === "number" ? item[1] : 0;
1833
1745
  else if (key === "DATA") {
1834
- if (Array.isArray(item[1]) && item[1].length > 0 && item[1][0].length > 0 && !isNaN(parseInt(item[1][0][0]))) {
1746
+ if (Array.isArray(item[1]) && item[1].length > 0) {
1835
1747
  tblData = item[1];
1836
1748
  }
1837
1749
  }
@@ -1843,46 +1755,41 @@ async function getTables(params = {}) {
1843
1755
  result = {
1844
1756
  table: tableName,
1845
1757
  total,
1846
- data: tblData.map(parseTableRecord).filter(Boolean)
1758
+ data: tblData.map((r) => parseTableRecord(r, tableName)).filter(Boolean)
1847
1759
  };
1848
1760
  } else {
1849
1761
  const allData = {};
1850
1762
  parsed.forEach((item) => {
1851
- if (!Array.isArray(item) || item.length < 2)
1852
- return;
1763
+ if (!Array.isArray(item) || item.length < 2) return;
1853
1764
  let tableKey = null;
1854
1765
  const entry = { total: 0, data: [] };
1855
1766
  if (Array.isArray(item[0]) && item[0].length >= 2 && String(item[0][0]).toLowerCase() === "table") {
1856
1767
  tableKey = String(item[0][1]).toLowerCase();
1857
1768
  for (let i = 1; i < item.length; i++) {
1858
1769
  const sub = item[i];
1859
- if (!Array.isArray(sub) || sub.length < 2)
1860
- continue;
1770
+ if (!Array.isArray(sub) || sub.length < 2) continue;
1861
1771
  const subKey = String(sub[0]).toUpperCase();
1862
- if (subKey === "TOTAL")
1863
- entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1772
+ if (subKey === "TOTAL") entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1864
1773
  else if (subKey === "DATA") {
1865
1774
  const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
1866
- entry.data = raw.map(parseTableRecord).filter(Boolean);
1775
+ entry.data = raw.map((r) => parseTableRecord(r, tableKey)).filter(Boolean);
1867
1776
  }
1868
1777
  }
1869
1778
  } else {
1870
1779
  tableKey = String(item[0]).toLowerCase();
1871
1780
  for (let i = 1; i < item.length; i++) {
1872
1781
  const sub = item[i];
1873
- if (!Array.isArray(sub) || sub.length < 2)
1874
- continue;
1782
+ if (!Array.isArray(sub) || sub.length < 2) continue;
1875
1783
  const subKey = String(sub[0]).toUpperCase();
1876
1784
  if (subKey === "TOTAL") {
1877
1785
  entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1878
1786
  } else if (subKey === "DATA") {
1879
1787
  const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
1880
- entry.data = raw.map(parseTableRecord).filter(Boolean);
1788
+ entry.data = raw.map((r) => parseTableRecord(r, tableKey)).filter(Boolean);
1881
1789
  }
1882
1790
  }
1883
1791
  }
1884
- if (tableKey)
1885
- allData[tableKey] = entry;
1792
+ if (tableKey) allData[tableKey] = entry;
1886
1793
  });
1887
1794
  result = allData;
1888
1795
  }
@@ -1896,12 +1803,9 @@ async function getTables(params = {}) {
1896
1803
  async function getPackages(filterName = null) {
1897
1804
  const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
1898
1805
  const cached = getCached(cacheKey);
1899
- if (cached)
1900
- return cached;
1901
- if (!cad.connected)
1902
- await cad.connect();
1903
- if (!cad.connected)
1904
- return [];
1806
+ if (cached) return cached;
1807
+ if (!cad.connected) await cad.connect();
1808
+ if (!cad.connected) return [];
1905
1809
  try {
1906
1810
  const code = `(mapcar 'cdr @::*local-pkgs*)`;
1907
1811
  const result = await cad.sendCommandWithResult(code);
@@ -1914,8 +1818,7 @@ async function getPackages(filterName = null) {
1914
1818
  } catch {
1915
1819
  raw = parseLispList(result) || [];
1916
1820
  }
1917
- if (!Array.isArray(raw))
1918
- raw = [];
1821
+ if (!Array.isArray(raw)) raw = [];
1919
1822
  const packages = raw.map((item) => {
1920
1823
  if (Array.isArray(item)) {
1921
1824
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
@@ -1924,20 +1827,13 @@ async function getPackages(filterName = null) {
1924
1827
  const [[key, val]] = Object.entries(entry);
1925
1828
  const k = String(key);
1926
1829
  const v = String(val);
1927
- if (k === ":NAME")
1928
- pkg.name = v;
1929
- else if (k === ":VERSION")
1930
- pkg.version = v;
1931
- else if (k === ":DESCRIPTION")
1932
- pkg.description = v;
1933
- else if (k === ":FULL-NAME")
1934
- pkg.fullName = v;
1935
- else if (k === ":AUTHOR")
1936
- pkg.author = v;
1937
- else if (k === ":CATEGORY")
1938
- pkg.category = v;
1939
- else if (k === ":URL")
1940
- pkg.url = v;
1830
+ if (k === ":NAME") pkg.name = v;
1831
+ else if (k === ":VERSION") pkg.version = v;
1832
+ else if (k === ":DESCRIPTION") pkg.description = v;
1833
+ else if (k === ":FULL-NAME") pkg.fullName = v;
1834
+ else if (k === ":AUTHOR") pkg.author = v;
1835
+ else if (k === ":CATEGORY") pkg.category = v;
1836
+ else if (k === ":URL") pkg.url = v;
1941
1837
  }
1942
1838
  }
1943
1839
  return pkg;
@@ -1948,22 +1844,15 @@ async function getPackages(filterName = null) {
1948
1844
  if (item && typeof item === "object") {
1949
1845
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
1950
1846
  const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
1951
- if (nameVal)
1952
- pkg.name = String(nameVal);
1847
+ if (nameVal) pkg.name = String(nameVal);
1953
1848
  const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
1954
- if (verVal)
1955
- pkg.version = String(verVal);
1849
+ if (verVal) pkg.version = String(verVal);
1956
1850
  const descVal = item.description || item.Description || item.DESCRIPTION || item[":DESCRIPTION"];
1957
- if (descVal)
1958
- pkg.description = String(descVal);
1959
- if (item.fullName || item.full_name)
1960
- pkg.fullName = String(item.fullName || item.full_name);
1961
- if (item.author || item.Author)
1962
- pkg.author = String(item.author || item.Author);
1963
- if (item.category || item.Category)
1964
- pkg.category = String(item.category || item.Category);
1965
- if (item.url || item.Url || item.URL)
1966
- pkg.url = String(item.url || item.Url || item.URL);
1851
+ if (descVal) pkg.description = String(descVal);
1852
+ if (item.fullName || item.full_name) pkg.fullName = String(item.fullName || item.full_name);
1853
+ if (item.author || item.Author) pkg.author = String(item.author || item.Author);
1854
+ if (item.category || item.Category) pkg.category = String(item.category || item.Category);
1855
+ if (item.url || item.Url || item.URL) pkg.url = String(item.url || item.Url || item.URL);
1967
1856
  return pkg;
1968
1857
  }
1969
1858
  return null;
@@ -1988,12 +1877,9 @@ function getPlatforms() {
1988
1877
  async function getDwgList() {
1989
1878
  const cacheKey = "cad:dwgs";
1990
1879
  const cached = getCached(cacheKey);
1991
- if (cached)
1992
- return cached;
1993
- if (!cad.connected)
1994
- await cad.connect();
1995
- if (!cad.connected)
1996
- return [];
1880
+ if (cached) return cached;
1881
+ if (!cad.connected) await cad.connect();
1882
+ if (!cad.connected) return [];
1997
1883
  try {
1998
1884
  const code = `(progn
1999
1885
  (vl-load-com)
@@ -2011,13 +1897,12 @@ async function getDwgList() {
2011
1897
  try {
2012
1898
  parsed = JSON.parse(result);
2013
1899
  } catch (e) {
2014
- const listResult = parseLispList(result);
2015
- if (listResult) {
1900
+ const listResult = parseLispRecursive(result);
1901
+ if (Array.isArray(listResult)) {
2016
1902
  parsed = listResult;
2017
1903
  }
2018
1904
  }
2019
- if (!Array.isArray(parsed))
2020
- parsed = [];
1905
+ if (!Array.isArray(parsed)) parsed = [];
2021
1906
  const dwgList = parsed.map((item) => {
2022
1907
  if (Array.isArray(item) && item.length >= 2) {
2023
1908
  return { name: String(item[0]), path: String(item[1]) };
@@ -2043,8 +1928,7 @@ function loadStandardsFile(filename) {
2043
1928
  var standardsCache = /* @__PURE__ */ new Map();
2044
1929
  function getCachedStandards(key) {
2045
1930
  const entry = standardsCache.get(key);
2046
- if (entry && Date.now() - entry.timestamp < 3e4)
2047
- return entry.data;
1931
+ if (entry && Date.now() - entry.timestamp < 3e4) return entry.data;
2048
1932
  standardsCache.delete(key);
2049
1933
  return null;
2050
1934
  }
@@ -2053,49 +1937,40 @@ function setCachedStandards(key, data) {
2053
1937
  }
2054
1938
  function getDraftingStandards() {
2055
1939
  const cached = getCachedStandards("drafting");
2056
- if (cached)
2057
- return cached;
1940
+ if (cached) return cached;
2058
1941
  const data = loadStandardsFile("drafting.json");
2059
- if (data)
2060
- setCachedStandards("drafting", data);
1942
+ if (data) setCachedStandards("drafting", data);
2061
1943
  return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
2062
1944
  }
2063
1945
  function getCodingStandards() {
2064
1946
  const cached = getCachedStandards("coding");
2065
- if (cached)
2066
- return cached;
1947
+ if (cached) return cached;
2067
1948
  const data = loadStandardsFile("coding.json");
2068
- if (data)
2069
- setCachedStandards("coding", data);
1949
+ if (data) setCachedStandards("coding", data);
2070
1950
  return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
2071
1951
  }
2072
1952
 
2073
1953
  // src/handlers/resource-handlers.js
2074
1954
  function parseQuery(uri) {
2075
1955
  const qIdx = uri.indexOf("?");
2076
- if (qIdx === -1)
2077
- return { base: uri, params: {} };
1956
+ if (qIdx === -1) return { base: uri, params: {} };
2078
1957
  const base = uri.substring(0, qIdx);
2079
1958
  const params = {};
2080
1959
  uri.substring(qIdx + 1).split("&").forEach((p) => {
2081
1960
  const eqIdx = p.indexOf("=");
2082
1961
  const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
2083
1962
  const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
2084
- if (k)
2085
- params[k] = decodeURIComponent(v);
1963
+ if (k) params[k] = decodeURIComponent(v);
2086
1964
  });
2087
1965
  return { base, params };
2088
1966
  }
2089
1967
  function parseTemplateUri(uri) {
2090
1968
  const entityMatch = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
2091
- if (entityMatch)
2092
- return { type: "entity", handle: entityMatch[1] };
1969
+ if (entityMatch) return { type: "entity", handle: entityMatch[1] };
2093
1970
  const tblMatch = uri.match(/^atlisp:\/\/dwg\/tbl\/([^?]+)$/);
2094
- if (tblMatch)
2095
- return { type: "tbl", tblName: tblMatch[1] };
1971
+ if (tblMatch) return { type: "tbl", tblName: tblMatch[1] };
2096
1972
  const blockRefMatch = uri.match(/^atlisp:\/\/dwg\/block-refs\/([^?]+)$/);
2097
- if (blockRefMatch)
2098
- return { type: "block-refs", blockName: blockRefMatch[1] };
1973
+ if (blockRefMatch) return { type: "block-refs", blockName: blockRefMatch[1] };
2099
1974
  return null;
2100
1975
  }
2101
1976
  async function listResources(subscribedUris = []) {
@@ -2255,10 +2130,8 @@ function isPrefixUri(uri) {
2255
2130
  return uri.endsWith("/");
2256
2131
  }
2257
2132
  function matchesSubscription(subscribedUri, targetUri) {
2258
- if (subscribedUri === targetUri)
2259
- return true;
2260
- if (isPrefixUri(subscribedUri) && targetUri.startsWith(subscribedUri))
2261
- return true;
2133
+ if (subscribedUri === targetUri) return true;
2134
+ if (isPrefixUri(subscribedUri) && targetUri.startsWith(subscribedUri)) return true;
2262
2135
  return false;
2263
2136
  }
2264
2137
  function isSubscribed(uri, sessionId) {
@@ -2268,8 +2141,7 @@ function isSubscribed(uri, sessionId) {
2268
2141
  }
2269
2142
  const allUris = sessionManager.getAllSubscribedUris();
2270
2143
  for (const su of allUris) {
2271
- if (matchesSubscription(su, uri))
2272
- return true;
2144
+ if (matchesSubscription(su, uri)) return true;
2273
2145
  }
2274
2146
  return false;
2275
2147
  }
@@ -2378,11 +2250,9 @@ var SseSession = class {
2378
2250
  return lines.join("\n") + "\n\n";
2379
2251
  }
2380
2252
  _setupDrain() {
2381
- if (typeof this.#res.on !== "function")
2382
- return;
2253
+ if (typeof this.#res.on !== "function") return;
2383
2254
  this.#drainHandler = () => {
2384
- if (!this.#active)
2385
- return;
2255
+ if (!this.#active) return;
2386
2256
  if (this.#backpressureBuffer.length > 0) {
2387
2257
  this._drainBuffer();
2388
2258
  }
@@ -2404,8 +2274,7 @@ var SseSession = class {
2404
2274
  }
2405
2275
  }
2406
2276
  _write(content) {
2407
- if (!this.#active)
2408
- return false;
2277
+ if (!this.#active) return false;
2409
2278
  try {
2410
2279
  if (this.#backpressureBuffer.length > 0) {
2411
2280
  this.#backpressureBuffer.push(content);
@@ -2534,8 +2403,7 @@ function persistSessionData(clientId, sessionData) {
2534
2403
  function loadPersistedSessionData(clientId) {
2535
2404
  try {
2536
2405
  const filePath = getSessionStorePath(clientId);
2537
- if (!fs4.existsSync(filePath))
2538
- return null;
2406
+ if (!fs4.existsSync(filePath)) return null;
2539
2407
  const raw = fs4.readFileSync(filePath, "utf-8");
2540
2408
  const store = JSON.parse(raw);
2541
2409
  if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
@@ -2599,8 +2467,7 @@ var SseSessionManager = class {
2599
2467
  session.close();
2600
2468
  this.#sessions.delete(clientId);
2601
2469
  const idx = this.#accessOrder.indexOf(clientId);
2602
- if (idx !== -1)
2603
- this.#accessOrder.splice(idx, 1);
2470
+ if (idx !== -1) this.#accessOrder.splice(idx, 1);
2604
2471
  return true;
2605
2472
  }
2606
2473
  return false;
@@ -2687,8 +2554,7 @@ var SseSessionManager = class {
2687
2554
  session.close();
2688
2555
  this.#sessions.delete(clientId);
2689
2556
  const idx = this.#accessOrder.indexOf(clientId);
2690
- if (idx !== -1)
2691
- this.#accessOrder.splice(idx, 1);
2557
+ if (idx !== -1) this.#accessOrder.splice(idx, 1);
2692
2558
  }
2693
2559
  }
2694
2560
  }
@@ -2736,8 +2602,7 @@ var SessionTransport = class {
2736
2602
  this._started = true;
2737
2603
  }
2738
2604
  async send(message) {
2739
- if (this._closed)
2740
- return;
2605
+ if (this._closed) return;
2741
2606
  if (this._pendingRequest) {
2742
2607
  const { resolve, reject, timeout } = this._pendingRequest;
2743
2608
  clearTimeout(timeout);
@@ -2746,8 +2611,7 @@ var SessionTransport = class {
2746
2611
  }
2747
2612
  }
2748
2613
  async close() {
2749
- if (this._closed)
2750
- return;
2614
+ if (this._closed) return;
2751
2615
  this._closed = true;
2752
2616
  if (this._pendingRequest) {
2753
2617
  const { reject, timeout } = this._pendingRequest;
@@ -2821,12 +2685,10 @@ var DEFS_DIR = path7.join(__dirname3, "definitions");
2821
2685
  var PROMPTS_DIR = path7.join(__dirname3, "..", "..", "prompts");
2822
2686
  var builtinDefs = null;
2823
2687
  function loadBuiltinDefs() {
2824
- if (builtinDefs)
2825
- return builtinDefs;
2688
+ if (builtinDefs) return builtinDefs;
2826
2689
  builtinDefs = {};
2827
2690
  try {
2828
- if (!fs5.existsSync(DEFS_DIR))
2829
- return builtinDefs;
2691
+ if (!fs5.existsSync(DEFS_DIR)) return builtinDefs;
2830
2692
  const files = fs5.readdirSync(DEFS_DIR).filter((f) => f.endsWith(".json"));
2831
2693
  for (const file of files) {
2832
2694
  try {
@@ -2888,15 +2750,12 @@ function formatLispPoints(pointsStr) {
2888
2750
  return `(list ${ptList.join(" ")})`;
2889
2751
  }
2890
2752
  function getDimensionStyleLisp(style) {
2891
- if (style === "horizontal" || style === "vertical")
2892
- return "DIMLINEAR";
2753
+ if (style === "horizontal" || style === "vertical") return "DIMLINEAR";
2893
2754
  return "DIMALIGNED";
2894
2755
  }
2895
2756
  function getDimensionStyleLabel(style) {
2896
- if (style === "horizontal")
2897
- return "\u6C34\u5E73";
2898
- if (style === "vertical")
2899
- return "\u5782\u76F4";
2757
+ if (style === "horizontal") return "\u6C34\u5E73";
2758
+ if (style === "vertical") return "\u5782\u76F4";
2900
2759
  return "aligned";
2901
2760
  }
2902
2761
  async function handleComplexPrompt(def, args) {
@@ -2930,14 +2789,10 @@ async function handleComplexPrompt(def, args) {
2930
2789
  } catch {
2931
2790
  }
2932
2791
  const suggestions = [];
2933
- if (entities.total > 1e3)
2934
- suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
2935
- if (layers.length > 20)
2936
- suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
2937
- if (entities.byType.LINE && entities.byType.LINE > 500)
2938
- suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
2939
- if (!entities.byType.DIMENSION)
2940
- suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
2792
+ if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
2793
+ if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
2794
+ 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");
2795
+ if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
2941
2796
  return {
2942
2797
  messages: [{
2943
2798
  role: "user",
@@ -3130,8 +2985,7 @@ ${code}
3130
2985
  }
3131
2986
  const defs = loadBuiltinDefs();
3132
2987
  const def = defs[name];
3133
- if (!def)
3134
- throw new Error(`Unknown prompt: ${name}`);
2988
+ if (!def) throw new Error(`Unknown prompt: ${name}`);
3135
2989
  if (def.handler) {
3136
2990
  return handleComplexPrompt(def, args);
3137
2991
  }
@@ -3156,8 +3010,7 @@ import path8 from "path";
3156
3010
  init_config();
3157
3011
  var MAX_HISTORY_VALUES = 1e3;
3158
3012
  function percentile(sorted, p) {
3159
- if (sorted.length === 0)
3160
- return 0;
3013
+ if (sorted.length === 0) return 0;
3161
3014
  const idx = Math.ceil(p * sorted.length) - 1;
3162
3015
  return sorted[Math.max(0, Math.min(idx, sorted.length - 1))];
3163
3016
  }
@@ -3448,8 +3301,7 @@ async function evalLisp(code, withResult = false, encoding = null) {
3448
3301
  return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3449
3302
  }
3450
3303
  const trimmed = (code || "").trim();
3451
- if (!trimmed)
3452
- return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3304
+ if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3453
3305
  try {
3454
3306
  if (withResult) {
3455
3307
  const result = await cad.sendCommandWithResult(trimmed, encoding);
@@ -3469,17 +3321,14 @@ async function getCadInfo2() {
3469
3321
  if (!cad.connected) {
3470
3322
  await cad.connect();
3471
3323
  }
3472
- if (!cad.connected)
3473
- return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3324
+ if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3474
3325
  const info = await cad.getInfo();
3475
3326
  return { content: [{ type: "text", text: info }] };
3476
3327
  }
3477
3328
  async function atCommand(command) {
3478
- if (!cad.connected)
3479
- return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3329
+ if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3480
3330
  const trimmed = (command || "").trim();
3481
- if (!trimmed)
3482
- return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3331
+ if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3483
3332
  await cad.sendCommand(trimmed + "\n");
3484
3333
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
3485
3334
  }
@@ -3487,8 +3336,7 @@ async function newDocument() {
3487
3336
  if (!cad.connected) {
3488
3337
  await cad.connect();
3489
3338
  }
3490
- if (!cad.connected)
3491
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3339
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3492
3340
  const result = await cad.newDoc();
3493
3341
  if (result) {
3494
3342
  return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
@@ -3499,8 +3347,7 @@ async function bringToFront() {
3499
3347
  if (!cad.connected) {
3500
3348
  await cad.connect();
3501
3349
  }
3502
- if (!cad.connected)
3503
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3350
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3504
3351
  const result = await cad.bringToFront();
3505
3352
  if (result) {
3506
3353
  return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
@@ -3511,8 +3358,7 @@ async function installAtlisp() {
3511
3358
  if (!cad.connected) {
3512
3359
  await cad.connect();
3513
3360
  }
3514
- if (!cad.connected)
3515
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3361
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3516
3362
  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))))`;
3517
3363
  await cad.sendCommand(installCode + "\n");
3518
3364
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
@@ -3521,12 +3367,10 @@ async function listFunctionsInCad() {
3521
3367
  if (!cad.connected) {
3522
3368
  await cad.connect();
3523
3369
  }
3524
- if (!cad.connected)
3525
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3370
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3526
3371
  try {
3527
3372
  const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
3528
- if (result)
3529
- return { content: [{ type: "text", text: result }] };
3373
+ if (result) return { content: [{ type: "text", text: result }] };
3530
3374
  return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
3531
3375
  } catch (e) {
3532
3376
  return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
@@ -3583,8 +3427,7 @@ async function initAtlisp() {
3583
3427
  if (!cad.connected) {
3584
3428
  await cad.connect();
3585
3429
  }
3586
- if (!cad.connected)
3587
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3430
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3588
3431
  const code = `(if (null @::load-module)
3589
3432
  (progn
3590
3433
  (vl-load-com)
@@ -3626,15 +3469,12 @@ async function fetchPackages() {
3626
3469
  return cachedPackages || MOCK_PACKAGES;
3627
3470
  }
3628
3471
  function flattenPackages(data) {
3629
- if (Array.isArray(data))
3630
- return data;
3631
- if (data && Array.isArray(data.packages))
3632
- return data.packages;
3472
+ if (Array.isArray(data)) return data;
3473
+ if (data && Array.isArray(data.packages)) return data.packages;
3633
3474
  return [];
3634
3475
  }
3635
3476
  async function listPackages() {
3636
- if (!cad.connected)
3637
- await cad.connect();
3477
+ if (!cad.connected) await cad.connect();
3638
3478
  if (!cad.connected) {
3639
3479
  const data2 = await fetchPackages();
3640
3480
  const items2 = flattenPackages(data2);
@@ -3642,8 +3482,7 @@ async function listPackages() {
3642
3482
  return { content: [{ type: "text", text: text2 }] };
3643
3483
  }
3644
3484
  const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
3645
- if (result && result !== "nil")
3646
- return { content: [{ type: "text", text: result }] };
3485
+ if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
3647
3486
  const data = await fetchPackages();
3648
3487
  const items = flattenPackages(data);
3649
3488
  const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
@@ -3663,12 +3502,10 @@ async function searchPackages(query) {
3663
3502
  for (const p of items) {
3664
3503
  const name = (p.name || "").toLowerCase();
3665
3504
  const desc = (p.description || "").toLowerCase();
3666
- if (name.includes(q) || desc.includes(q))
3667
- results.push(p);
3505
+ if (name.includes(q) || desc.includes(q)) results.push(p);
3668
3506
  }
3669
3507
  } else {
3670
- for (const p of items)
3671
- results.push(p);
3508
+ for (const p of items) results.push(p);
3672
3509
  }
3673
3510
  if (results.length === 0) {
3674
3511
  return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
@@ -3757,8 +3594,7 @@ async function getFunctionUsage(funcName, packageName) {
3757
3594
  if (data) {
3758
3595
  const funcs = Object.values(data.all_functions || {});
3759
3596
  const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
3760
- if (func)
3761
- results.push(func);
3597
+ if (func) results.push(func);
3762
3598
  }
3763
3599
  if (results.length === 0 && FUNCTIONS_DIR) {
3764
3600
  try {
@@ -3767,8 +3603,7 @@ async function getFunctionUsage(funcName, packageName) {
3767
3603
  const raw = fs6.readFileSync(path9.join(FUNCTIONS_DIR, file), "utf-8");
3768
3604
  const data2 = JSON.parse(raw);
3769
3605
  const func = data2.functions?.find((f2) => f2.name === funcName);
3770
- if (func)
3771
- results.push(func);
3606
+ if (func) results.push(func);
3772
3607
  }
3773
3608
  } catch (e) {
3774
3609
  log(`function-handlers: FUNCTIONS_DIR read error: ${e.message}`);
@@ -3838,8 +3673,7 @@ async function getEntity(handle) {
3838
3673
  if (!cad.connected) {
3839
3674
  await cad.connect();
3840
3675
  }
3841
- if (!cad.connected)
3842
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3676
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3843
3677
  const code = `(progn
3844
3678
  (vl-load-com)
3845
3679
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -3871,8 +3705,7 @@ async function setEntityProperty(handle, property, value) {
3871
3705
  if (!cad.connected) {
3872
3706
  await cad.connect();
3873
3707
  }
3874
- if (!cad.connected)
3875
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3708
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3876
3709
  let propCode = "";
3877
3710
  switch (property) {
3878
3711
  case "layer":
@@ -3915,8 +3748,7 @@ async function deleteEntity(handle) {
3915
3748
  if (!cad.connected) {
3916
3749
  await cad.connect();
3917
3750
  }
3918
- if (!cad.connected)
3919
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3751
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3920
3752
  const code = `(progn
3921
3753
  (vl-load-com)
3922
3754
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -3941,15 +3773,12 @@ async function selectEntities(filter) {
3941
3773
  if (!cad.connected) {
3942
3774
  await cad.connect();
3943
3775
  }
3944
- if (!cad.connected)
3945
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3776
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3946
3777
  let filterCode = "nil";
3947
3778
  if (filter && (filter.type || filter.layer)) {
3948
3779
  const items = [];
3949
- if (filter.type)
3950
- items.push(`'(0 . "${escapeLispString(filter.type)}")`);
3951
- if (filter.layer)
3952
- items.push(`'(8 . "${escapeLispString(filter.layer)}")`);
3780
+ if (filter.type) items.push(`'(0 . "${escapeLispString(filter.type)}")`);
3781
+ if (filter.layer) items.push(`'(8 . "${escapeLispString(filter.layer)}")`);
3953
3782
  filterCode = `(list ${items.join(" ")})`;
3954
3783
  }
3955
3784
  const code = `(progn
@@ -3982,8 +3811,7 @@ async function createLayer(name, color = 7, linetype = "Continuous") {
3982
3811
  if (!cad.connected) {
3983
3812
  await cad.connect();
3984
3813
  }
3985
- if (!cad.connected)
3986
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3814
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3987
3815
  const code = `(progn
3988
3816
  (vl-load-com)
3989
3817
  (if (not (tblsearch "LAYER" "${escapeLispString(name)}"))
@@ -4019,8 +3847,7 @@ async function deleteLayer(name) {
4019
3847
  if (!cad.connected) {
4020
3848
  await cad.connect();
4021
3849
  }
4022
- if (!cad.connected)
4023
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3850
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4024
3851
  const code = `(progn
4025
3852
  (vl-load-com)
4026
3853
  (cond
@@ -4054,8 +3881,7 @@ async function setLayerProperty(name, property, value) {
4054
3881
  if (!cad.connected) {
4055
3882
  await cad.connect();
4056
3883
  }
4057
- if (!cad.connected)
4058
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3884
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4059
3885
  let propCode = "";
4060
3886
  switch (property) {
4061
3887
  case "color":
@@ -4103,8 +3929,7 @@ async function setCurrentLayer(name) {
4103
3929
  if (!cad.connected) {
4104
3930
  await cad.connect();
4105
3931
  }
4106
- if (!cad.connected)
4107
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3932
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4108
3933
  const code = `(progn
4109
3934
  (vl-load-com)
4110
3935
  (if (tblsearch "LAYER" "${escapeLispString(name)}")
@@ -4132,8 +3957,7 @@ async function createBlock(name, entities) {
4132
3957
  if (!cad.connected) {
4133
3958
  await cad.connect();
4134
3959
  }
4135
- if (!cad.connected)
4136
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3960
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4137
3961
  const code = `(progn
4138
3962
  (vl-load-com)
4139
3963
  (if (not (tblsearch "BLOCK" "${escapeLispString(name)}"))
@@ -4170,8 +3994,7 @@ async function insertBlock(blockName, point, scale = 1, rotation = 0) {
4170
3994
  if (!cad.connected) {
4171
3995
  await cad.connect();
4172
3996
  }
4173
- if (!cad.connected)
4174
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3997
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4175
3998
  const coords = Array.isArray(point) ? point : point.split(",").map((s) => parseFloat(s.trim()));
4176
3999
  if (coords.length < 2) {
4177
4000
  return { content: [{ type: "text", text: "\u63D2\u5165\u70B9\u683C\u5F0F\u9519\u8BEF\uFF0C\u9700\u8981 x,y \u6216 [x,y,z]" }], isError: true };
@@ -4201,8 +4024,7 @@ async function getBlocks() {
4201
4024
  if (!cad.connected) {
4202
4025
  await cad.connect();
4203
4026
  }
4204
- if (!cad.connected)
4205
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4027
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4206
4028
  const code = `(progn
4207
4029
  (vl-load-com)
4208
4030
  (setq blocks nil)
@@ -4225,8 +4047,7 @@ async function explodeBlock(handle) {
4225
4047
  if (!cad.connected) {
4226
4048
  await cad.connect();
4227
4049
  }
4228
- if (!cad.connected)
4229
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4050
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4230
4051
  const code = `(progn
4231
4052
  (vl-load-com)
4232
4053
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -4262,8 +4083,7 @@ async function openDwg(filePath) {
4262
4083
  if (!cad.connected) {
4263
4084
  await cad.connect();
4264
4085
  }
4265
- if (!cad.connected)
4266
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4086
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4267
4087
  try {
4268
4088
  validateFilePath(filePath);
4269
4089
  } catch (e) {
@@ -4304,8 +4124,7 @@ async function saveDwg(filePath = null) {
4304
4124
  if (!cad.connected) {
4305
4125
  await cad.connect();
4306
4126
  }
4307
- if (!cad.connected)
4308
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4127
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4309
4128
  if (filePath) {
4310
4129
  try {
4311
4130
  validateFilePath(filePath);
@@ -4336,8 +4155,7 @@ async function exportPdf(outputPath, layout = "Model") {
4336
4155
  if (!cad.connected) {
4337
4156
  await cad.connect();
4338
4157
  }
4339
- if (!cad.connected)
4340
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4158
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4341
4159
  try {
4342
4160
  validateFilePath(outputPath);
4343
4161
  } catch (e) {
@@ -4369,8 +4187,7 @@ async function closeDwg(save = false) {
4369
4187
  if (!cad.connected) {
4370
4188
  await cad.connect();
4371
4189
  }
4372
- if (!cad.connected)
4373
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4190
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4374
4191
  const code = `(progn
4375
4192
  (vl-load-com)
4376
4193
  (if ${save ? "T" : "nil"}
@@ -4397,8 +4214,7 @@ async function createDimension(type, points, style = {}) {
4397
4214
  if (!cad.connected) {
4398
4215
  await cad.connect();
4399
4216
  }
4400
- if (!cad.connected)
4401
- 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 };
4402
4218
  let dimCode = "";
4403
4219
  const validTypes = ["ALIGNED", "LINEAR", "ORDINATE", "RADIAL", "DIAMETER", "ANGULAR"];
4404
4220
  const dimType = (type || "ALIGNED").toUpperCase();
@@ -4440,8 +4256,7 @@ async function getDimensionValue(handle) {
4440
4256
  if (!cad.connected) {
4441
4257
  await cad.connect();
4442
4258
  }
4443
- if (!cad.connected)
4444
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4259
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4445
4260
  const code = `(progn
4446
4261
  (vl-load-com)
4447
4262
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -4472,8 +4287,7 @@ async function createHatch(patternName, boundary, scale = 1, angle = 0) {
4472
4287
  if (!cad.connected) {
4473
4288
  await cad.connect();
4474
4289
  }
4475
- if (!cad.connected)
4476
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4290
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4477
4291
  const code = `(progn
4478
4292
  (vl-load-com)
4479
4293
  (command "._BHATCH" "p" "${escapeLispString(patternName)}" "s" "s" "sc" ${scale} "an" ${angle} "")
@@ -4493,17 +4307,12 @@ async function setHatchProperties(handle, props) {
4493
4307
  if (!cad.connected) {
4494
4308
  await cad.connect();
4495
4309
  }
4496
- if (!cad.connected)
4497
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4310
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4498
4311
  let propCode = "";
4499
- if (props.pattern)
4500
- propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "p" "${escapeLispString(props.pattern)}")`;
4501
- if (props.scale)
4502
- propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "s" ${parseFloat(props.scale) || 1})`;
4503
- if (props.angle)
4504
- propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "an" ${parseFloat(props.angle) || 0})`;
4505
- if (props.color)
4506
- propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "c" ${parseInt(props.color) || 256})`;
4312
+ if (props.pattern) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "p" "${escapeLispString(props.pattern)}")`;
4313
+ if (props.scale) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "s" ${parseFloat(props.scale) || 1})`;
4314
+ if (props.angle) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "an" ${parseFloat(props.angle) || 0})`;
4315
+ if (props.color) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "c" ${parseInt(props.color) || 256})`;
4507
4316
  const code = `(progn
4508
4317
  (vl-load-com)
4509
4318
  ${propCode}
@@ -4520,8 +4329,7 @@ async function getBlockAttributes(blockHandle) {
4520
4329
  if (!cad.connected) {
4521
4330
  await cad.connect();
4522
4331
  }
4523
- if (!cad.connected)
4524
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4332
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4525
4333
  const code = `(progn
4526
4334
  (vl-load-com)
4527
4335
  (if (setq ent (handent "${escapeLispString(blockHandle)}"))
@@ -4550,8 +4358,7 @@ async function setBlockAttribute(blockHandle, tag, value) {
4550
4358
  if (!cad.connected) {
4551
4359
  await cad.connect();
4552
4360
  }
4553
- if (!cad.connected)
4554
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4361
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4555
4362
  const code = `(progn
4556
4363
  (vl-load-com)
4557
4364
  (if (setq ent (handent "${escapeLispString(blockHandle)}"))
@@ -4587,8 +4394,7 @@ async function zoomToExtents() {
4587
4394
  if (!cad.connected) {
4588
4395
  await cad.connect();
4589
4396
  }
4590
- if (!cad.connected)
4591
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4397
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4592
4398
  const code = `(progn
4593
4399
  (vl-load-com)
4594
4400
  (command "._ZOOM" "E")
@@ -4605,8 +4411,7 @@ async function zoomToWindow(p1, p2) {
4605
4411
  if (!cad.connected) {
4606
4412
  await cad.connect();
4607
4413
  }
4608
- if (!cad.connected)
4609
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4414
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4610
4415
  const code = `(command "._ZOOM" "W" (list ${toSafePoint(p1)}) (list ${toSafePoint(p2)}))`;
4611
4416
  try {
4612
4417
  await cad.sendCommand(code + "\n");
@@ -4619,8 +4424,7 @@ async function createNamedView(viewName, center = null) {
4619
4424
  if (!cad.connected) {
4620
4425
  await cad.connect();
4621
4426
  }
4622
- if (!cad.connected)
4623
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4427
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4624
4428
  const code = center ? `(command ".-VIEW" "S" "${escapeLispString(viewName)}" "C" (list ${toSafePoint(center)}))` : `(command ".-VIEW" "S" "${escapeLispString(viewName)}")`;
4625
4429
  try {
4626
4430
  await cad.sendCommand(code + "\n");
@@ -4633,8 +4437,7 @@ async function restoreNamedView(viewName) {
4633
4437
  if (!cad.connected) {
4634
4438
  await cad.connect();
4635
4439
  }
4636
- if (!cad.connected)
4637
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4440
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4638
4441
  const code = `(command ".-VIEW" "R" "${escapeLispString(viewName)}")`;
4639
4442
  try {
4640
4443
  await cad.sendCommand(code + "\n");
@@ -4647,8 +4450,7 @@ async function listNamedViews() {
4647
4450
  if (!cad.connected) {
4648
4451
  await cad.connect();
4649
4452
  }
4650
- if (!cad.connected)
4651
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4453
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4652
4454
  const code = `(progn
4653
4455
  (vl-load-com)
4654
4456
  (setq views nil)
@@ -4668,8 +4470,7 @@ async function exportDxf(outputPath, version2 = "R2018") {
4668
4470
  if (!cad.connected) {
4669
4471
  await cad.connect();
4670
4472
  }
4671
- if (!cad.connected)
4672
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4473
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4673
4474
  const versionMap = {
4674
4475
  "R2018": "AC1027",
4675
4476
  "R2015": "AC1024",
@@ -4699,8 +4500,7 @@ async function exportDwf(outputPath) {
4699
4500
  if (!cad.connected) {
4700
4501
  await cad.connect();
4701
4502
  }
4702
- if (!cad.connected)
4703
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4503
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4704
4504
  const code = `(progn
4705
4505
  (vl-load-com)
4706
4506
  (vla-export (vla-get-activedocument (vlax-get-acad-object)) "${escapeLispString(outputPath)}" "dwf")
@@ -4720,8 +4520,7 @@ async function batchSetLayer(handles, layerName) {
4720
4520
  if (!cad.connected) {
4721
4521
  await cad.connect();
4722
4522
  }
4723
- if (!cad.connected)
4724
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4523
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4725
4524
  if (!Array.isArray(handles) || handles.length === 0) {
4726
4525
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
4727
4526
  }
@@ -4751,8 +4550,7 @@ async function createUcs(name, origin = "0,0,0", xAxis = "1,0,0", yAxis = "0,1,0
4751
4550
  if (!cad.connected) {
4752
4551
  await cad.connect();
4753
4552
  }
4754
- if (!cad.connected)
4755
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4553
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4756
4554
  const code = `(progn
4757
4555
  (vl-load-com)
4758
4556
  (if (not (tblsearch "UCS" "${escapeLispString(name)}"))
@@ -4783,8 +4581,7 @@ async function setUcs(name) {
4783
4581
  if (!cad.connected) {
4784
4582
  await cad.connect();
4785
4583
  }
4786
- if (!cad.connected)
4787
- 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 };
4788
4585
  const code = `(progn
4789
4586
  (vl-load-com)
4790
4587
  (if (tblsearch "UCS" "${escapeLispString(name)}")
@@ -4809,8 +4606,7 @@ async function listUcs() {
4809
4606
  if (!cad.connected) {
4810
4607
  await cad.connect();
4811
4608
  }
4812
- if (!cad.connected)
4813
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4609
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4814
4610
  const code = `(progn
4815
4611
  (vl-load-com)
4816
4612
  (setq ucsList nil)
@@ -4833,8 +4629,7 @@ async function deleteUcs(name) {
4833
4629
  if (!cad.connected) {
4834
4630
  await cad.connect();
4835
4631
  }
4836
- if (!cad.connected)
4837
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4632
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4838
4633
  const code = `(progn
4839
4634
  (vl-load-com)
4840
4635
  (if (tblsearch "UCS" "${escapeLispString(name)}")
@@ -4859,8 +4654,7 @@ async function getCurrentUcs() {
4859
4654
  if (!cad.connected) {
4860
4655
  await cad.connect();
4861
4656
  }
4862
- if (!cad.connected)
4863
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4657
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4864
4658
  const code = `(progn
4865
4659
  (vl-load-com)
4866
4660
  (vla-get-activeutilities (vla-get-document (vla-get-application (vlax-get-acad-object))))
@@ -4877,8 +4671,7 @@ async function createLayout(name) {
4877
4671
  if (!cad.connected) {
4878
4672
  await cad.connect();
4879
4673
  }
4880
- if (!cad.connected)
4881
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4674
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4882
4675
  const code = `(progn
4883
4676
  (vl-load-com)
4884
4677
  (if (not (tblsearch "LAYOUT" "${escapeLispString(name)}"))
@@ -4906,8 +4699,7 @@ async function setLayout(name) {
4906
4699
  if (!cad.connected) {
4907
4700
  await cad.connect();
4908
4701
  }
4909
- if (!cad.connected)
4910
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4702
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4911
4703
  const code = `(progn
4912
4704
  (vl-load-com)
4913
4705
  (vlax-for layout (vla-get-layouts (vla-get-activedocument (vla-get-application (vlax-get-acad-object))))
@@ -4937,8 +4729,7 @@ async function listLayouts() {
4937
4729
  if (!cad.connected) {
4938
4730
  await cad.connect();
4939
4731
  }
4940
- if (!cad.connected)
4941
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4732
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4942
4733
  const code = `(progn
4943
4734
  (vl-load-com)
4944
4735
  (setq layouts nil)
@@ -4961,8 +4752,7 @@ async function deleteLayout(name) {
4961
4752
  if (!cad.connected) {
4962
4753
  await cad.connect();
4963
4754
  }
4964
- if (!cad.connected)
4965
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4755
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4966
4756
  if (name === "Model" || name === "\u6A21\u578B") {
4967
4757
  return { content: [{ type: "text", text: "\u65E0\u6CD5\u5220\u9664\u6A21\u578B\u7A7A\u95F4" }], isError: true };
4968
4758
  }
@@ -4990,8 +4780,7 @@ async function getCurrentLayout() {
4990
4780
  if (!cad.connected) {
4991
4781
  await cad.connect();
4992
4782
  }
4993
- if (!cad.connected)
4994
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4783
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4995
4784
  const code = `(vl-prin1-to-string (getvar "CTAB"))`;
4996
4785
  try {
4997
4786
  const result = await cad.sendCommandWithResult(code);
@@ -5004,8 +4793,7 @@ async function renameLayout(oldName, newName) {
5004
4793
  if (!cad.connected) {
5005
4794
  await cad.connect();
5006
4795
  }
5007
- if (!cad.connected)
5008
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4796
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5009
4797
  const code = `(progn
5010
4798
  (vl-load-com)
5011
4799
  (if (tblsearch "LAYOUT" "${escapeLispString(oldName)}")
@@ -5037,8 +4825,7 @@ async function plotToPdf(outputPath, layout = "Model", style = {}) {
5037
4825
  if (!cad.connected) {
5038
4826
  await cad.connect();
5039
4827
  }
5040
- if (!cad.connected)
5041
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4828
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5042
4829
  const paperSize = style.paperSize || "A4";
5043
4830
  const code = `(progn
5044
4831
  (vl-load-com)
@@ -5068,8 +4855,7 @@ async function plotToPrinter(printerName, layout = "Model") {
5068
4855
  if (!cad.connected) {
5069
4856
  await cad.connect();
5070
4857
  }
5071
- if (!cad.connected)
5072
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4858
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5073
4859
  const code = `(progn
5074
4860
  (vl-load-com)
5075
4861
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
@@ -5095,8 +4881,7 @@ async function createGroup(name, handles) {
5095
4881
  if (!cad.connected) {
5096
4882
  await cad.connect();
5097
4883
  }
5098
- if (!cad.connected)
5099
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4884
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5100
4885
  if (!Array.isArray(handles) || handles.length === 0) {
5101
4886
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
5102
4887
  }
@@ -5122,8 +4907,7 @@ async function deleteGroup(name) {
5122
4907
  if (!cad.connected) {
5123
4908
  await cad.connect();
5124
4909
  }
5125
- if (!cad.connected)
5126
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4910
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5127
4911
  const code = `(progn
5128
4912
  (vl-load-com)
5129
4913
  (if (tblsearch "GROUP" "${escapeLispString(name)}")
@@ -5148,8 +4932,7 @@ async function listGroups() {
5148
4932
  if (!cad.connected) {
5149
4933
  await cad.connect();
5150
4934
  }
5151
- if (!cad.connected)
5152
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4935
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5153
4936
  const code = `(progn
5154
4937
  (vl-load-com)
5155
4938
  (setq groups nil)
@@ -5169,8 +4952,7 @@ async function getGroupEntities(groupName) {
5169
4952
  if (!cad.connected) {
5170
4953
  await cad.connect();
5171
4954
  }
5172
- if (!cad.connected)
5173
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4955
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5174
4956
  const code = `(progn
5175
4957
  (vl-load-com)
5176
4958
  (if (tblsearch "GROUP" "${escapeLispString(groupName)}")
@@ -5208,8 +4990,7 @@ async function measureDistance(p1, p2) {
5208
4990
  if (!cad.connected) {
5209
4991
  await cad.connect();
5210
4992
  }
5211
- if (!cad.connected)
5212
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4993
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5213
4994
  const code = `(progn
5214
4995
  (vl-load-com)
5215
4996
  (setq pt1 (list ${toSafePoint3(p1)}) pt2 (list ${toSafePoint3(p2)}))
@@ -5233,8 +5014,7 @@ async function measureArea(points) {
5233
5014
  if (!cad.connected) {
5234
5015
  await cad.connect();
5235
5016
  }
5236
- if (!cad.connected)
5237
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5017
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5238
5018
  const pts = Array.isArray(points) ? points : points.split(/[\s,]+/).filter(Boolean);
5239
5019
  if (pts.length < 3) {
5240
5020
  return { content: [{ type: "text", text: "\u81F3\u5C11\u9700\u8981 3 \u4E2A\u70B9" }], isError: true };
@@ -5271,8 +5051,7 @@ async function getEntityInfo(handle) {
5271
5051
  if (!cad.connected) {
5272
5052
  await cad.connect();
5273
5053
  }
5274
- if (!cad.connected)
5275
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5054
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5276
5055
  const code = `(progn
5277
5056
  (vl-load-com)
5278
5057
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -5312,8 +5091,7 @@ function parseHandleList(handles) {
5312
5091
  handles = handles.split(",").map((h) => h.trim());
5313
5092
  }
5314
5093
  }
5315
- if (!Array.isArray(handles))
5316
- handles = [handles];
5094
+ if (!Array.isArray(handles)) handles = [handles];
5317
5095
  return handles;
5318
5096
  }
5319
5097
  async function batchRename(handles, newNameTemplate, startNum = 1) {
@@ -5687,8 +5465,7 @@ async function copyXdata(sourceHandle, targetHandle, appName = null) {
5687
5465
  const xdataResult = await getXdata(sourceHandle, appName);
5688
5466
  if (xdataResult.content?.[0]) {
5689
5467
  const parsed = JSON.parse(xdataResult.content[0].text);
5690
- if (parsed.xdata)
5691
- return await setXdata(targetHandle, appName, parsed.xdata);
5468
+ if (parsed.xdata) return await setXdata(targetHandle, appName, parsed.xdata);
5692
5469
  }
5693
5470
  return mcpError("\u6E90\u5B9E\u4F53\u672A\u627E\u5230\u6269\u5C55\u6570\u636E");
5694
5471
  } else {
@@ -5923,10 +5700,8 @@ async function createSheetSetArchive(sheetSetName, archivePath) {
5923
5700
  // src/handlers/3d-handlers.js
5924
5701
  init_cad();
5925
5702
  function parsePoint(point) {
5926
- if (Array.isArray(point))
5927
- return point.join(" ");
5928
- if (typeof point === "string")
5929
- return point;
5703
+ if (Array.isArray(point)) return point.join(" ");
5704
+ if (typeof point === "string") return point;
5930
5705
  return "0,0,0";
5931
5706
  }
5932
5707
  async function createBox(center, length, width, height) {
@@ -8398,8 +8173,7 @@ function validateToolArgs(name, args) {
8398
8173
  const baseType = type.replace("?", "");
8399
8174
  const val = args[key];
8400
8175
  if (val === void 0 || val === null) {
8401
- if (isOptional)
8402
- continue;
8176
+ if (isOptional) continue;
8403
8177
  throw new Error(`Missing required argument: ${key}`);
8404
8178
  }
8405
8179
  const actualType = typeof args[key];
@@ -8444,8 +8218,7 @@ ${CAD_PLATFORMS.join("\n")}
8444
8218
  },
8445
8219
  import_funlib: async (a) => {
8446
8220
  const data = await loadAtlibFunctionLib();
8447
- if (!data)
8448
- return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
8221
+ if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
8449
8222
  if (a.format === "list") {
8450
8223
  const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
8451
8224
  return { content: [{ type: "text", text: items.join("\n") }] };
@@ -8655,8 +8428,7 @@ function notifyResourceChanges(toolName) {
8655
8428
  }
8656
8429
  async function handleToolCall(name, args) {
8657
8430
  const handler = TOOL_HANDLERS[name];
8658
- if (!handler)
8659
- return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8431
+ if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8660
8432
  try {
8661
8433
  validateToolArgs(name, args || {});
8662
8434
  const result = await handler(args || {});
@@ -8717,12 +8489,10 @@ var RateLimiter = class {
8717
8489
  this.keyLimits = /* @__PURE__ */ new Map();
8718
8490
  }
8719
8491
  getKeyLimit(apiKey2) {
8720
- if (!apiKey2)
8721
- return this.defaultLimit;
8492
+ if (!apiKey2) return this.defaultLimit;
8722
8493
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8723
8494
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8724
- if (found)
8725
- return found.limit;
8495
+ if (found) return found.limit;
8726
8496
  }
8727
8497
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8728
8498
  return config_default.apiKeyRateLimit || 1e3;
@@ -8730,12 +8500,10 @@ var RateLimiter = class {
8730
8500
  return this.defaultLimit;
8731
8501
  }
8732
8502
  getKeyInfo(apiKey2) {
8733
- if (!apiKey2)
8734
- return { name: "anonymous", limit: this.defaultLimit };
8503
+ if (!apiKey2) return { name: "anonymous", limit: this.defaultLimit };
8735
8504
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8736
8505
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8737
- if (found)
8738
- return { name: found.name || apiKey2, limit: found.limit };
8506
+ if (found) return { name: found.name || apiKey2, limit: found.limit };
8739
8507
  }
8740
8508
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8741
8509
  return { name: "admin", limit: config_default.apiKeyRateLimit || 1e3 };
@@ -8831,8 +8599,7 @@ var JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "applicati
8831
8599
  function createJsonBodyParser() {
8832
8600
  return async (req, res, next) => {
8833
8601
  const ct = (req.headers["content-type"] || "").toLowerCase();
8834
- if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
8835
- return next();
8602
+ if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
8836
8603
  try {
8837
8604
  const chunks = [];
8838
8605
  for await (const chunk of req) {
@@ -8865,11 +8632,9 @@ function createAuthMiddleware() {
8865
8632
  const PUBLIC_PATHS = ["/health"];
8866
8633
  return (req, res, next) => {
8867
8634
  if (apiKey) {
8868
- if (PUBLIC_PATHS.includes(req.path))
8869
- return next();
8635
+ if (PUBLIC_PATHS.includes(req.path)) return next();
8870
8636
  const auth = req.get("Authorization");
8871
- if (auth === `Bearer ${apiKey}`)
8872
- return next();
8637
+ if (auth === `Bearer ${apiKey}`) return next();
8873
8638
  return res.status(401).json({ error: "Unauthorized" });
8874
8639
  }
8875
8640
  next();
@@ -8877,16 +8642,14 @@ function createAuthMiddleware() {
8877
8642
  }
8878
8643
  function createCorsMiddleware() {
8879
8644
  return (req, res, next) => {
8880
- if (!enableCors)
8881
- return next();
8645
+ if (!enableCors) return next();
8882
8646
  res.setHeader("Access-Control-Allow-Origin", corsOrigin);
8883
8647
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, CONNECT");
8884
8648
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, mcp-session-id, last-event-id");
8885
8649
  res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
8886
8650
  res.setHeader("Access-Control-Max-Age", "86400");
8887
8651
  res.setHeader("Vary", "Accept");
8888
- if (req.method === "OPTIONS")
8889
- return res.status(204).end();
8652
+ if (req.method === "OPTIONS") return res.status(204).end();
8890
8653
  next();
8891
8654
  };
8892
8655
  }
@@ -9303,8 +9066,7 @@ For more info: https://atlisp.cn
9303
9066
  }
9304
9067
  }
9305
9068
  }
9306
- if (config_default.apiKey)
9307
- log("API Key authentication enabled");
9069
+ if (config_default.apiKey) log("API Key authentication enabled");
9308
9070
  async function initCadConnection() {
9309
9071
  log("Attempting to connect to CAD on startup...");
9310
9072
  try {
@@ -9369,10 +9131,8 @@ async function startServer() {
9369
9131
  await cad.disconnect();
9370
9132
  closeLog();
9371
9133
  httpServer.close(() => {
9372
- if (httpsServer)
9373
- httpsServer.close(() => process.exit(0));
9374
- else
9375
- process.exit(0);
9134
+ if (httpsServer) httpsServer.close(() => process.exit(0));
9135
+ else process.exit(0);
9376
9136
  });
9377
9137
  setTimeout(() => process.exit(1), 5e3);
9378
9138
  }