@atlisp/mcp 1.8.1 → 1.8.2

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 +383 -614
  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,92 @@ 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)
1557
+ (defun @br:try (obj prop / r)
1558
+ (if (vl-catch-all-error-p
1559
+ (setq r (vl-catch-all-apply
1560
+ (function (lambda () (vlax-get obj prop))))))
1561
+ nil
1562
+ r))
1563
+
1564
+ (defun @br:get-attrs (ent / att atts)
1565
+ (if (setq att (entnext ent))
1654
1566
  (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)))
1567
+ (setq atts nil)
1568
+ (while (= (cdr (assoc 0 (entget att))) "ATTRIB")
1569
+ (setq atts (cons (cons (cdr (assoc 2 (entget att))) (cdr (assoc 1 (entget att)))) atts))
1570
+ att (entnext att))
1571
+ (reverse atts))
1572
+ nil))
1680
1573
 
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)
1574
+ (defun @br:get-dynprops (obj / r)
1575
+ (setq r (vl-catch-all-apply
1576
+ (function (lambda ()
1577
+ (mapcar '(lambda (x)
1578
+ (cons (vla-get-propertyname x)
1579
+ (list (cons "value" (vlax-get x 'value))
1580
+ (cons "readOnly" (vlax-get x 'readonly))
1581
+ (cons "show" (vlax-get x 'show)))))
1582
+ (vlax-safearray->list (vlax-invoke obj 'getdynamicblockproperties)))))))
1583
+ (if (vl-catch-all-error-p r) nil r))
1584
+
1585
+ (defun @br:props (ent / obj ed r)
1586
+ (setq r (vl-catch-all-apply
1587
+ (function (lambda ()
1588
+ (setq obj (vlax-ename->vla-object ent)
1589
+ ed (entget ent))
1590
+ (list
1591
+ (cons "handle" (cdr (assoc 5 ed)))
1592
+ (cons "layer" (cdr (assoc 8 ed)))
1593
+ (cons "blockName" (vla-get-name obj))
1594
+ (cons "effectiveBlockName" (@br:try obj 'effectivename))
1595
+ (cons "insertionPoint" (vlax-safearray->list (vla-get-insertionpoint obj)))
1596
+ (cons "rotation" (vla-get-rotation obj))
1597
+ (cons "scale" (list (vla-get-xscale obj) (vla-get-yscale obj) (vla-get-zscale obj)))
1598
+ (cons "isDynamic" (@br:try obj 'isdynamicblock))
1599
+ (cons "attributes" (@br:get-attrs ent))
1600
+ (cons "dynamicProperties" (@br:get-dynprops obj)))))))
1601
+ (if (vl-catch-all-error-p r) nil r))
1695
1602
 
1696
- (setq ss (ssget "_X" (list (cons 0 "INSERT") ${filterExpr})))
1603
+ (setq ss (ssget "_X" ${filterCode}))
1697
1604
  (if (null ss)
1698
1605
  (list (cons "total" 0) (cons "blockRefs" nil))
1699
1606
  (progn
1700
1607
  (setq total (sslength ss) i 0 refs nil)
1701
1608
  (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))))))`;
1609
+ (setq r (@br:props (ssname ss i)))
1610
+ (if r (setq refs (cons r refs)))
1611
+ (setq i (1+ i)))
1612
+ (list (cons "total" total) (cons "blockRefs" (list (reverse refs)))))))`;
1704
1613
  }
1705
1614
  async function getBlockRefs(params = {}) {
1706
1615
  const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
1707
1616
  const cached = getCached(cacheKey);
1708
- if (cached)
1709
- return cached;
1710
- if (!cad.connected)
1711
- await cad.connect();
1617
+ if (cached) return cached;
1618
+ if (!cad.connected) await cad.connect();
1712
1619
  if (!cad.connected) {
1713
1620
  return { total: 0, blockRefs: [] };
1714
1621
  }
1715
1622
  try {
1716
1623
  const code = buildBlockRefsCode(params.blockName);
1717
1624
  const resultStr = await cad.sendCommandWithResult(code);
1718
- if (!resultStr || resultStr === "" || resultStr === "nil") {
1719
- return { total: 0, blockRefs: [] };
1720
- }
1721
1625
  const parsed = parseLispRecursive(resultStr);
1722
1626
  if (!parsed || !Array.isArray(parsed)) {
1723
- return { total: 0, blockRefs: [] };
1627
+ throw new Error(`block-refs: \u89E3\u6790 Lisp \u7ED3\u679C\u5931\u8D25: raw="${String(resultStr).substring(0, 500)}"`);
1628
+ }
1629
+ const result = {};
1630
+ for (const pair of parsed) {
1631
+ if (Array.isArray(pair) && pair.length >= 2) {
1632
+ result[String(pair[0])] = pair[1];
1633
+ }
1724
1634
  }
1725
- const result = lispPairsToObject(parsed);
1726
1635
  const blockRefs = Array.isArray(result.blockRefs) ? result.blockRefs : [];
1727
1636
  const finalResult = {
1728
1637
  total: typeof result.total === "number" ? result.total : blockRefs.length,
@@ -1732,7 +1641,7 @@ async function getBlockRefs(params = {}) {
1732
1641
  br.forEach((pair) => {
1733
1642
  if (Array.isArray(pair) && pair.length >= 2) {
1734
1643
  const key = pair[0];
1735
- let val = pair[1];
1644
+ let val = pair.length === 2 ? pair[1] : pair.slice(1);
1736
1645
  if (key === "insertionPoint" && Array.isArray(val)) {
1737
1646
  val = val.map((v) => typeof v === "number" ? v : 0);
1738
1647
  } else if (key === "scale" && Array.isArray(val)) {
@@ -1751,51 +1660,67 @@ async function getBlockRefs(params = {}) {
1751
1660
  return finalResult;
1752
1661
  } catch (e) {
1753
1662
  log(`getBlockRefs error: ${e.message}`);
1754
- return { total: 0, blockRefs: [] };
1663
+ throw e;
1755
1664
  }
1756
1665
  }
1666
+ var VLA_HELPER_LISP = `(defun @:get-props (obj prop-names / result p p-sym val)
1667
+ (setq result nil)
1668
+ (foreach p prop-names
1669
+ (setq p-sym (read p))
1670
+ (if (vlax-property-available-p obj p-sym)
1671
+ (progn
1672
+ (setq val (vl-catch-all-apply 'vlax-get (list obj p-sym)))
1673
+ (if (not (vl-catch-all-error-p val))
1674
+ (progn
1675
+ (cond
1676
+ ((= (type val) 'VLA-OBJECT) (setq val (strcat "@" (vla-get-objectname val))))
1677
+ ((or (= (type val) 'STR) (= (type val) 'SAFEARRAY) (listp val)) (setq val (vl-prin1-to-string val))))
1678
+ (setq result (cons (cons p val) result)))))))
1679
+ (reverse result))`;
1757
1680
  function buildTablesCode(tblName) {
1758
1681
  const raw = tblName.toLowerCase();
1759
1682
  const key = TBL_KEY_ALIAS[raw] || raw;
1760
1683
  const query = TBL_QUERIES[key];
1684
+ const isVlaTable = key !== "layer";
1761
1685
  if (query) {
1686
+ if (isVlaTable) {
1687
+ return `(progn (vl-load-com) ${VLA_HELPER_LISP} ${query.lisp})`;
1688
+ }
1762
1689
  return `(progn (vl-load-com) ${query.lisp})`;
1763
1690
  }
1764
- const parts = Object.values(TBL_QUERIES).map((q) => q.lisp);
1765
- return `(progn (vl-load-com) (list ${parts.join(" ")}))`;
1691
+ const parts = Object.values(TBL_QUERIES).map((q) => `(vl-catch-all-apply '(lambda () ${q.lisp}))`);
1692
+ return `(progn (vl-load-com) ${VLA_HELPER_LISP} (list ${parts.join(" ")}))`;
1766
1693
  }
1767
- function parseTableRecord(rec) {
1768
- if (!rec || !Array.isArray(rec))
1769
- return null;
1694
+ function parseTableRecord(rec, tableName) {
1695
+ if (!rec || !Array.isArray(rec)) return null;
1770
1696
  const obj = {};
1697
+ const isLayer = tableName === "layer";
1771
1698
  for (const pair of rec) {
1772
1699
  if (Array.isArray(pair) && pair.length >= 2) {
1773
1700
  const key = String(pair[0]);
1774
1701
  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;
1702
+ const isDxfCode = typeof pair[0] === "number";
1703
+ if (isDxfCode) {
1704
+ if (key === "2") obj.name = String(val);
1705
+ else if (key === "62") obj.color = typeof val === "number" ? val : 7;
1706
+ else if (key === "6") obj.linetype = String(val);
1707
+ else if (key === "70") {
1708
+ obj.flags = typeof val === "number" ? val : 0;
1709
+ if (isLayer) {
1710
+ obj.frozen = (val & 1) !== 0;
1711
+ obj.locked = (val & 4) !== 0;
1712
+ }
1713
+ } else if (key === "60") obj.on = val === 0;
1714
+ else if (key === "1") obj.font = String(val);
1715
+ else if (key === "40") obj.height = typeof val === "number" ? val : 0;
1716
+ else if (key === "41") obj.width = typeof val === "number" ? val : 1;
1717
+ else if (key === "42") obj.oblique = typeof val === "number" ? val : 0;
1718
+ else if (key === "3") obj.bigfont = String(val);
1719
+ else if (key === "50") obj.flags = typeof val === "number" ? val : 0;
1720
+ } else {
1721
+ if (key === "Name") obj.name = val;
1722
+ obj[key] = val;
1723
+ }
1799
1724
  }
1800
1725
  }
1801
1726
  return obj.name ? obj : null;
@@ -1804,12 +1729,9 @@ async function getTables(params = {}) {
1804
1729
  const tblName = params.tbl || params.type || "all";
1805
1730
  const cacheKey = `dwg:tbl:${tblName}`;
1806
1731
  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: [] };
1732
+ if (cached) return cached;
1733
+ if (!cad.connected) await cad.connect();
1734
+ if (!cad.connected) return { table: tblName, data: [] };
1813
1735
  try {
1814
1736
  const code = buildTablesCode(tblName);
1815
1737
  const resultStr = await cad.sendCommandWithResult(code);
@@ -1828,10 +1750,9 @@ async function getTables(params = {}) {
1828
1750
  for (const item of parsed) {
1829
1751
  if (Array.isArray(item) && item.length >= 2) {
1830
1752
  const key = String(item[0]).toUpperCase();
1831
- if (key === "TOTAL")
1832
- total = typeof item[1] === "number" ? item[1] : 0;
1753
+ if (key === "TOTAL") total = typeof item[1] === "number" ? item[1] : 0;
1833
1754
  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]))) {
1755
+ if (Array.isArray(item[1]) && item[1].length > 0) {
1835
1756
  tblData = item[1];
1836
1757
  }
1837
1758
  }
@@ -1843,46 +1764,41 @@ async function getTables(params = {}) {
1843
1764
  result = {
1844
1765
  table: tableName,
1845
1766
  total,
1846
- data: tblData.map(parseTableRecord).filter(Boolean)
1767
+ data: tblData.map((r) => parseTableRecord(r, tableName)).filter(Boolean)
1847
1768
  };
1848
1769
  } else {
1849
1770
  const allData = {};
1850
1771
  parsed.forEach((item) => {
1851
- if (!Array.isArray(item) || item.length < 2)
1852
- return;
1772
+ if (!Array.isArray(item) || item.length < 2) return;
1853
1773
  let tableKey = null;
1854
1774
  const entry = { total: 0, data: [] };
1855
1775
  if (Array.isArray(item[0]) && item[0].length >= 2 && String(item[0][0]).toLowerCase() === "table") {
1856
1776
  tableKey = String(item[0][1]).toLowerCase();
1857
1777
  for (let i = 1; i < item.length; i++) {
1858
1778
  const sub = item[i];
1859
- if (!Array.isArray(sub) || sub.length < 2)
1860
- continue;
1779
+ if (!Array.isArray(sub) || sub.length < 2) continue;
1861
1780
  const subKey = String(sub[0]).toUpperCase();
1862
- if (subKey === "TOTAL")
1863
- entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1781
+ if (subKey === "TOTAL") entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1864
1782
  else if (subKey === "DATA") {
1865
1783
  const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
1866
- entry.data = raw.map(parseTableRecord).filter(Boolean);
1784
+ entry.data = raw.map((r) => parseTableRecord(r, tableKey)).filter(Boolean);
1867
1785
  }
1868
1786
  }
1869
1787
  } else {
1870
1788
  tableKey = String(item[0]).toLowerCase();
1871
1789
  for (let i = 1; i < item.length; i++) {
1872
1790
  const sub = item[i];
1873
- if (!Array.isArray(sub) || sub.length < 2)
1874
- continue;
1791
+ if (!Array.isArray(sub) || sub.length < 2) continue;
1875
1792
  const subKey = String(sub[0]).toUpperCase();
1876
1793
  if (subKey === "TOTAL") {
1877
1794
  entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1878
1795
  } else if (subKey === "DATA") {
1879
1796
  const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
1880
- entry.data = raw.map(parseTableRecord).filter(Boolean);
1797
+ entry.data = raw.map((r) => parseTableRecord(r, tableKey)).filter(Boolean);
1881
1798
  }
1882
1799
  }
1883
1800
  }
1884
- if (tableKey)
1885
- allData[tableKey] = entry;
1801
+ if (tableKey) allData[tableKey] = entry;
1886
1802
  });
1887
1803
  result = allData;
1888
1804
  }
@@ -1896,12 +1812,9 @@ async function getTables(params = {}) {
1896
1812
  async function getPackages(filterName = null) {
1897
1813
  const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
1898
1814
  const cached = getCached(cacheKey);
1899
- if (cached)
1900
- return cached;
1901
- if (!cad.connected)
1902
- await cad.connect();
1903
- if (!cad.connected)
1904
- return [];
1815
+ if (cached) return cached;
1816
+ if (!cad.connected) await cad.connect();
1817
+ if (!cad.connected) return [];
1905
1818
  try {
1906
1819
  const code = `(mapcar 'cdr @::*local-pkgs*)`;
1907
1820
  const result = await cad.sendCommandWithResult(code);
@@ -1914,8 +1827,7 @@ async function getPackages(filterName = null) {
1914
1827
  } catch {
1915
1828
  raw = parseLispList(result) || [];
1916
1829
  }
1917
- if (!Array.isArray(raw))
1918
- raw = [];
1830
+ if (!Array.isArray(raw)) raw = [];
1919
1831
  const packages = raw.map((item) => {
1920
1832
  if (Array.isArray(item)) {
1921
1833
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
@@ -1924,20 +1836,13 @@ async function getPackages(filterName = null) {
1924
1836
  const [[key, val]] = Object.entries(entry);
1925
1837
  const k = String(key);
1926
1838
  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;
1839
+ if (k === ":NAME") pkg.name = v;
1840
+ else if (k === ":VERSION") pkg.version = v;
1841
+ else if (k === ":DESCRIPTION") pkg.description = v;
1842
+ else if (k === ":FULL-NAME") pkg.fullName = v;
1843
+ else if (k === ":AUTHOR") pkg.author = v;
1844
+ else if (k === ":CATEGORY") pkg.category = v;
1845
+ else if (k === ":URL") pkg.url = v;
1941
1846
  }
1942
1847
  }
1943
1848
  return pkg;
@@ -1948,22 +1853,15 @@ async function getPackages(filterName = null) {
1948
1853
  if (item && typeof item === "object") {
1949
1854
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
1950
1855
  const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
1951
- if (nameVal)
1952
- pkg.name = String(nameVal);
1856
+ if (nameVal) pkg.name = String(nameVal);
1953
1857
  const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
1954
- if (verVal)
1955
- pkg.version = String(verVal);
1858
+ if (verVal) pkg.version = String(verVal);
1956
1859
  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);
1860
+ if (descVal) pkg.description = String(descVal);
1861
+ if (item.fullName || item.full_name) pkg.fullName = String(item.fullName || item.full_name);
1862
+ if (item.author || item.Author) pkg.author = String(item.author || item.Author);
1863
+ if (item.category || item.Category) pkg.category = String(item.category || item.Category);
1864
+ if (item.url || item.Url || item.URL) pkg.url = String(item.url || item.Url || item.URL);
1967
1865
  return pkg;
1968
1866
  }
1969
1867
  return null;
@@ -1988,12 +1886,9 @@ function getPlatforms() {
1988
1886
  async function getDwgList() {
1989
1887
  const cacheKey = "cad:dwgs";
1990
1888
  const cached = getCached(cacheKey);
1991
- if (cached)
1992
- return cached;
1993
- if (!cad.connected)
1994
- await cad.connect();
1995
- if (!cad.connected)
1996
- return [];
1889
+ if (cached) return cached;
1890
+ if (!cad.connected) await cad.connect();
1891
+ if (!cad.connected) return [];
1997
1892
  try {
1998
1893
  const code = `(progn
1999
1894
  (vl-load-com)
@@ -2011,13 +1906,12 @@ async function getDwgList() {
2011
1906
  try {
2012
1907
  parsed = JSON.parse(result);
2013
1908
  } catch (e) {
2014
- const listResult = parseLispList(result);
2015
- if (listResult) {
1909
+ const listResult = parseLispRecursive(result);
1910
+ if (Array.isArray(listResult)) {
2016
1911
  parsed = listResult;
2017
1912
  }
2018
1913
  }
2019
- if (!Array.isArray(parsed))
2020
- parsed = [];
1914
+ if (!Array.isArray(parsed)) parsed = [];
2021
1915
  const dwgList = parsed.map((item) => {
2022
1916
  if (Array.isArray(item) && item.length >= 2) {
2023
1917
  return { name: String(item[0]), path: String(item[1]) };
@@ -2043,8 +1937,7 @@ function loadStandardsFile(filename) {
2043
1937
  var standardsCache = /* @__PURE__ */ new Map();
2044
1938
  function getCachedStandards(key) {
2045
1939
  const entry = standardsCache.get(key);
2046
- if (entry && Date.now() - entry.timestamp < 3e4)
2047
- return entry.data;
1940
+ if (entry && Date.now() - entry.timestamp < 3e4) return entry.data;
2048
1941
  standardsCache.delete(key);
2049
1942
  return null;
2050
1943
  }
@@ -2053,49 +1946,40 @@ function setCachedStandards(key, data) {
2053
1946
  }
2054
1947
  function getDraftingStandards() {
2055
1948
  const cached = getCachedStandards("drafting");
2056
- if (cached)
2057
- return cached;
1949
+ if (cached) return cached;
2058
1950
  const data = loadStandardsFile("drafting.json");
2059
- if (data)
2060
- setCachedStandards("drafting", data);
1951
+ if (data) setCachedStandards("drafting", data);
2061
1952
  return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
2062
1953
  }
2063
1954
  function getCodingStandards() {
2064
1955
  const cached = getCachedStandards("coding");
2065
- if (cached)
2066
- return cached;
1956
+ if (cached) return cached;
2067
1957
  const data = loadStandardsFile("coding.json");
2068
- if (data)
2069
- setCachedStandards("coding", data);
1958
+ if (data) setCachedStandards("coding", data);
2070
1959
  return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
2071
1960
  }
2072
1961
 
2073
1962
  // src/handlers/resource-handlers.js
2074
1963
  function parseQuery(uri) {
2075
1964
  const qIdx = uri.indexOf("?");
2076
- if (qIdx === -1)
2077
- return { base: uri, params: {} };
1965
+ if (qIdx === -1) return { base: uri, params: {} };
2078
1966
  const base = uri.substring(0, qIdx);
2079
1967
  const params = {};
2080
1968
  uri.substring(qIdx + 1).split("&").forEach((p) => {
2081
1969
  const eqIdx = p.indexOf("=");
2082
1970
  const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
2083
1971
  const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
2084
- if (k)
2085
- params[k] = decodeURIComponent(v);
1972
+ if (k) params[k] = decodeURIComponent(v);
2086
1973
  });
2087
1974
  return { base, params };
2088
1975
  }
2089
1976
  function parseTemplateUri(uri) {
2090
1977
  const entityMatch = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
2091
- if (entityMatch)
2092
- return { type: "entity", handle: entityMatch[1] };
1978
+ if (entityMatch) return { type: "entity", handle: entityMatch[1] };
2093
1979
  const tblMatch = uri.match(/^atlisp:\/\/dwg\/tbl\/([^?]+)$/);
2094
- if (tblMatch)
2095
- return { type: "tbl", tblName: tblMatch[1] };
1980
+ if (tblMatch) return { type: "tbl", tblName: tblMatch[1] };
2096
1981
  const blockRefMatch = uri.match(/^atlisp:\/\/dwg\/block-refs\/([^?]+)$/);
2097
- if (blockRefMatch)
2098
- return { type: "block-refs", blockName: blockRefMatch[1] };
1982
+ if (blockRefMatch) return { type: "block-refs", blockName: blockRefMatch[1] };
2099
1983
  return null;
2100
1984
  }
2101
1985
  async function listResources(subscribedUris = []) {
@@ -2255,10 +2139,8 @@ function isPrefixUri(uri) {
2255
2139
  return uri.endsWith("/");
2256
2140
  }
2257
2141
  function matchesSubscription(subscribedUri, targetUri) {
2258
- if (subscribedUri === targetUri)
2259
- return true;
2260
- if (isPrefixUri(subscribedUri) && targetUri.startsWith(subscribedUri))
2261
- return true;
2142
+ if (subscribedUri === targetUri) return true;
2143
+ if (isPrefixUri(subscribedUri) && targetUri.startsWith(subscribedUri)) return true;
2262
2144
  return false;
2263
2145
  }
2264
2146
  function isSubscribed(uri, sessionId) {
@@ -2268,8 +2150,7 @@ function isSubscribed(uri, sessionId) {
2268
2150
  }
2269
2151
  const allUris = sessionManager.getAllSubscribedUris();
2270
2152
  for (const su of allUris) {
2271
- if (matchesSubscription(su, uri))
2272
- return true;
2153
+ if (matchesSubscription(su, uri)) return true;
2273
2154
  }
2274
2155
  return false;
2275
2156
  }
@@ -2378,11 +2259,9 @@ var SseSession = class {
2378
2259
  return lines.join("\n") + "\n\n";
2379
2260
  }
2380
2261
  _setupDrain() {
2381
- if (typeof this.#res.on !== "function")
2382
- return;
2262
+ if (typeof this.#res.on !== "function") return;
2383
2263
  this.#drainHandler = () => {
2384
- if (!this.#active)
2385
- return;
2264
+ if (!this.#active) return;
2386
2265
  if (this.#backpressureBuffer.length > 0) {
2387
2266
  this._drainBuffer();
2388
2267
  }
@@ -2404,8 +2283,7 @@ var SseSession = class {
2404
2283
  }
2405
2284
  }
2406
2285
  _write(content) {
2407
- if (!this.#active)
2408
- return false;
2286
+ if (!this.#active) return false;
2409
2287
  try {
2410
2288
  if (this.#backpressureBuffer.length > 0) {
2411
2289
  this.#backpressureBuffer.push(content);
@@ -2534,8 +2412,7 @@ function persistSessionData(clientId, sessionData) {
2534
2412
  function loadPersistedSessionData(clientId) {
2535
2413
  try {
2536
2414
  const filePath = getSessionStorePath(clientId);
2537
- if (!fs4.existsSync(filePath))
2538
- return null;
2415
+ if (!fs4.existsSync(filePath)) return null;
2539
2416
  const raw = fs4.readFileSync(filePath, "utf-8");
2540
2417
  const store = JSON.parse(raw);
2541
2418
  if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
@@ -2599,8 +2476,7 @@ var SseSessionManager = class {
2599
2476
  session.close();
2600
2477
  this.#sessions.delete(clientId);
2601
2478
  const idx = this.#accessOrder.indexOf(clientId);
2602
- if (idx !== -1)
2603
- this.#accessOrder.splice(idx, 1);
2479
+ if (idx !== -1) this.#accessOrder.splice(idx, 1);
2604
2480
  return true;
2605
2481
  }
2606
2482
  return false;
@@ -2687,8 +2563,7 @@ var SseSessionManager = class {
2687
2563
  session.close();
2688
2564
  this.#sessions.delete(clientId);
2689
2565
  const idx = this.#accessOrder.indexOf(clientId);
2690
- if (idx !== -1)
2691
- this.#accessOrder.splice(idx, 1);
2566
+ if (idx !== -1) this.#accessOrder.splice(idx, 1);
2692
2567
  }
2693
2568
  }
2694
2569
  }
@@ -2736,8 +2611,7 @@ var SessionTransport = class {
2736
2611
  this._started = true;
2737
2612
  }
2738
2613
  async send(message) {
2739
- if (this._closed)
2740
- return;
2614
+ if (this._closed) return;
2741
2615
  if (this._pendingRequest) {
2742
2616
  const { resolve, reject, timeout } = this._pendingRequest;
2743
2617
  clearTimeout(timeout);
@@ -2746,8 +2620,7 @@ var SessionTransport = class {
2746
2620
  }
2747
2621
  }
2748
2622
  async close() {
2749
- if (this._closed)
2750
- return;
2623
+ if (this._closed) return;
2751
2624
  this._closed = true;
2752
2625
  if (this._pendingRequest) {
2753
2626
  const { reject, timeout } = this._pendingRequest;
@@ -2821,12 +2694,10 @@ var DEFS_DIR = path7.join(__dirname3, "definitions");
2821
2694
  var PROMPTS_DIR = path7.join(__dirname3, "..", "..", "prompts");
2822
2695
  var builtinDefs = null;
2823
2696
  function loadBuiltinDefs() {
2824
- if (builtinDefs)
2825
- return builtinDefs;
2697
+ if (builtinDefs) return builtinDefs;
2826
2698
  builtinDefs = {};
2827
2699
  try {
2828
- if (!fs5.existsSync(DEFS_DIR))
2829
- return builtinDefs;
2700
+ if (!fs5.existsSync(DEFS_DIR)) return builtinDefs;
2830
2701
  const files = fs5.readdirSync(DEFS_DIR).filter((f) => f.endsWith(".json"));
2831
2702
  for (const file of files) {
2832
2703
  try {
@@ -2888,15 +2759,12 @@ function formatLispPoints(pointsStr) {
2888
2759
  return `(list ${ptList.join(" ")})`;
2889
2760
  }
2890
2761
  function getDimensionStyleLisp(style) {
2891
- if (style === "horizontal" || style === "vertical")
2892
- return "DIMLINEAR";
2762
+ if (style === "horizontal" || style === "vertical") return "DIMLINEAR";
2893
2763
  return "DIMALIGNED";
2894
2764
  }
2895
2765
  function getDimensionStyleLabel(style) {
2896
- if (style === "horizontal")
2897
- return "\u6C34\u5E73";
2898
- if (style === "vertical")
2899
- return "\u5782\u76F4";
2766
+ if (style === "horizontal") return "\u6C34\u5E73";
2767
+ if (style === "vertical") return "\u5782\u76F4";
2900
2768
  return "aligned";
2901
2769
  }
2902
2770
  async function handleComplexPrompt(def, args) {
@@ -2930,14 +2798,10 @@ async function handleComplexPrompt(def, args) {
2930
2798
  } catch {
2931
2799
  }
2932
2800
  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");
2801
+ if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
2802
+ if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
2803
+ 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");
2804
+ if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
2941
2805
  return {
2942
2806
  messages: [{
2943
2807
  role: "user",
@@ -3130,8 +2994,7 @@ ${code}
3130
2994
  }
3131
2995
  const defs = loadBuiltinDefs();
3132
2996
  const def = defs[name];
3133
- if (!def)
3134
- throw new Error(`Unknown prompt: ${name}`);
2997
+ if (!def) throw new Error(`Unknown prompt: ${name}`);
3135
2998
  if (def.handler) {
3136
2999
  return handleComplexPrompt(def, args);
3137
3000
  }
@@ -3156,8 +3019,7 @@ import path8 from "path";
3156
3019
  init_config();
3157
3020
  var MAX_HISTORY_VALUES = 1e3;
3158
3021
  function percentile(sorted, p) {
3159
- if (sorted.length === 0)
3160
- return 0;
3022
+ if (sorted.length === 0) return 0;
3161
3023
  const idx = Math.ceil(p * sorted.length) - 1;
3162
3024
  return sorted[Math.max(0, Math.min(idx, sorted.length - 1))];
3163
3025
  }
@@ -3448,8 +3310,7 @@ async function evalLisp(code, withResult = false, encoding = null) {
3448
3310
  return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3449
3311
  }
3450
3312
  const trimmed = (code || "").trim();
3451
- if (!trimmed)
3452
- return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3313
+ if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3453
3314
  try {
3454
3315
  if (withResult) {
3455
3316
  const result = await cad.sendCommandWithResult(trimmed, encoding);
@@ -3469,17 +3330,14 @@ async function getCadInfo2() {
3469
3330
  if (!cad.connected) {
3470
3331
  await cad.connect();
3471
3332
  }
3472
- if (!cad.connected)
3473
- return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3333
+ if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3474
3334
  const info = await cad.getInfo();
3475
3335
  return { content: [{ type: "text", text: info }] };
3476
3336
  }
3477
3337
  async function atCommand(command) {
3478
- if (!cad.connected)
3479
- return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3338
+ if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3480
3339
  const trimmed = (command || "").trim();
3481
- if (!trimmed)
3482
- return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3340
+ if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3483
3341
  await cad.sendCommand(trimmed + "\n");
3484
3342
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
3485
3343
  }
@@ -3487,8 +3345,7 @@ async function newDocument() {
3487
3345
  if (!cad.connected) {
3488
3346
  await cad.connect();
3489
3347
  }
3490
- if (!cad.connected)
3491
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3348
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3492
3349
  const result = await cad.newDoc();
3493
3350
  if (result) {
3494
3351
  return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
@@ -3499,8 +3356,7 @@ async function bringToFront() {
3499
3356
  if (!cad.connected) {
3500
3357
  await cad.connect();
3501
3358
  }
3502
- if (!cad.connected)
3503
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3359
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3504
3360
  const result = await cad.bringToFront();
3505
3361
  if (result) {
3506
3362
  return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
@@ -3511,8 +3367,7 @@ async function installAtlisp() {
3511
3367
  if (!cad.connected) {
3512
3368
  await cad.connect();
3513
3369
  }
3514
- if (!cad.connected)
3515
- 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 };
3516
3371
  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
3372
  await cad.sendCommand(installCode + "\n");
3518
3373
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
@@ -3521,12 +3376,10 @@ async function listFunctionsInCad() {
3521
3376
  if (!cad.connected) {
3522
3377
  await cad.connect();
3523
3378
  }
3524
- if (!cad.connected)
3525
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3379
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3526
3380
  try {
3527
3381
  const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
3528
- if (result)
3529
- return { content: [{ type: "text", text: result }] };
3382
+ if (result) return { content: [{ type: "text", text: result }] };
3530
3383
  return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
3531
3384
  } catch (e) {
3532
3385
  return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
@@ -3583,8 +3436,7 @@ async function initAtlisp() {
3583
3436
  if (!cad.connected) {
3584
3437
  await cad.connect();
3585
3438
  }
3586
- if (!cad.connected)
3587
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3439
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3588
3440
  const code = `(if (null @::load-module)
3589
3441
  (progn
3590
3442
  (vl-load-com)
@@ -3626,15 +3478,12 @@ async function fetchPackages() {
3626
3478
  return cachedPackages || MOCK_PACKAGES;
3627
3479
  }
3628
3480
  function flattenPackages(data) {
3629
- if (Array.isArray(data))
3630
- return data;
3631
- if (data && Array.isArray(data.packages))
3632
- return data.packages;
3481
+ if (Array.isArray(data)) return data;
3482
+ if (data && Array.isArray(data.packages)) return data.packages;
3633
3483
  return [];
3634
3484
  }
3635
3485
  async function listPackages() {
3636
- if (!cad.connected)
3637
- await cad.connect();
3486
+ if (!cad.connected) await cad.connect();
3638
3487
  if (!cad.connected) {
3639
3488
  const data2 = await fetchPackages();
3640
3489
  const items2 = flattenPackages(data2);
@@ -3642,8 +3491,7 @@ async function listPackages() {
3642
3491
  return { content: [{ type: "text", text: text2 }] };
3643
3492
  }
3644
3493
  const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
3645
- if (result && result !== "nil")
3646
- return { content: [{ type: "text", text: result }] };
3494
+ if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
3647
3495
  const data = await fetchPackages();
3648
3496
  const items = flattenPackages(data);
3649
3497
  const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
@@ -3663,12 +3511,10 @@ async function searchPackages(query) {
3663
3511
  for (const p of items) {
3664
3512
  const name = (p.name || "").toLowerCase();
3665
3513
  const desc = (p.description || "").toLowerCase();
3666
- if (name.includes(q) || desc.includes(q))
3667
- results.push(p);
3514
+ if (name.includes(q) || desc.includes(q)) results.push(p);
3668
3515
  }
3669
3516
  } else {
3670
- for (const p of items)
3671
- results.push(p);
3517
+ for (const p of items) results.push(p);
3672
3518
  }
3673
3519
  if (results.length === 0) {
3674
3520
  return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
@@ -3757,8 +3603,7 @@ async function getFunctionUsage(funcName, packageName) {
3757
3603
  if (data) {
3758
3604
  const funcs = Object.values(data.all_functions || {});
3759
3605
  const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
3760
- if (func)
3761
- results.push(func);
3606
+ if (func) results.push(func);
3762
3607
  }
3763
3608
  if (results.length === 0 && FUNCTIONS_DIR) {
3764
3609
  try {
@@ -3767,8 +3612,7 @@ async function getFunctionUsage(funcName, packageName) {
3767
3612
  const raw = fs6.readFileSync(path9.join(FUNCTIONS_DIR, file), "utf-8");
3768
3613
  const data2 = JSON.parse(raw);
3769
3614
  const func = data2.functions?.find((f2) => f2.name === funcName);
3770
- if (func)
3771
- results.push(func);
3615
+ if (func) results.push(func);
3772
3616
  }
3773
3617
  } catch (e) {
3774
3618
  log(`function-handlers: FUNCTIONS_DIR read error: ${e.message}`);
@@ -3838,8 +3682,7 @@ async function getEntity(handle) {
3838
3682
  if (!cad.connected) {
3839
3683
  await cad.connect();
3840
3684
  }
3841
- if (!cad.connected)
3842
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3685
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3843
3686
  const code = `(progn
3844
3687
  (vl-load-com)
3845
3688
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -3871,8 +3714,7 @@ async function setEntityProperty(handle, property, value) {
3871
3714
  if (!cad.connected) {
3872
3715
  await cad.connect();
3873
3716
  }
3874
- if (!cad.connected)
3875
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3717
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3876
3718
  let propCode = "";
3877
3719
  switch (property) {
3878
3720
  case "layer":
@@ -3915,8 +3757,7 @@ async function deleteEntity(handle) {
3915
3757
  if (!cad.connected) {
3916
3758
  await cad.connect();
3917
3759
  }
3918
- if (!cad.connected)
3919
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3760
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3920
3761
  const code = `(progn
3921
3762
  (vl-load-com)
3922
3763
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -3941,15 +3782,12 @@ async function selectEntities(filter) {
3941
3782
  if (!cad.connected) {
3942
3783
  await cad.connect();
3943
3784
  }
3944
- if (!cad.connected)
3945
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3785
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3946
3786
  let filterCode = "nil";
3947
3787
  if (filter && (filter.type || filter.layer)) {
3948
3788
  const items = [];
3949
- if (filter.type)
3950
- items.push(`'(0 . "${escapeLispString(filter.type)}")`);
3951
- if (filter.layer)
3952
- items.push(`'(8 . "${escapeLispString(filter.layer)}")`);
3789
+ if (filter.type) items.push(`'(0 . "${escapeLispString(filter.type)}")`);
3790
+ if (filter.layer) items.push(`'(8 . "${escapeLispString(filter.layer)}")`);
3953
3791
  filterCode = `(list ${items.join(" ")})`;
3954
3792
  }
3955
3793
  const code = `(progn
@@ -3982,8 +3820,7 @@ async function createLayer(name, color = 7, linetype = "Continuous") {
3982
3820
  if (!cad.connected) {
3983
3821
  await cad.connect();
3984
3822
  }
3985
- if (!cad.connected)
3986
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3823
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3987
3824
  const code = `(progn
3988
3825
  (vl-load-com)
3989
3826
  (if (not (tblsearch "LAYER" "${escapeLispString(name)}"))
@@ -4019,8 +3856,7 @@ async function deleteLayer(name) {
4019
3856
  if (!cad.connected) {
4020
3857
  await cad.connect();
4021
3858
  }
4022
- if (!cad.connected)
4023
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3859
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4024
3860
  const code = `(progn
4025
3861
  (vl-load-com)
4026
3862
  (cond
@@ -4054,8 +3890,7 @@ async function setLayerProperty(name, property, value) {
4054
3890
  if (!cad.connected) {
4055
3891
  await cad.connect();
4056
3892
  }
4057
- if (!cad.connected)
4058
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3893
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4059
3894
  let propCode = "";
4060
3895
  switch (property) {
4061
3896
  case "color":
@@ -4103,8 +3938,7 @@ async function setCurrentLayer(name) {
4103
3938
  if (!cad.connected) {
4104
3939
  await cad.connect();
4105
3940
  }
4106
- if (!cad.connected)
4107
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3941
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4108
3942
  const code = `(progn
4109
3943
  (vl-load-com)
4110
3944
  (if (tblsearch "LAYER" "${escapeLispString(name)}")
@@ -4132,8 +3966,7 @@ async function createBlock(name, entities) {
4132
3966
  if (!cad.connected) {
4133
3967
  await cad.connect();
4134
3968
  }
4135
- if (!cad.connected)
4136
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3969
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4137
3970
  const code = `(progn
4138
3971
  (vl-load-com)
4139
3972
  (if (not (tblsearch "BLOCK" "${escapeLispString(name)}"))
@@ -4170,8 +4003,7 @@ async function insertBlock(blockName, point, scale = 1, rotation = 0) {
4170
4003
  if (!cad.connected) {
4171
4004
  await cad.connect();
4172
4005
  }
4173
- if (!cad.connected)
4174
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4006
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4175
4007
  const coords = Array.isArray(point) ? point : point.split(",").map((s) => parseFloat(s.trim()));
4176
4008
  if (coords.length < 2) {
4177
4009
  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 +4033,7 @@ async function getBlocks() {
4201
4033
  if (!cad.connected) {
4202
4034
  await cad.connect();
4203
4035
  }
4204
- if (!cad.connected)
4205
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4036
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4206
4037
  const code = `(progn
4207
4038
  (vl-load-com)
4208
4039
  (setq blocks nil)
@@ -4225,8 +4056,7 @@ async function explodeBlock(handle) {
4225
4056
  if (!cad.connected) {
4226
4057
  await cad.connect();
4227
4058
  }
4228
- if (!cad.connected)
4229
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4059
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4230
4060
  const code = `(progn
4231
4061
  (vl-load-com)
4232
4062
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -4262,8 +4092,7 @@ async function openDwg(filePath) {
4262
4092
  if (!cad.connected) {
4263
4093
  await cad.connect();
4264
4094
  }
4265
- if (!cad.connected)
4266
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4095
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4267
4096
  try {
4268
4097
  validateFilePath(filePath);
4269
4098
  } catch (e) {
@@ -4304,8 +4133,7 @@ async function saveDwg(filePath = null) {
4304
4133
  if (!cad.connected) {
4305
4134
  await cad.connect();
4306
4135
  }
4307
- if (!cad.connected)
4308
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4136
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4309
4137
  if (filePath) {
4310
4138
  try {
4311
4139
  validateFilePath(filePath);
@@ -4336,8 +4164,7 @@ async function exportPdf(outputPath, layout = "Model") {
4336
4164
  if (!cad.connected) {
4337
4165
  await cad.connect();
4338
4166
  }
4339
- if (!cad.connected)
4340
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4167
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4341
4168
  try {
4342
4169
  validateFilePath(outputPath);
4343
4170
  } catch (e) {
@@ -4369,8 +4196,7 @@ async function closeDwg(save = false) {
4369
4196
  if (!cad.connected) {
4370
4197
  await cad.connect();
4371
4198
  }
4372
- if (!cad.connected)
4373
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4199
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4374
4200
  const code = `(progn
4375
4201
  (vl-load-com)
4376
4202
  (if ${save ? "T" : "nil"}
@@ -4397,8 +4223,7 @@ async function createDimension(type, points, style = {}) {
4397
4223
  if (!cad.connected) {
4398
4224
  await cad.connect();
4399
4225
  }
4400
- if (!cad.connected)
4401
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4226
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4402
4227
  let dimCode = "";
4403
4228
  const validTypes = ["ALIGNED", "LINEAR", "ORDINATE", "RADIAL", "DIAMETER", "ANGULAR"];
4404
4229
  const dimType = (type || "ALIGNED").toUpperCase();
@@ -4440,8 +4265,7 @@ async function getDimensionValue(handle) {
4440
4265
  if (!cad.connected) {
4441
4266
  await cad.connect();
4442
4267
  }
4443
- if (!cad.connected)
4444
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4268
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4445
4269
  const code = `(progn
4446
4270
  (vl-load-com)
4447
4271
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -4472,8 +4296,7 @@ async function createHatch(patternName, boundary, scale = 1, angle = 0) {
4472
4296
  if (!cad.connected) {
4473
4297
  await cad.connect();
4474
4298
  }
4475
- if (!cad.connected)
4476
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4299
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4477
4300
  const code = `(progn
4478
4301
  (vl-load-com)
4479
4302
  (command "._BHATCH" "p" "${escapeLispString(patternName)}" "s" "s" "sc" ${scale} "an" ${angle} "")
@@ -4493,17 +4316,12 @@ async function setHatchProperties(handle, props) {
4493
4316
  if (!cad.connected) {
4494
4317
  await cad.connect();
4495
4318
  }
4496
- if (!cad.connected)
4497
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4319
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4498
4320
  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})`;
4321
+ if (props.pattern) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "p" "${escapeLispString(props.pattern)}")`;
4322
+ if (props.scale) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "s" ${parseFloat(props.scale) || 1})`;
4323
+ if (props.angle) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "an" ${parseFloat(props.angle) || 0})`;
4324
+ if (props.color) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "c" ${parseInt(props.color) || 256})`;
4507
4325
  const code = `(progn
4508
4326
  (vl-load-com)
4509
4327
  ${propCode}
@@ -4520,8 +4338,7 @@ async function getBlockAttributes(blockHandle) {
4520
4338
  if (!cad.connected) {
4521
4339
  await cad.connect();
4522
4340
  }
4523
- if (!cad.connected)
4524
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4341
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4525
4342
  const code = `(progn
4526
4343
  (vl-load-com)
4527
4344
  (if (setq ent (handent "${escapeLispString(blockHandle)}"))
@@ -4550,8 +4367,7 @@ async function setBlockAttribute(blockHandle, tag, value) {
4550
4367
  if (!cad.connected) {
4551
4368
  await cad.connect();
4552
4369
  }
4553
- if (!cad.connected)
4554
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4370
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4555
4371
  const code = `(progn
4556
4372
  (vl-load-com)
4557
4373
  (if (setq ent (handent "${escapeLispString(blockHandle)}"))
@@ -4587,8 +4403,7 @@ async function zoomToExtents() {
4587
4403
  if (!cad.connected) {
4588
4404
  await cad.connect();
4589
4405
  }
4590
- if (!cad.connected)
4591
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4406
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4592
4407
  const code = `(progn
4593
4408
  (vl-load-com)
4594
4409
  (command "._ZOOM" "E")
@@ -4605,8 +4420,7 @@ async function zoomToWindow(p1, p2) {
4605
4420
  if (!cad.connected) {
4606
4421
  await cad.connect();
4607
4422
  }
4608
- if (!cad.connected)
4609
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4423
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4610
4424
  const code = `(command "._ZOOM" "W" (list ${toSafePoint(p1)}) (list ${toSafePoint(p2)}))`;
4611
4425
  try {
4612
4426
  await cad.sendCommand(code + "\n");
@@ -4619,8 +4433,7 @@ async function createNamedView(viewName, center = null) {
4619
4433
  if (!cad.connected) {
4620
4434
  await cad.connect();
4621
4435
  }
4622
- if (!cad.connected)
4623
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4436
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4624
4437
  const code = center ? `(command ".-VIEW" "S" "${escapeLispString(viewName)}" "C" (list ${toSafePoint(center)}))` : `(command ".-VIEW" "S" "${escapeLispString(viewName)}")`;
4625
4438
  try {
4626
4439
  await cad.sendCommand(code + "\n");
@@ -4633,8 +4446,7 @@ async function restoreNamedView(viewName) {
4633
4446
  if (!cad.connected) {
4634
4447
  await cad.connect();
4635
4448
  }
4636
- if (!cad.connected)
4637
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4449
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4638
4450
  const code = `(command ".-VIEW" "R" "${escapeLispString(viewName)}")`;
4639
4451
  try {
4640
4452
  await cad.sendCommand(code + "\n");
@@ -4647,8 +4459,7 @@ async function listNamedViews() {
4647
4459
  if (!cad.connected) {
4648
4460
  await cad.connect();
4649
4461
  }
4650
- if (!cad.connected)
4651
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4462
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4652
4463
  const code = `(progn
4653
4464
  (vl-load-com)
4654
4465
  (setq views nil)
@@ -4668,8 +4479,7 @@ async function exportDxf(outputPath, version2 = "R2018") {
4668
4479
  if (!cad.connected) {
4669
4480
  await cad.connect();
4670
4481
  }
4671
- if (!cad.connected)
4672
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4482
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4673
4483
  const versionMap = {
4674
4484
  "R2018": "AC1027",
4675
4485
  "R2015": "AC1024",
@@ -4699,8 +4509,7 @@ async function exportDwf(outputPath) {
4699
4509
  if (!cad.connected) {
4700
4510
  await cad.connect();
4701
4511
  }
4702
- if (!cad.connected)
4703
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4512
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4704
4513
  const code = `(progn
4705
4514
  (vl-load-com)
4706
4515
  (vla-export (vla-get-activedocument (vlax-get-acad-object)) "${escapeLispString(outputPath)}" "dwf")
@@ -4720,8 +4529,7 @@ async function batchSetLayer(handles, layerName) {
4720
4529
  if (!cad.connected) {
4721
4530
  await cad.connect();
4722
4531
  }
4723
- if (!cad.connected)
4724
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4532
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4725
4533
  if (!Array.isArray(handles) || handles.length === 0) {
4726
4534
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
4727
4535
  }
@@ -4751,8 +4559,7 @@ async function createUcs(name, origin = "0,0,0", xAxis = "1,0,0", yAxis = "0,1,0
4751
4559
  if (!cad.connected) {
4752
4560
  await cad.connect();
4753
4561
  }
4754
- if (!cad.connected)
4755
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4562
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4756
4563
  const code = `(progn
4757
4564
  (vl-load-com)
4758
4565
  (if (not (tblsearch "UCS" "${escapeLispString(name)}"))
@@ -4783,8 +4590,7 @@ async function setUcs(name) {
4783
4590
  if (!cad.connected) {
4784
4591
  await cad.connect();
4785
4592
  }
4786
- if (!cad.connected)
4787
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4593
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4788
4594
  const code = `(progn
4789
4595
  (vl-load-com)
4790
4596
  (if (tblsearch "UCS" "${escapeLispString(name)}")
@@ -4809,8 +4615,7 @@ async function listUcs() {
4809
4615
  if (!cad.connected) {
4810
4616
  await cad.connect();
4811
4617
  }
4812
- if (!cad.connected)
4813
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4618
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4814
4619
  const code = `(progn
4815
4620
  (vl-load-com)
4816
4621
  (setq ucsList nil)
@@ -4833,8 +4638,7 @@ async function deleteUcs(name) {
4833
4638
  if (!cad.connected) {
4834
4639
  await cad.connect();
4835
4640
  }
4836
- if (!cad.connected)
4837
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4641
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4838
4642
  const code = `(progn
4839
4643
  (vl-load-com)
4840
4644
  (if (tblsearch "UCS" "${escapeLispString(name)}")
@@ -4859,8 +4663,7 @@ async function getCurrentUcs() {
4859
4663
  if (!cad.connected) {
4860
4664
  await cad.connect();
4861
4665
  }
4862
- if (!cad.connected)
4863
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4666
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4864
4667
  const code = `(progn
4865
4668
  (vl-load-com)
4866
4669
  (vla-get-activeutilities (vla-get-document (vla-get-application (vlax-get-acad-object))))
@@ -4877,8 +4680,7 @@ async function createLayout(name) {
4877
4680
  if (!cad.connected) {
4878
4681
  await cad.connect();
4879
4682
  }
4880
- if (!cad.connected)
4881
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4683
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4882
4684
  const code = `(progn
4883
4685
  (vl-load-com)
4884
4686
  (if (not (tblsearch "LAYOUT" "${escapeLispString(name)}"))
@@ -4906,8 +4708,7 @@ async function setLayout(name) {
4906
4708
  if (!cad.connected) {
4907
4709
  await cad.connect();
4908
4710
  }
4909
- if (!cad.connected)
4910
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4711
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4911
4712
  const code = `(progn
4912
4713
  (vl-load-com)
4913
4714
  (vlax-for layout (vla-get-layouts (vla-get-activedocument (vla-get-application (vlax-get-acad-object))))
@@ -4937,8 +4738,7 @@ async function listLayouts() {
4937
4738
  if (!cad.connected) {
4938
4739
  await cad.connect();
4939
4740
  }
4940
- if (!cad.connected)
4941
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4741
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4942
4742
  const code = `(progn
4943
4743
  (vl-load-com)
4944
4744
  (setq layouts nil)
@@ -4961,8 +4761,7 @@ async function deleteLayout(name) {
4961
4761
  if (!cad.connected) {
4962
4762
  await cad.connect();
4963
4763
  }
4964
- if (!cad.connected)
4965
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4764
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4966
4765
  if (name === "Model" || name === "\u6A21\u578B") {
4967
4766
  return { content: [{ type: "text", text: "\u65E0\u6CD5\u5220\u9664\u6A21\u578B\u7A7A\u95F4" }], isError: true };
4968
4767
  }
@@ -4990,8 +4789,7 @@ async function getCurrentLayout() {
4990
4789
  if (!cad.connected) {
4991
4790
  await cad.connect();
4992
4791
  }
4993
- if (!cad.connected)
4994
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4792
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4995
4793
  const code = `(vl-prin1-to-string (getvar "CTAB"))`;
4996
4794
  try {
4997
4795
  const result = await cad.sendCommandWithResult(code);
@@ -5004,8 +4802,7 @@ async function renameLayout(oldName, newName) {
5004
4802
  if (!cad.connected) {
5005
4803
  await cad.connect();
5006
4804
  }
5007
- if (!cad.connected)
5008
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4805
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5009
4806
  const code = `(progn
5010
4807
  (vl-load-com)
5011
4808
  (if (tblsearch "LAYOUT" "${escapeLispString(oldName)}")
@@ -5037,8 +4834,7 @@ async function plotToPdf(outputPath, layout = "Model", style = {}) {
5037
4834
  if (!cad.connected) {
5038
4835
  await cad.connect();
5039
4836
  }
5040
- if (!cad.connected)
5041
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4837
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5042
4838
  const paperSize = style.paperSize || "A4";
5043
4839
  const code = `(progn
5044
4840
  (vl-load-com)
@@ -5068,8 +4864,7 @@ async function plotToPrinter(printerName, layout = "Model") {
5068
4864
  if (!cad.connected) {
5069
4865
  await cad.connect();
5070
4866
  }
5071
- if (!cad.connected)
5072
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4867
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5073
4868
  const code = `(progn
5074
4869
  (vl-load-com)
5075
4870
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
@@ -5095,8 +4890,7 @@ async function createGroup(name, handles) {
5095
4890
  if (!cad.connected) {
5096
4891
  await cad.connect();
5097
4892
  }
5098
- if (!cad.connected)
5099
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4893
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5100
4894
  if (!Array.isArray(handles) || handles.length === 0) {
5101
4895
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
5102
4896
  }
@@ -5122,8 +4916,7 @@ async function deleteGroup(name) {
5122
4916
  if (!cad.connected) {
5123
4917
  await cad.connect();
5124
4918
  }
5125
- if (!cad.connected)
5126
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4919
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5127
4920
  const code = `(progn
5128
4921
  (vl-load-com)
5129
4922
  (if (tblsearch "GROUP" "${escapeLispString(name)}")
@@ -5148,8 +4941,7 @@ async function listGroups() {
5148
4941
  if (!cad.connected) {
5149
4942
  await cad.connect();
5150
4943
  }
5151
- if (!cad.connected)
5152
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4944
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5153
4945
  const code = `(progn
5154
4946
  (vl-load-com)
5155
4947
  (setq groups nil)
@@ -5169,8 +4961,7 @@ async function getGroupEntities(groupName) {
5169
4961
  if (!cad.connected) {
5170
4962
  await cad.connect();
5171
4963
  }
5172
- if (!cad.connected)
5173
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4964
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5174
4965
  const code = `(progn
5175
4966
  (vl-load-com)
5176
4967
  (if (tblsearch "GROUP" "${escapeLispString(groupName)}")
@@ -5208,8 +4999,7 @@ async function measureDistance(p1, p2) {
5208
4999
  if (!cad.connected) {
5209
5000
  await cad.connect();
5210
5001
  }
5211
- if (!cad.connected)
5212
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5002
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5213
5003
  const code = `(progn
5214
5004
  (vl-load-com)
5215
5005
  (setq pt1 (list ${toSafePoint3(p1)}) pt2 (list ${toSafePoint3(p2)}))
@@ -5233,8 +5023,7 @@ async function measureArea(points) {
5233
5023
  if (!cad.connected) {
5234
5024
  await cad.connect();
5235
5025
  }
5236
- if (!cad.connected)
5237
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5026
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5238
5027
  const pts = Array.isArray(points) ? points : points.split(/[\s,]+/).filter(Boolean);
5239
5028
  if (pts.length < 3) {
5240
5029
  return { content: [{ type: "text", text: "\u81F3\u5C11\u9700\u8981 3 \u4E2A\u70B9" }], isError: true };
@@ -5271,8 +5060,7 @@ async function getEntityInfo(handle) {
5271
5060
  if (!cad.connected) {
5272
5061
  await cad.connect();
5273
5062
  }
5274
- if (!cad.connected)
5275
- return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5063
+ if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5276
5064
  const code = `(progn
5277
5065
  (vl-load-com)
5278
5066
  (if (setq ent (handent "${escapeLispString(handle)}"))
@@ -5312,8 +5100,7 @@ function parseHandleList(handles) {
5312
5100
  handles = handles.split(",").map((h) => h.trim());
5313
5101
  }
5314
5102
  }
5315
- if (!Array.isArray(handles))
5316
- handles = [handles];
5103
+ if (!Array.isArray(handles)) handles = [handles];
5317
5104
  return handles;
5318
5105
  }
5319
5106
  async function batchRename(handles, newNameTemplate, startNum = 1) {
@@ -5687,8 +5474,7 @@ async function copyXdata(sourceHandle, targetHandle, appName = null) {
5687
5474
  const xdataResult = await getXdata(sourceHandle, appName);
5688
5475
  if (xdataResult.content?.[0]) {
5689
5476
  const parsed = JSON.parse(xdataResult.content[0].text);
5690
- if (parsed.xdata)
5691
- return await setXdata(targetHandle, appName, parsed.xdata);
5477
+ if (parsed.xdata) return await setXdata(targetHandle, appName, parsed.xdata);
5692
5478
  }
5693
5479
  return mcpError("\u6E90\u5B9E\u4F53\u672A\u627E\u5230\u6269\u5C55\u6570\u636E");
5694
5480
  } else {
@@ -5923,10 +5709,8 @@ async function createSheetSetArchive(sheetSetName, archivePath) {
5923
5709
  // src/handlers/3d-handlers.js
5924
5710
  init_cad();
5925
5711
  function parsePoint(point) {
5926
- if (Array.isArray(point))
5927
- return point.join(" ");
5928
- if (typeof point === "string")
5929
- return point;
5712
+ if (Array.isArray(point)) return point.join(" ");
5713
+ if (typeof point === "string") return point;
5930
5714
  return "0,0,0";
5931
5715
  }
5932
5716
  async function createBox(center, length, width, height) {
@@ -8398,8 +8182,7 @@ function validateToolArgs(name, args) {
8398
8182
  const baseType = type.replace("?", "");
8399
8183
  const val = args[key];
8400
8184
  if (val === void 0 || val === null) {
8401
- if (isOptional)
8402
- continue;
8185
+ if (isOptional) continue;
8403
8186
  throw new Error(`Missing required argument: ${key}`);
8404
8187
  }
8405
8188
  const actualType = typeof args[key];
@@ -8444,8 +8227,7 @@ ${CAD_PLATFORMS.join("\n")}
8444
8227
  },
8445
8228
  import_funlib: async (a) => {
8446
8229
  const data = await loadAtlibFunctionLib();
8447
- if (!data)
8448
- return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
8230
+ if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
8449
8231
  if (a.format === "list") {
8450
8232
  const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
8451
8233
  return { content: [{ type: "text", text: items.join("\n") }] };
@@ -8655,8 +8437,7 @@ function notifyResourceChanges(toolName) {
8655
8437
  }
8656
8438
  async function handleToolCall(name, args) {
8657
8439
  const handler = TOOL_HANDLERS[name];
8658
- if (!handler)
8659
- return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8440
+ if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8660
8441
  try {
8661
8442
  validateToolArgs(name, args || {});
8662
8443
  const result = await handler(args || {});
@@ -8717,12 +8498,10 @@ var RateLimiter = class {
8717
8498
  this.keyLimits = /* @__PURE__ */ new Map();
8718
8499
  }
8719
8500
  getKeyLimit(apiKey2) {
8720
- if (!apiKey2)
8721
- return this.defaultLimit;
8501
+ if (!apiKey2) return this.defaultLimit;
8722
8502
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8723
8503
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8724
- if (found)
8725
- return found.limit;
8504
+ if (found) return found.limit;
8726
8505
  }
8727
8506
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8728
8507
  return config_default.apiKeyRateLimit || 1e3;
@@ -8730,12 +8509,10 @@ var RateLimiter = class {
8730
8509
  return this.defaultLimit;
8731
8510
  }
8732
8511
  getKeyInfo(apiKey2) {
8733
- if (!apiKey2)
8734
- return { name: "anonymous", limit: this.defaultLimit };
8512
+ if (!apiKey2) return { name: "anonymous", limit: this.defaultLimit };
8735
8513
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8736
8514
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8737
- if (found)
8738
- return { name: found.name || apiKey2, limit: found.limit };
8515
+ if (found) return { name: found.name || apiKey2, limit: found.limit };
8739
8516
  }
8740
8517
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8741
8518
  return { name: "admin", limit: config_default.apiKeyRateLimit || 1e3 };
@@ -8831,8 +8608,7 @@ var JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "applicati
8831
8608
  function createJsonBodyParser() {
8832
8609
  return async (req, res, next) => {
8833
8610
  const ct = (req.headers["content-type"] || "").toLowerCase();
8834
- if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
8835
- return next();
8611
+ if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
8836
8612
  try {
8837
8613
  const chunks = [];
8838
8614
  for await (const chunk of req) {
@@ -8865,11 +8641,9 @@ function createAuthMiddleware() {
8865
8641
  const PUBLIC_PATHS = ["/health"];
8866
8642
  return (req, res, next) => {
8867
8643
  if (apiKey) {
8868
- if (PUBLIC_PATHS.includes(req.path))
8869
- return next();
8644
+ if (PUBLIC_PATHS.includes(req.path)) return next();
8870
8645
  const auth = req.get("Authorization");
8871
- if (auth === `Bearer ${apiKey}`)
8872
- return next();
8646
+ if (auth === `Bearer ${apiKey}`) return next();
8873
8647
  return res.status(401).json({ error: "Unauthorized" });
8874
8648
  }
8875
8649
  next();
@@ -8877,16 +8651,14 @@ function createAuthMiddleware() {
8877
8651
  }
8878
8652
  function createCorsMiddleware() {
8879
8653
  return (req, res, next) => {
8880
- if (!enableCors)
8881
- return next();
8654
+ if (!enableCors) return next();
8882
8655
  res.setHeader("Access-Control-Allow-Origin", corsOrigin);
8883
8656
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, CONNECT");
8884
8657
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, mcp-session-id, last-event-id");
8885
8658
  res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
8886
8659
  res.setHeader("Access-Control-Max-Age", "86400");
8887
8660
  res.setHeader("Vary", "Accept");
8888
- if (req.method === "OPTIONS")
8889
- return res.status(204).end();
8661
+ if (req.method === "OPTIONS") return res.status(204).end();
8890
8662
  next();
8891
8663
  };
8892
8664
  }
@@ -9303,8 +9075,7 @@ For more info: https://atlisp.cn
9303
9075
  }
9304
9076
  }
9305
9077
  }
9306
- if (config_default.apiKey)
9307
- log("API Key authentication enabled");
9078
+ if (config_default.apiKey) log("API Key authentication enabled");
9308
9079
  async function initCadConnection() {
9309
9080
  log("Attempting to connect to CAD on startup...");
9310
9081
  try {
@@ -9369,10 +9140,8 @@ async function startServer() {
9369
9140
  await cad.disconnect();
9370
9141
  closeLog();
9371
9142
  httpServer.close(() => {
9372
- if (httpsServer)
9373
- httpsServer.close(() => process.exit(0));
9374
- else
9375
- process.exit(0);
9143
+ if (httpsServer) httpsServer.close(() => process.exit(0));
9144
+ else process.exit(0);
9376
9145
  });
9377
9146
  setTimeout(() => process.exit(1), 5e3);
9378
9147
  }