@atlisp/mcp 1.6.9 → 1.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@
2
2
 
3
3
  // src/atlisp-mcp.js
4
4
  import path10 from "path";
5
+ import fs8 from "fs";
5
6
  import { fileURLToPath as fileURLToPath4 } from "url";
6
7
  import { createRequire } from "module";
7
8
  import express2 from "express";
@@ -22,7 +23,7 @@ var FILE_EXTENSIONS = {
22
23
  "BricsCAD": [".des"]
23
24
  };
24
25
  var SERVER_NAME = "atlisp-mcp-server";
25
- var SERVER_VERSION = "1.6.4";
26
+ var SERVER_VERSION = "1.6.7";
26
27
  var MOCK_PACKAGES = [
27
28
  { name: "base", description: "\u57FA\u7840\u51FD\u6570\u5E93", version: "1.0.0" },
28
29
  { name: "at-pm", description: "\u5DE5\u7A0B\u9879\u76EE\u7BA1\u7406", version: "2.1.0" },
@@ -115,7 +116,8 @@ function parseArgs() {
115
116
  return result;
116
117
  }
117
118
  function loadConfigFile(filePath) {
118
- if (!filePath || !fs.existsSync(filePath)) return null;
119
+ if (!filePath || !fs.existsSync(filePath))
120
+ return null;
119
121
  try {
120
122
  const raw = fs.readFileSync(filePath, "utf-8");
121
123
  const parsed = JSON.parse(raw);
@@ -136,7 +138,7 @@ if (!envResult.success) {
136
138
  process.exit(1);
137
139
  }
138
140
  var env = envResult.data;
139
- var configFilePath = env.CONFIG_FILE || cliArgs.configFile || path.join(os.homedir(), "@lisp", "atlisp.config.json");
141
+ var configFilePath = env.CONFIG_FILE || cliArgs.configFile || path.join(os.homedir(), ".atlisp", "atlisp.config.json");
140
142
  var fileConfig = loadConfigFile(configFilePath);
141
143
  var config = {
142
144
  port: fileConfig?.port || parseInt(env.PORT || cliArgs.port, 10),
@@ -253,7 +255,8 @@ function setupStdoutHandler(w) {
253
255
  const lines = buffer.split("\n");
254
256
  buffer = lines.pop() || "";
255
257
  for (const line of lines) {
256
- if (!line.trim()) continue;
258
+ if (!line.trim())
259
+ continue;
257
260
  try {
258
261
  const result = JSON.parse(line);
259
262
  const rid = result.requestId;
@@ -279,7 +282,8 @@ function setupStdoutHandler(w) {
279
282
  }
280
283
  function getWorker(force = false) {
281
284
  if (!worker || !worker.connected || force) {
282
- if (worker) worker.kill();
285
+ if (worker)
286
+ worker.kill();
283
287
  worker = spawn("node", [workerPath], {
284
288
  stdio: ["pipe", "pipe", "pipe"]
285
289
  });
@@ -287,7 +291,8 @@ function getWorker(force = false) {
287
291
  const w = worker;
288
292
  w.on("exit", (code) => {
289
293
  console.error("worker exited with code:", code);
290
- if (w !== worker) return;
294
+ if (w !== worker)
295
+ return;
291
296
  w.connected = false;
292
297
  for (const [id, { reject, timeout }] of pendingRequests) {
293
298
  clearTimeout(timeout);
@@ -308,7 +313,8 @@ function getWorker(force = false) {
308
313
  return worker;
309
314
  }
310
315
  function startHeartbeat() {
311
- if (heartbeatTimer) clearInterval(heartbeatTimer);
316
+ if (heartbeatTimer)
317
+ clearInterval(heartbeatTimer);
312
318
  heartbeatTimer = setInterval(async () => {
313
319
  try {
314
320
  const result = await sendMessage({ type: "ping" });
@@ -353,7 +359,8 @@ var CadConnection = class {
353
359
  return process.platform === "win32";
354
360
  }
355
361
  async connect(platform = null) {
356
- if (!this.isAvailable()) return false;
362
+ if (!this.isAvailable())
363
+ return false;
357
364
  try {
358
365
  const msg = platform ? { type: "connect", platform } : { type: "connect" };
359
366
  const result = await sendMessage(msg);
@@ -370,13 +377,16 @@ var CadConnection = class {
370
377
  return false;
371
378
  }
372
379
  async sendCommand(code) {
373
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
380
+ if (!this.connected)
381
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
374
382
  const result = await sendMessage({ type: "send", code, platform: _platform });
375
- if (result.success) return true;
383
+ if (result.success)
384
+ return true;
376
385
  throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
377
386
  }
378
387
  async sendCommandWithResult(code, encoding = null) {
379
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
388
+ if (!this.connected)
389
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
380
390
  const result = await sendMessage({ type: "sendResult", code, platform: _platform, encoding: encoding || "" });
381
391
  if (result.success) {
382
392
  return result.result || "";
@@ -390,7 +400,8 @@ var CadConnection = class {
390
400
  return this.product;
391
401
  }
392
402
  async isBusy() {
393
- if (!this.connected) return false;
403
+ if (!this.connected)
404
+ return false;
394
405
  try {
395
406
  const result = await sendMessage({ type: "isBusy", platform: _platform });
396
407
  return result && result.isBusy;
@@ -399,7 +410,8 @@ var CadConnection = class {
399
410
  }
400
411
  }
401
412
  async hasDoc() {
402
- if (!this.connected) return { hasDoc: false, docCount: 0 };
413
+ if (!this.connected)
414
+ return { hasDoc: false, docCount: 0 };
403
415
  try {
404
416
  const result = await sendMessage({ type: "hasdoc", platform: _platform });
405
417
  return result || { hasDoc: false, docCount: 0 };
@@ -408,7 +420,8 @@ var CadConnection = class {
408
420
  }
409
421
  }
410
422
  async newDoc() {
411
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
423
+ if (!this.connected)
424
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
412
425
  try {
413
426
  const result = await sendMessage({ type: "newdoc", platform: _platform });
414
427
  return result && result.success;
@@ -417,7 +430,8 @@ var CadConnection = class {
417
430
  }
418
431
  }
419
432
  async bringToFront() {
420
- if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
433
+ if (!this.connected)
434
+ throw new Error("\u672A\u8FDE\u63A5 CAD");
421
435
  try {
422
436
  const result = await sendMessage({ type: "bringToFront", platform: _platform });
423
437
  return result && result.success;
@@ -426,7 +440,8 @@ var CadConnection = class {
426
440
  }
427
441
  }
428
442
  async getInfo() {
429
- if (!this.connected) return "CAD \u672A\u8FDE\u63A5";
443
+ if (!this.connected)
444
+ return "CAD \u672A\u8FDE\u63A5";
430
445
  return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
431
446
  }
432
447
  async disconnect() {
@@ -463,9 +478,11 @@ var MAX_LOG_SIZE = 10 * 1024 * 1024;
463
478
  var MAX_LOG_FILES = 5;
464
479
  var stream = null;
465
480
  function rotateLog() {
466
- if (!fs2.existsSync(DEBUG_FILE)) return;
481
+ if (!fs2.existsSync(DEBUG_FILE))
482
+ return;
467
483
  const stat = fs2.statSync(DEBUG_FILE);
468
- if (stat.size < MAX_LOG_SIZE) return;
484
+ if (stat.size < MAX_LOG_SIZE)
485
+ return;
469
486
  if (stream) {
470
487
  stream.end();
471
488
  stream = null;
@@ -529,9 +546,11 @@ function ensureRequestLogDir() {
529
546
  }
530
547
  }
531
548
  function rotateRequestLog() {
532
- if (!fs2.existsSync(REQUEST_LOG_FILE)) return;
549
+ if (!fs2.existsSync(REQUEST_LOG_FILE))
550
+ return;
533
551
  const stat = fs2.statSync(REQUEST_LOG_FILE);
534
- if (stat.size < 10 * 1024 * 1024) return;
552
+ if (stat.size < 10 * 1024 * 1024)
553
+ return;
535
554
  const dir = path3.dirname(REQUEST_LOG_FILE);
536
555
  for (let i = 5; i > 0; i--) {
537
556
  const oldPath = `${REQUEST_LOG_FILE}.${i}`;
@@ -549,7 +568,8 @@ function rotateRequestLog() {
549
568
  }
550
569
  }
551
570
  function logRequest(req) {
552
- if (!config_default.requestLogEnabled) return;
571
+ if (!config_default.requestLogEnabled)
572
+ return;
553
573
  try {
554
574
  ensureRequestLogDir();
555
575
  rotateRequestLog();
@@ -566,7 +586,8 @@ function logRequest(req) {
566
586
  }
567
587
  }
568
588
  function logResponse(req, res, duration) {
569
- if (!config_default.requestLogEnabled) return;
589
+ if (!config_default.requestLogEnabled)
590
+ return;
570
591
  try {
571
592
  ensureRequestLogDir();
572
593
  const entry = {
@@ -664,11 +685,14 @@ function clearCache(uri) {
664
685
  }
665
686
  }
666
687
  function parseLispList(str) {
667
- if (!str || typeof str !== "string") return null;
688
+ if (!str || typeof str !== "string")
689
+ return null;
668
690
  const trimmed = str.trim();
669
- if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) return null;
691
+ if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
692
+ return null;
670
693
  const content = trimmed.slice(1, -1).trim();
671
- if (!content) return [];
694
+ if (!content)
695
+ return [];
672
696
  const result = [];
673
697
  let depth = 0;
674
698
  let current = "";
@@ -710,32 +734,44 @@ function parseLispList(str) {
710
734
  }
711
735
  current += ch;
712
736
  }
713
- if (current.trim()) result.push(current.trim());
737
+ if (current.trim())
738
+ result.push(current.trim());
714
739
  return result.map((item) => {
715
740
  const t = item.trim();
716
- if (t === "nil") return null;
717
- if (t === "t") return true;
718
- if (t === "T") return true;
741
+ if (t === "nil")
742
+ return null;
743
+ if (t === "t")
744
+ return true;
745
+ if (t === "T")
746
+ return true;
719
747
  const num = Number(t);
720
- if (!isNaN(num) && t !== "") return num;
721
- if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
748
+ if (!isNaN(num) && t !== "")
749
+ return num;
750
+ if (t.startsWith('"') && t.endsWith('"'))
751
+ return t.slice(1, -1);
722
752
  return t;
723
753
  });
724
754
  }
725
755
  function parseLispRecursive(str) {
726
- if (!str || typeof str !== "string") return null;
756
+ if (!str || typeof str !== "string")
757
+ return null;
727
758
  str = str.trim();
728
- if (!str) return null;
759
+ if (!str)
760
+ return null;
729
761
  let pos = 0;
730
762
  function skipWs() {
731
- while (pos < str.length && /\s/.test(str[pos])) pos++;
763
+ while (pos < str.length && /\s/.test(str[pos]))
764
+ pos++;
732
765
  }
733
766
  function parseValue() {
734
767
  skipWs();
735
- if (pos >= str.length) return null;
768
+ if (pos >= str.length)
769
+ return null;
736
770
  const ch = str[pos];
737
- if (ch === "(") return parseList();
738
- if (ch === '"') return parseString();
771
+ if (ch === "(")
772
+ return parseList();
773
+ if (ch === '"')
774
+ return parseString();
739
775
  if (ch === "'") {
740
776
  pos++;
741
777
  return parseValue();
@@ -748,11 +784,16 @@ function parseLispRecursive(str) {
748
784
  while (pos < str.length && str[pos] !== '"') {
749
785
  if (str[pos] === "\\" && pos + 1 < str.length) {
750
786
  pos++;
751
- if (str[pos] === '"') r += '"';
752
- else if (str[pos] === "n") r += "\n";
753
- else if (str[pos] === "t") r += " ";
754
- else if (str[pos] === "\\") r += "\\";
755
- else r += str[pos];
787
+ if (str[pos] === '"')
788
+ r += '"';
789
+ else if (str[pos] === "n")
790
+ r += "\n";
791
+ else if (str[pos] === "t")
792
+ r += " ";
793
+ else if (str[pos] === "\\")
794
+ r += "\\";
795
+ else
796
+ r += str[pos];
756
797
  } else {
757
798
  r += str[pos];
758
799
  }
@@ -763,12 +804,16 @@ function parseLispRecursive(str) {
763
804
  }
764
805
  function parseAtom() {
765
806
  const start = pos;
766
- while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(") pos++;
807
+ while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
808
+ pos++;
767
809
  const atom = str.slice(start, pos);
768
- if (atom === "nil" || atom === "NIL") return null;
769
- if (atom === "t" || atom === "T") return true;
810
+ if (atom === "nil" || atom === "NIL")
811
+ return null;
812
+ if (atom === "t" || atom === "T")
813
+ return true;
770
814
  const num = Number(atom);
771
- if (!isNaN(num) && atom !== "") return num;
815
+ if (!isNaN(num) && atom !== "")
816
+ return num;
772
817
  return atom;
773
818
  }
774
819
  function parseList() {
@@ -776,13 +821,15 @@ function parseLispRecursive(str) {
776
821
  const items = [];
777
822
  while (pos < str.length) {
778
823
  skipWs();
779
- if (pos >= str.length) break;
824
+ if (pos >= str.length)
825
+ break;
780
826
  if (str[pos] === ")") {
781
827
  pos++;
782
828
  return items;
783
829
  }
784
830
  const left = parseValue();
785
- if (left === void 0) break;
831
+ if (left === void 0)
832
+ break;
786
833
  skipWs();
787
834
  if (str[pos] === "." && (pos + 1 >= str.length || /\s/.test(str[pos + 1]) || str[pos + 1] === ")")) {
788
835
  pos++;
@@ -805,7 +852,8 @@ function parseLispRecursive(str) {
805
852
  return parseValue();
806
853
  }
807
854
  function lispPairsToObject(pairs) {
808
- if (!Array.isArray(pairs)) return pairs;
855
+ if (!Array.isArray(pairs))
856
+ return pairs;
809
857
  const obj = {};
810
858
  for (let i = 0; i < pairs.length - 1; i += 2) {
811
859
  const key = pairs[i];
@@ -817,7 +865,8 @@ function lispPairsToObject(pairs) {
817
865
  return obj;
818
866
  }
819
867
  function propertyPairsToObject(pairs) {
820
- if (!Array.isArray(pairs)) return null;
868
+ if (!Array.isArray(pairs))
869
+ return null;
821
870
  const obj = {};
822
871
  for (const pair of pairs) {
823
872
  if (Array.isArray(pair) && pair.length >= 2) {
@@ -828,8 +877,10 @@ function propertyPairsToObject(pairs) {
828
877
  }
829
878
  function buildEntityPropertiesCode({ type, layer, bbox }) {
830
879
  const items = [];
831
- if (type) items.push(`(cons 0 "${type.replace(/"/g, '\\"')}")`);
832
- if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
880
+ if (type)
881
+ items.push(`(cons 0 "${type.replace(/"/g, '\\"')}")`);
882
+ if (layer)
883
+ items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
833
884
  if (bbox) {
834
885
  const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
835
886
  if (parts.length === 4) {
@@ -860,8 +911,8 @@ var RESOURCES = [
860
911
  { uri: "atlisp://dwg/text-content", name: "Text Content", description: "\u6587\u672C\u5185\u5BB9\u53CA\u4F4D\u7F6E\uFF0C\u7528\u4E8E\u8BED\u4E49\u5206\u6790\u3002\u652F\u6301 ?layer=0&bbox=0,0,100,100&limit=5000&offset=0", mimeType: "application/json", subscribable: true },
861
912
  { uri: "atlisp://dwg/name", name: "DWG Name", description: "\u5F53\u524D DWG \u6587\u4EF6\u540D", mimeType: "application/json", subscribable: true },
862
913
  { uri: "atlisp://dwg/path", name: "DWG Path", description: "\u6587\u4EF6\u5B8C\u6574\u8DEF\u5F84", mimeType: "application/json", subscribable: true },
863
- { uri: "atlisp://dwg/block-refs", name: "Block References", description: "\u5757\u53C2\u7167\u5217\u8868\u53CA\u5C5E\u6027\u503C\u3001\u52A8\u6001\u5757\u7279\u6027\uFF0C\u652F\u6301 ?blockName=xxx", mimeType: "application/json", subscribable: true },
864
- { uri: "atlisp://dwg/tbl", name: "Tables", description: "CAD \u8868\u6570\u636E (layer, block, textstyle, dimstyle, linetype, ucs, view, viewport, regapp)\uFF0C\u652F\u6301 ?tbl=layer", mimeType: "application/json", subscribable: true },
914
+ { uri: "atlisp://dwg/block-refs", name: "Block References", description: "\u5757\u53C2\u7167\u5217\u8868\u53CA\u5C5E\u6027\u503C\u3001\u52A8\u6001\u5757\u7279\u6027\uFF0C\u652F\u6301\u8DEF\u5F84\u65B9\u5F0F atlisp://dwg/block-refs/{blockName}", mimeType: "application/json", subscribable: true },
915
+ { uri: "atlisp://dwg/tbl", name: "Tables", description: "CAD \u8868\u6570\u636E (layer, block, textstyle, dimstyle, linetype, ucs, view, viewport, regapp)\uFF0C\u652F\u6301\u8DEF\u5F84\u65B9\u5F0F atlisp://dwg/tbl/layer", mimeType: "application/json", subscribable: true },
865
916
  { uri: "atlisp://cad/dwgs", name: "DWG List", description: "\u6240\u6709\u6253\u5F00\u7684 DWG \u6587\u4EF6\u5217\u8868", mimeType: "application/json", subscribable: true },
866
917
  { uri: "atlisp://packages", name: "Packages", description: "\u5DF2\u5B89\u88C5\u5305\u5217\u8868", mimeType: "application/json", subscribable: true },
867
918
  { uri: "atlisp://platforms", name: "Platforms", description: "\u652F\u6301\u7684\u5E73\u53F0\u4FE1\u606F", mimeType: "application/json", subscribable: false },
@@ -870,20 +921,29 @@ var RESOURCES = [
870
921
  ];
871
922
  function parseQuery(uri) {
872
923
  const qIdx = uri.indexOf("?");
873
- if (qIdx === -1) return { base: uri, params: {} };
924
+ if (qIdx === -1)
925
+ return { base: uri, params: {} };
874
926
  const base = uri.substring(0, qIdx);
875
927
  const params = {};
876
928
  uri.substring(qIdx + 1).split("&").forEach((p) => {
877
929
  const eqIdx = p.indexOf("=");
878
930
  const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
879
931
  const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
880
- if (k) params[k] = decodeURIComponent(v);
932
+ if (k)
933
+ params[k] = decodeURIComponent(v);
881
934
  });
882
935
  return { base, params };
883
936
  }
884
937
  function parseTemplateUri(uri) {
885
- const match = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
886
- if (match) return { type: "entity", handle: match[1] };
938
+ const entityMatch = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
939
+ if (entityMatch)
940
+ return { type: "entity", handle: entityMatch[1] };
941
+ const tblMatch = uri.match(/^atlisp:\/\/dwg\/tbl\/([^?]+)$/);
942
+ if (tblMatch)
943
+ return { type: "tbl", tblName: tblMatch[1] };
944
+ const blockRefMatch = uri.match(/^atlisp:\/\/dwg\/block-refs\/([^?]+)$/);
945
+ if (blockRefMatch)
946
+ return { type: "block-refs", blockName: blockRefMatch[1] };
887
947
  return null;
888
948
  }
889
949
  async function listResources(subscribedUris = []) {
@@ -897,8 +957,16 @@ async function listResources(subscribedUris = []) {
897
957
  }
898
958
  async function readResource(uri) {
899
959
  const templateMatch = parseTemplateUri(uri);
900
- if (templateMatch && templateMatch.type === "entity") {
901
- return await getEntityByHandle(templateMatch.handle);
960
+ if (templateMatch) {
961
+ if (templateMatch.type === "entity") {
962
+ return await getEntityByHandle(templateMatch.handle);
963
+ }
964
+ if (templateMatch.type === "tbl") {
965
+ return await getTables({ tbl: templateMatch.tblName });
966
+ }
967
+ if (templateMatch.type === "block-refs") {
968
+ return await getBlockRefs({ blockName: templateMatch.blockName });
969
+ }
902
970
  }
903
971
  const { base, params } = parseQuery(uri);
904
972
  switch (base) {
@@ -931,8 +999,10 @@ async function readResource(uri) {
931
999
  }
932
1000
  }
933
1001
  async function getEntityByHandle(handle) {
934
- if (!cad.connected) await cad.connect();
935
- if (!cad.connected) return { error: "CAD \u672A\u8FDE\u63A5" };
1002
+ if (!cad.connected)
1003
+ await cad.connect();
1004
+ if (!cad.connected)
1005
+ return { error: "CAD \u672A\u8FDE\u63A5" };
936
1006
  const code = `(progn
937
1007
  (vl-load-com)
938
1008
  (if (setq ent (handent "${handle}"))
@@ -952,7 +1022,8 @@ async function getEntityByHandle(handle) {
952
1022
  )`;
953
1023
  try {
954
1024
  const result = await cad.sendCommandWithResult(code);
955
- if (!result || result === "nil") return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
1025
+ if (!result || result === "nil")
1026
+ return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
956
1027
  try {
957
1028
  return JSON.parse(result);
958
1029
  } catch {
@@ -964,7 +1035,8 @@ async function getEntityByHandle(handle) {
964
1035
  }
965
1036
  async function getCadInfo() {
966
1037
  const cached = getCached("cad:info");
967
- if (cached) return cached;
1038
+ if (cached)
1039
+ return cached;
968
1040
  if (!cad.connected) {
969
1041
  await cad.connect();
970
1042
  }
@@ -991,8 +1063,10 @@ async function getCadInfo() {
991
1063
  async function getEntities(params = {}) {
992
1064
  const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
993
1065
  const cached = getCached(cacheKey);
994
- if (cached) return cached;
995
- if (!cad.connected) await cad.connect();
1066
+ if (cached)
1067
+ return cached;
1068
+ if (!cad.connected)
1069
+ await cad.connect();
996
1070
  if (!cad.connected) {
997
1071
  const result = { total: 0, entities: [] };
998
1072
  setCache(cacheKey, result);
@@ -1093,7 +1167,8 @@ async function getEntitiesSummary(cacheKey) {
1093
1167
  }
1094
1168
  function buildTextContentCode({ layer, bbox, offset, limit }) {
1095
1169
  const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
1096
- if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
1170
+ if (layer)
1171
+ items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
1097
1172
  if (bbox) {
1098
1173
  const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
1099
1174
  if (parts.length === 4) {
@@ -1122,8 +1197,10 @@ function buildTextContentCode({ layer, bbox, offset, limit }) {
1122
1197
  async function getTextContent(params = {}) {
1123
1198
  const cacheKey = `dwg:text-content:${JSON.stringify(params)}`;
1124
1199
  const cached = getCached(cacheKey);
1125
- if (cached) return cached;
1126
- if (!cad.connected) await cad.connect();
1200
+ if (cached)
1201
+ return cached;
1202
+ if (!cad.connected)
1203
+ await cad.connect();
1127
1204
  if (!cad.connected) {
1128
1205
  const result = { total: 0, offset: 0, limit: 5e3, texts: [] };
1129
1206
  setCache(cacheKey, result);
@@ -1148,11 +1225,13 @@ async function getTextContent(params = {}) {
1148
1225
  const data = lispPairsToObject(parsed);
1149
1226
  const rawTexts = Array.isArray(data.texts) ? data.texts : [];
1150
1227
  data.texts = rawTexts.map((item) => {
1151
- if (!Array.isArray(item)) return null;
1228
+ if (!Array.isArray(item))
1229
+ return null;
1152
1230
  const obj = {};
1153
1231
  item.forEach((pair) => {
1154
1232
  if (Array.isArray(pair) && pair.length >= 2) {
1155
- if (pair[0] === "text") obj.text = String(pair[1] || "");
1233
+ if (pair[0] === "text")
1234
+ obj.text = String(pair[1] || "");
1156
1235
  else if (pair[0] === "position" && Array.isArray(pair[1])) {
1157
1236
  obj.position = pair[1].map((v) => typeof v === "number" ? v : 0);
1158
1237
  }
@@ -1170,8 +1249,10 @@ async function getTextContent(params = {}) {
1170
1249
  }
1171
1250
  }
1172
1251
  async function getDwgName() {
1173
- if (!cad.connected) await cad.connect();
1174
- if (!cad.connected) return { name: null };
1252
+ if (!cad.connected)
1253
+ await cad.connect();
1254
+ if (!cad.connected)
1255
+ return { name: null };
1175
1256
  try {
1176
1257
  const code = `(vl-princ-to-string (getvar "dwgname"))`;
1177
1258
  const name = await cad.sendCommandWithResult(code);
@@ -1181,8 +1262,10 @@ async function getDwgName() {
1181
1262
  }
1182
1263
  }
1183
1264
  async function getDwgPath() {
1184
- if (!cad.connected) await cad.connect();
1185
- if (!cad.connected) return { path: null, name: null };
1265
+ if (!cad.connected)
1266
+ await cad.connect();
1267
+ if (!cad.connected)
1268
+ return { path: null, name: null };
1186
1269
  try {
1187
1270
  const code = `(progn
1188
1271
  (setq prefix (vl-princ-to-string (getvar "dwgprefix")))
@@ -1200,7 +1283,8 @@ async function getDwgPath() {
1200
1283
  }
1201
1284
  if (!parsed) {
1202
1285
  const listResult = parseLispList(result);
1203
- if (listResult && listResult.length >= 2) parsed = listResult;
1286
+ if (listResult && listResult.length >= 2)
1287
+ parsed = listResult;
1204
1288
  }
1205
1289
  if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
1206
1290
  return { path: String(parsed[0]), name: String(parsed[1]) };
@@ -1287,8 +1371,10 @@ function buildBlockRefsCode(filterBlockName) {
1287
1371
  async function getBlockRefs(params = {}) {
1288
1372
  const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
1289
1373
  const cached = getCached(cacheKey);
1290
- if (cached) return cached;
1291
- if (!cad.connected) await cad.connect();
1374
+ if (cached)
1375
+ return cached;
1376
+ if (!cad.connected)
1377
+ await cad.connect();
1292
1378
  if (!cad.connected) {
1293
1379
  const result = { total: 0, blockRefs: [] };
1294
1380
  setCache(cacheKey, result);
@@ -1342,76 +1428,112 @@ async function getBlockRefs(params = {}) {
1342
1428
  return result;
1343
1429
  }
1344
1430
  }
1345
- var TBL_INFO = {
1346
- layer: { name: "\u56FE\u5C42", fields: ["name", "color", "linetype", "frozen", "locked", "on"] },
1347
- block: { name: "\u5757\u5B9A\u4E49", fields: ["name", "path", "flags"] },
1348
- textstyle: { name: "\u6587\u5B57\u6837\u5F0F", fields: ["name", "font", "height", "width", "oblique"] },
1349
- dimstyle: { name: "\u6807\u6CE8\u6837\u5F0F", fields: ["name", "arrow", "textheight", "scale"] },
1350
- linetype: { name: "\u7EBF\u578B", fields: ["name", "description", "pattern"] },
1351
- ucs: { name: "UCS", fields: ["name", "origin", "xaxis", "yaxis"] },
1352
- view: { name: "\u89C6\u56FE", fields: ["name", "center", "height", "width"] },
1353
- viewport: { name: "\u89C6\u53E3", fields: ["name", "number", "flags"] },
1354
- regapp: { name: "\u6CE8\u518C\u5E94\u7528", fields: ["name"] },
1355
- viewport: { name: "\u89C6\u53E3\u914D\u7F6E", fields: ["name", "number"] },
1356
- plotstyle: { name: "\u6253\u5370\u6837\u5F0F", fields: ["name"] }
1431
+ var TBL_QUERIES = {
1432
+ layer: { name: "layer", lisp: `(progn
1433
+ (setq @d nil)
1434
+ (setq @e (tblnext "layer" t))
1435
+ (while @e
1436
+ (setq @d (cons (list
1437
+ (cons 2 (cdr (assoc 2 @e)))
1438
+ (cons 62 (cdr (assoc 62 @e)))
1439
+ (cons 6 (cdr (assoc 6 @e)))
1440
+ (cons 70 (cdr (assoc 70 @e)))
1441
+ (cons 60 (if (< (cdr (assoc 62 @e)) 0) 1 0))
1442
+ ) @d))
1443
+ (setq @e (tblnext "layer" nil)))
1444
+ (list (cons 'table 'layer) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
1445
+ block: { name: "block", lisp: `(progn
1446
+ (setq @d nil)
1447
+ (vlax-for e (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
1448
+ (if (not (and (vlax-property-available-p e 'isfoundation) (vlax-get e 'isfoundation)))
1449
+ (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))))
1450
+ (list (cons 'table 'block) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
1451
+ style: { name: "style", lisp: `(progn
1452
+ (setq @d nil)
1453
+ (vlax-for e (vla-get-textstyles (vla-get-activedocument (vlax-get-acad-object)))
1454
+ (setq @d (cons (list
1455
+ (cons 2 (vla-get-name e))
1456
+ (cons 1 (vla-get-fontfile e))
1457
+ (cons 3 (vla-get-bigfontfile e))
1458
+ (cons 40 (vla-get-height e))
1459
+ (cons 41 (vla-get-width e))
1460
+ (cons 42 (/ (* 180.0 (vla-get-obliqueangle e)) pi))
1461
+ (cons 70 (vla-get-textgenerationflag e))
1462
+ ) @d)))
1463
+ (list (cons 'table 'style) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
1464
+ dimstyle: { name: "dimstyle", lisp: `(progn
1465
+ (setq @d nil)
1466
+ (vlax-for e (vla-get-dimstyles (vla-get-activedocument (vlax-get-acad-object)))
1467
+ (setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 0)) @d)))
1468
+ (list (cons 'table 'dimstyle) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
1469
+ ltype: { name: "linetype", lisp: `(progn
1470
+ (setq @d nil)
1471
+ (vlax-for e (vla-get-linetypes (vla-get-activedocument (vlax-get-acad-object)))
1472
+ (setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 0)) @d)))
1473
+ (list (cons 'table 'linetype) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` }
1474
+ };
1475
+ var TBL_KEY_ALIAS = {
1476
+ textstyle: "style",
1477
+ textstyles: "style",
1478
+ ltype: "linetype",
1479
+ linetype: "ltype"
1357
1480
  };
1358
1481
  function buildTablesCode(tblName) {
1359
- const validTbls = Object.keys(TBL_INFO).join('","');
1360
- return `(progn
1361
- (vl-load-com)
1362
- (defun @tbl:get (tbl / res)
1363
- (setq res nil)
1364
- (while (setq rec (tblnext tbl (null res)))
1365
- (setq res (cons (list (cdr (assoc 2 rec)) rec) res)))
1366
- (reverse res))
1367
- (defun @tbl:get-all nil
1368
- (list
1369
- (cons "layer" (@tbl:get "LAYER"))
1370
- (cons "block" (@tbl:get "BLOCK"))
1371
- (cons "textstyle" (@tbl:get "STYLE"))
1372
- (cons "dimstyle" (@tbl:get "DIMSTYLE"))
1373
- (cons "linetype" (@tbl:get "LTYPE"))
1374
- (cons "ucs" (@tbl:get "UCS"))
1375
- (cons "view" (@tbl:get "VIEW"))
1376
- (cons "regapp" (@tbl:get "REGAPP"))
1377
- ))
1378
- (if (member (strcase "${tblName}") (list "${validTbls}"))
1379
- (list (cons "table" (strcase "${tblName}")) (cons "data" (@tbl:get (strcase "${tblName}"))))
1380
- (@tbl:get-all)))
1381
- `;
1482
+ const raw = tblName.toLowerCase();
1483
+ const key = TBL_KEY_ALIAS[raw] || raw;
1484
+ const query = TBL_QUERIES[key];
1485
+ if (query) {
1486
+ return `(progn (vl-load-com) ${query.lisp})`;
1487
+ }
1488
+ const parts = Object.values(TBL_QUERIES).map((q) => q.lisp);
1489
+ return `(progn (vl-load-com) (list ${parts.join(" ")}))`;
1382
1490
  }
1383
1491
  function parseTableRecord(rec) {
1384
- if (!Array.isArray(rec) || rec.length < 2) return null;
1385
- const name = rec[0];
1386
- const data = rec[1];
1387
- if (!Array.isArray(data)) return { name };
1388
- const obj = { name: String(name) };
1389
- data.forEach((pair) => {
1492
+ if (!rec || !Array.isArray(rec))
1493
+ return null;
1494
+ const obj = {};
1495
+ for (const pair of rec) {
1390
1496
  if (Array.isArray(pair) && pair.length >= 2) {
1391
- const key = pair[0];
1392
- let val = pair[1];
1393
- if (key === 62) obj.color = typeof val === "number" ? val : 7;
1394
- else if (key === 6) obj.linetype = String(val);
1395
- else if (key === 70) obj.flags = typeof val === "number" ? val : 0;
1396
- else if (key === 1) obj.font = String(val);
1397
- else if (key === 40) obj.height = typeof val === "number" ? val : 0;
1398
- else if (key === 41) obj.width = typeof val === "number" ? val : 1;
1399
- else if (key === 42) obj.oblique = typeof val === "number" ? val : 0;
1400
- else if (key === 3) obj.description = String(val);
1401
- else if (key === 10 && Array.isArray(val)) obj.origin = val;
1402
- else if (key === 11 && Array.isArray(val)) obj.xaxis = val;
1403
- else if (key === 12 && Array.isArray(val)) obj.yaxis = val;
1404
- }
1405
- });
1406
- return obj;
1497
+ const key = String(pair[0]);
1498
+ const val = pair[1];
1499
+ if (key === "2")
1500
+ obj.name = String(val);
1501
+ else if (key === "62")
1502
+ obj.color = typeof val === "number" ? val : 7;
1503
+ else if (key === "6")
1504
+ obj.linetype = String(val);
1505
+ else if (key === "70") {
1506
+ obj.flags = typeof val === "number" ? val : 0;
1507
+ obj.frozen = (val & 1) !== 0;
1508
+ obj.locked = (val & 4) !== 0;
1509
+ } else if (key === "60")
1510
+ obj.on = val === 0;
1511
+ else if (key === "1")
1512
+ obj.font = String(val);
1513
+ else if (key === "40")
1514
+ obj.height = typeof val === "number" ? val : 0;
1515
+ else if (key === "41")
1516
+ obj.width = typeof val === "number" ? val : 1;
1517
+ else if (key === "42")
1518
+ obj.oblique = typeof val === "number" ? val : 0;
1519
+ else if (key === "3")
1520
+ obj.bigfont = String(val);
1521
+ else if (key === "50")
1522
+ obj.flags = typeof val === "number" ? val : 0;
1523
+ }
1524
+ }
1525
+ return obj.name ? obj : null;
1407
1526
  }
1408
1527
  async function getTables(params = {}) {
1409
- const tblName = params.tbl || "all";
1528
+ const tblName = params.tbl || params.type || "all";
1410
1529
  const cacheKey = `dwg:tbl:${tblName}`;
1411
1530
  const cached = getCached(cacheKey);
1412
- if (cached) return cached;
1413
- if (!cad.connected) await cad.connect();
1414
- if (!cad.connected) return { table: tblName, data: [] };
1531
+ if (cached)
1532
+ return cached;
1533
+ if (!cad.connected)
1534
+ await cad.connect();
1535
+ if (!cad.connected)
1536
+ return { table: tblName, data: [] };
1415
1537
  try {
1416
1538
  const code = buildTablesCode(tblName);
1417
1539
  const resultStr = await cad.sendCommandWithResult(code);
@@ -1422,27 +1544,73 @@ async function getTables(params = {}) {
1422
1544
  }
1423
1545
  const parsed = parseLispRecursive(resultStr);
1424
1546
  if (!parsed || !Array.isArray(parsed)) {
1425
- const result2 = { table: tblName, data: [] };
1547
+ const result2 = { table: tblName, total: 0, data: [] };
1426
1548
  setCache(cacheKey, result2);
1427
1549
  return result2;
1428
1550
  }
1429
- const isSingleTable = parsed.length >= 2 && parsed[0] === "table";
1430
1551
  let result;
1431
- if (isSingleTable) {
1432
- const data = Array.isArray(parsed[1]) ? parsed[1] : [];
1433
- const tblData = Array.isArray(parsed[2]) ? parsed[2] : [];
1552
+ if (parsed.length >= 3 && parsed[0] && String(parsed[0][0]).toUpperCase() === "TABLE") {
1553
+ const tableName = String(parsed[0][1]).toLowerCase();
1554
+ let total = 0;
1555
+ let tblData = [];
1556
+ for (const item of parsed) {
1557
+ if (Array.isArray(item) && item.length >= 2) {
1558
+ const key = String(item[0]).toUpperCase();
1559
+ if (key === "TOTAL")
1560
+ total = typeof item[1] === "number" ? item[1] : 0;
1561
+ else if (key === "DATA") {
1562
+ if (Array.isArray(item[1]) && item[1].length > 0 && item[1][0].length > 0 && !isNaN(parseInt(item[1][0][0]))) {
1563
+ tblData = item[1];
1564
+ }
1565
+ }
1566
+ }
1567
+ }
1568
+ if (tblData.length === 0 && parsed.length > 2) {
1569
+ tblData = parsed.slice(2);
1570
+ }
1434
1571
  result = {
1435
- table: String(data),
1572
+ table: tableName,
1573
+ total,
1436
1574
  data: tblData.map(parseTableRecord).filter(Boolean)
1437
1575
  };
1438
1576
  } else {
1439
1577
  const allData = {};
1440
1578
  parsed.forEach((item) => {
1441
- if (Array.isArray(item) && item.length >= 2) {
1442
- const key = item[0];
1443
- const vals = Array.isArray(item[1]) ? item[1] : [];
1444
- allData[key] = vals.map(parseTableRecord).filter(Boolean);
1579
+ if (!Array.isArray(item) || item.length < 2)
1580
+ return;
1581
+ let tableKey = null;
1582
+ const entry = { total: 0, data: [] };
1583
+ if (Array.isArray(item[0]) && item[0].length >= 2 && String(item[0][0]).toLowerCase() === "table") {
1584
+ tableKey = String(item[0][1]).toLowerCase();
1585
+ for (let i = 1; i < item.length; i++) {
1586
+ const sub = item[i];
1587
+ if (!Array.isArray(sub) || sub.length < 2)
1588
+ continue;
1589
+ const subKey = String(sub[0]).toUpperCase();
1590
+ if (subKey === "TOTAL")
1591
+ entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1592
+ else if (subKey === "DATA") {
1593
+ const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
1594
+ entry.data = raw.map(parseTableRecord).filter(Boolean);
1595
+ }
1596
+ }
1597
+ } else {
1598
+ tableKey = String(item[0]).toLowerCase();
1599
+ for (let i = 1; i < item.length; i++) {
1600
+ const sub = item[i];
1601
+ if (!Array.isArray(sub) || sub.length < 2)
1602
+ continue;
1603
+ const subKey = String(sub[0]).toUpperCase();
1604
+ if (subKey === "TOTAL") {
1605
+ entry.total = typeof sub[1] === "number" ? sub[1] : 0;
1606
+ } else if (subKey === "DATA") {
1607
+ const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
1608
+ entry.data = raw.map(parseTableRecord).filter(Boolean);
1609
+ }
1610
+ }
1445
1611
  }
1612
+ if (tableKey)
1613
+ allData[tableKey] = entry;
1446
1614
  });
1447
1615
  result = allData;
1448
1616
  }
@@ -1458,9 +1626,12 @@ async function getTables(params = {}) {
1458
1626
  async function getPackages(filterName = null) {
1459
1627
  const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
1460
1628
  const cached = getCached(cacheKey);
1461
- if (cached) return cached;
1462
- if (!cad.connected) await cad.connect();
1463
- if (!cad.connected) return [];
1629
+ if (cached)
1630
+ return cached;
1631
+ if (!cad.connected)
1632
+ await cad.connect();
1633
+ if (!cad.connected)
1634
+ return [];
1464
1635
  try {
1465
1636
  const code = `(mapcar 'cdr @::*local-pkgs*)`;
1466
1637
  const result = await cad.sendCommandWithResult(code);
@@ -1474,7 +1645,8 @@ async function getPackages(filterName = null) {
1474
1645
  } catch {
1475
1646
  raw = parseLispList(result) || [];
1476
1647
  }
1477
- if (!Array.isArray(raw)) raw = [];
1648
+ if (!Array.isArray(raw))
1649
+ raw = [];
1478
1650
  const packages = raw.map((item) => {
1479
1651
  if (Array.isArray(item)) {
1480
1652
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
@@ -1483,13 +1655,20 @@ async function getPackages(filterName = null) {
1483
1655
  const [[key, val]] = Object.entries(entry);
1484
1656
  const k = String(key);
1485
1657
  const v = String(val);
1486
- if (k === ":NAME") pkg.name = v;
1487
- else if (k === ":VERSION") pkg.version = v;
1488
- else if (k === ":DESCRIPTION") pkg.description = v;
1489
- else if (k === ":FULL-NAME") pkg.fullName = v;
1490
- else if (k === ":AUTHOR") pkg.author = v;
1491
- else if (k === ":CATEGORY") pkg.category = v;
1492
- else if (k === ":URL") pkg.url = v;
1658
+ if (k === ":NAME")
1659
+ pkg.name = v;
1660
+ else if (k === ":VERSION")
1661
+ pkg.version = v;
1662
+ else if (k === ":DESCRIPTION")
1663
+ pkg.description = v;
1664
+ else if (k === ":FULL-NAME")
1665
+ pkg.fullName = v;
1666
+ else if (k === ":AUTHOR")
1667
+ pkg.author = v;
1668
+ else if (k === ":CATEGORY")
1669
+ pkg.category = v;
1670
+ else if (k === ":URL")
1671
+ pkg.url = v;
1493
1672
  }
1494
1673
  }
1495
1674
  return pkg;
@@ -1500,15 +1679,22 @@ async function getPackages(filterName = null) {
1500
1679
  if (item && typeof item === "object") {
1501
1680
  const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
1502
1681
  const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
1503
- if (nameVal) pkg.name = String(nameVal);
1682
+ if (nameVal)
1683
+ pkg.name = String(nameVal);
1504
1684
  const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
1505
- if (verVal) pkg.version = String(verVal);
1685
+ if (verVal)
1686
+ pkg.version = String(verVal);
1506
1687
  const descVal = item.description || item.Description || item.DESCRIPTION || item[":DESCRIPTION"];
1507
- if (descVal) pkg.description = String(descVal);
1508
- if (item.fullName || item.full_name) pkg.fullName = String(item.fullName || item.full_name);
1509
- if (item.author || item.Author) pkg.author = String(item.author || item.Author);
1510
- if (item.category || item.Category) pkg.category = String(item.category || item.Category);
1511
- if (item.url || item.Url || item.URL) pkg.url = String(item.url || item.Url || item.URL);
1688
+ if (descVal)
1689
+ pkg.description = String(descVal);
1690
+ if (item.fullName || item.full_name)
1691
+ pkg.fullName = String(item.fullName || item.full_name);
1692
+ if (item.author || item.Author)
1693
+ pkg.author = String(item.author || item.Author);
1694
+ if (item.category || item.Category)
1695
+ pkg.category = String(item.category || item.Category);
1696
+ if (item.url || item.Url || item.URL)
1697
+ pkg.url = String(item.url || item.Url || item.URL);
1512
1698
  return pkg;
1513
1699
  }
1514
1700
  return null;
@@ -1534,9 +1720,12 @@ function getPlatforms() {
1534
1720
  async function getDwgList() {
1535
1721
  const cacheKey = "cad:dwgs";
1536
1722
  const cached = getCached(cacheKey);
1537
- if (cached) return cached;
1538
- if (!cad.connected) await cad.connect();
1539
- if (!cad.connected) return [];
1723
+ if (cached)
1724
+ return cached;
1725
+ if (!cad.connected)
1726
+ await cad.connect();
1727
+ if (!cad.connected)
1728
+ return [];
1540
1729
  try {
1541
1730
  const code = `(progn
1542
1731
  (vl-load-com)
@@ -1560,7 +1749,8 @@ async function getDwgList() {
1560
1749
  parsed = listResult;
1561
1750
  }
1562
1751
  }
1563
- if (!Array.isArray(parsed)) parsed = [];
1752
+ if (!Array.isArray(parsed))
1753
+ parsed = [];
1564
1754
  const dwgList = parsed.map((item) => {
1565
1755
  if (Array.isArray(item) && item.length >= 2) {
1566
1756
  return { name: String(item[0]), path: String(item[1]) };
@@ -1587,7 +1777,8 @@ function loadStandardsFile(filename) {
1587
1777
  var standardsCache = /* @__PURE__ */ new Map();
1588
1778
  function getCachedStandards(key) {
1589
1779
  const entry = standardsCache.get(key);
1590
- if (entry && Date.now() - entry.timestamp < 3e4) return entry.data;
1780
+ if (entry && Date.now() - entry.timestamp < 3e4)
1781
+ return entry.data;
1591
1782
  standardsCache.delete(key);
1592
1783
  return null;
1593
1784
  }
@@ -1596,16 +1787,20 @@ function setCachedStandards(key, data) {
1596
1787
  }
1597
1788
  function getDraftingStandards() {
1598
1789
  const cached = getCachedStandards("drafting");
1599
- if (cached) return cached;
1790
+ if (cached)
1791
+ return cached;
1600
1792
  const data = loadStandardsFile("drafting.json");
1601
- if (data) setCachedStandards("drafting", data);
1793
+ if (data)
1794
+ setCachedStandards("drafting", data);
1602
1795
  return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
1603
1796
  }
1604
1797
  function getCodingStandards() {
1605
1798
  const cached = getCachedStandards("coding");
1606
- if (cached) return cached;
1799
+ if (cached)
1800
+ return cached;
1607
1801
  const data = loadStandardsFile("coding.json");
1608
- if (data) setCachedStandards("coding", data);
1802
+ if (data)
1803
+ setCachedStandards("coding", data);
1609
1804
  return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
1610
1805
  }
1611
1806
 
@@ -1820,9 +2015,11 @@ var SseSession = class {
1820
2015
  return lines.join("\n") + "\n\n";
1821
2016
  }
1822
2017
  _setupDrain() {
1823
- if (typeof this.#res.on !== "function") return;
2018
+ if (typeof this.#res.on !== "function")
2019
+ return;
1824
2020
  this.#drainHandler = () => {
1825
- if (!this.#active) return;
2021
+ if (!this.#active)
2022
+ return;
1826
2023
  if (this.#backpressureBuffer.length > 0) {
1827
2024
  this._drainBuffer();
1828
2025
  }
@@ -1844,7 +2041,8 @@ var SseSession = class {
1844
2041
  }
1845
2042
  }
1846
2043
  _write(content) {
1847
- if (!this.#active) return false;
2044
+ if (!this.#active)
2045
+ return false;
1848
2046
  try {
1849
2047
  if (this.#backpressureBuffer.length > 0) {
1850
2048
  this.#backpressureBuffer.push(content);
@@ -1972,7 +2170,8 @@ function persistSessionData(clientId, sessionData) {
1972
2170
  function loadPersistedSessionData(clientId) {
1973
2171
  try {
1974
2172
  const filePath = getSessionStorePath(clientId);
1975
- if (!fs4.existsSync(filePath)) return null;
2173
+ if (!fs4.existsSync(filePath))
2174
+ return null;
1976
2175
  const raw = fs4.readFileSync(filePath, "utf-8");
1977
2176
  const store = JSON.parse(raw);
1978
2177
  if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
@@ -2132,7 +2331,8 @@ var SessionTransport = class {
2132
2331
  this._started = true;
2133
2332
  }
2134
2333
  async send(message) {
2135
- if (this._closed) return;
2334
+ if (this._closed)
2335
+ return;
2136
2336
  if (this._pendingRequest) {
2137
2337
  const { resolve, reject, timeout } = this._pendingRequest;
2138
2338
  clearTimeout(timeout);
@@ -2141,7 +2341,8 @@ var SessionTransport = class {
2141
2341
  }
2142
2342
  }
2143
2343
  async close() {
2144
- if (this._closed) return;
2344
+ if (this._closed)
2345
+ return;
2145
2346
  this._closed = true;
2146
2347
  if (this._pendingRequest) {
2147
2348
  const { reject, timeout } = this._pendingRequest;
@@ -2453,10 +2654,14 @@ ${generateSuggestions(entities, layers)}`
2453
2654
  }
2454
2655
  function generateSuggestions(entities, layers) {
2455
2656
  const suggestions = [];
2456
- if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
2457
- if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
2458
- if (entities.byType.LINE && entities.byType.LINE > 500) suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
2459
- if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
2657
+ if (entities.total > 1e3)
2658
+ suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
2659
+ if (layers.length > 20)
2660
+ suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
2661
+ if (entities.byType.LINE && entities.byType.LINE > 500)
2662
+ suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
2663
+ if (!entities.byType.DIMENSION)
2664
+ suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
2460
2665
  return suggestions.length ? suggestions.join("\n") : "- \u56FE\u7EB8\u7ED3\u6784\u826F\u597D";
2461
2666
  }
2462
2667
  async function generateBatchLinesPrompt(args) {
@@ -3001,7 +3206,8 @@ var Metrics = class {
3001
3206
  bucket.sum += value;
3002
3207
  bucket.min = Math.min(bucket.min, value);
3003
3208
  bucket.max = Math.max(bucket.max, value);
3004
- if (!bucket.values) bucket.values = [];
3209
+ if (!bucket.values)
3210
+ bucket.values = [];
3005
3211
  bucket.values.push(value);
3006
3212
  this.histograms.set(key, bucket);
3007
3213
  }
@@ -3092,9 +3298,15 @@ var RESOURCE_TEMPLATES = [
3092
3298
  mimeType: "application/json"
3093
3299
  },
3094
3300
  {
3095
- uriTemplate: "atlisp://dwg/entities?type={type}",
3096
- name: "Entities by Type",
3097
- description: "\u6309\u7C7B\u578B\u67E5\u8BE2\u5B9E\u4F53\u5217\u8868",
3301
+ uriTemplate: "atlisp://dwg/entities",
3302
+ name: "Entities Summary",
3303
+ description: "\u8FD4\u56DE\u56FE\u5143\u603B\u6570\u548C\u6309\u7C7B\u578B\u7EDF\u8BA1\u5217\u8868",
3304
+ mimeType: "application/json"
3305
+ },
3306
+ {
3307
+ uriTemplate: "atlisp://dwg/entities?type={type}&layer={layer}&bbox={bbox}",
3308
+ name: "Filtered Entities",
3309
+ description: "\u6309 type/layer/bbox \u8FC7\u6EE4\u56FE\u5143\uFF0C\u8FD4\u56DE entity:properties \u5168\u5C5E\u6027 JSON\uFF08ObjectName, Handle, Layer, Color, Center, Radius \u7B49\uFF09",
3098
3310
  mimeType: "application/json"
3099
3311
  },
3100
3312
  {
@@ -3104,13 +3316,13 @@ var RESOURCE_TEMPLATES = [
3104
3316
  mimeType: "application/json"
3105
3317
  },
3106
3318
  {
3107
- uriTemplate: "atlisp://dwg/block-refs?blockName={blockName}",
3319
+ uriTemplate: "atlisp://dwg/block-refs/{blockName}",
3108
3320
  name: "Block References",
3109
3321
  description: "\u83B7\u53D6\u5757\u53C2\u7167\u5217\u8868\uFF0C\u652F\u6301\u6309\u5757\u540D\u8FC7\u6EE4",
3110
3322
  mimeType: "application/json"
3111
3323
  },
3112
3324
  {
3113
- uriTemplate: "atlisp://dwg/tbl?tbl={tbl}",
3325
+ uriTemplate: "atlisp://dwg/tbl/{tbl}",
3114
3326
  name: "CAD Tables",
3115
3327
  description: "\u83B7\u53D6 CAD \u8868\u6570\u636E (layer, block, textstyle, dimstyle, linetype, ucs, view, regapp)",
3116
3328
  mimeType: "application/json"
@@ -3240,7 +3452,8 @@ async function evalLisp(code, withResult = false, encoding = null) {
3240
3452
  return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3241
3453
  }
3242
3454
  const trimmed = (code || "").trim();
3243
- if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3455
+ if (!trimmed)
3456
+ return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3244
3457
  try {
3245
3458
  if (withResult) {
3246
3459
  const result = await cad.sendCommandWithResult(trimmed, encoding);
@@ -3260,14 +3473,17 @@ async function getCadInfo2() {
3260
3473
  if (!cad.connected) {
3261
3474
  await cad.connect();
3262
3475
  }
3263
- if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3476
+ if (!cad.connected)
3477
+ return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
3264
3478
  const info = await cad.getInfo();
3265
3479
  return { content: [{ type: "text", text: info }] };
3266
3480
  }
3267
3481
  async function atCommand(command) {
3268
- if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3482
+ if (!cad.connected)
3483
+ return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
3269
3484
  const trimmed = (command || "").trim();
3270
- if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3485
+ if (!trimmed)
3486
+ return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
3271
3487
  await cad.sendCommand(trimmed + "\n");
3272
3488
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
3273
3489
  }
@@ -3275,7 +3491,8 @@ async function newDocument() {
3275
3491
  if (!cad.connected) {
3276
3492
  await cad.connect();
3277
3493
  }
3278
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3494
+ if (!cad.connected)
3495
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3279
3496
  const result = await cad.newDoc();
3280
3497
  if (result) {
3281
3498
  return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
@@ -3286,7 +3503,8 @@ async function bringToFront() {
3286
3503
  if (!cad.connected) {
3287
3504
  await cad.connect();
3288
3505
  }
3289
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3506
+ if (!cad.connected)
3507
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3290
3508
  const result = await cad.bringToFront();
3291
3509
  if (result) {
3292
3510
  return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
@@ -3297,7 +3515,8 @@ async function installAtlisp() {
3297
3515
  if (!cad.connected) {
3298
3516
  await cad.connect();
3299
3517
  }
3300
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3518
+ if (!cad.connected)
3519
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3301
3520
  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))))`;
3302
3521
  await cad.sendCommand(installCode + "\n");
3303
3522
  return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
@@ -3306,10 +3525,12 @@ async function listFunctionsInCad() {
3306
3525
  if (!cad.connected) {
3307
3526
  await cad.connect();
3308
3527
  }
3309
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3528
+ if (!cad.connected)
3529
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3310
3530
  try {
3311
3531
  const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
3312
- if (result) return { content: [{ type: "text", text: result }] };
3532
+ if (result)
3533
+ return { content: [{ type: "text", text: result }] };
3313
3534
  return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
3314
3535
  } catch (e) {
3315
3536
  return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
@@ -3364,7 +3585,8 @@ async function initAtlisp() {
3364
3585
  if (!cad.connected) {
3365
3586
  await cad.connect();
3366
3587
  }
3367
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3588
+ if (!cad.connected)
3589
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3368
3590
  const code = `(if (null @::load-module)
3369
3591
  (progn
3370
3592
  (vl-load-com)
@@ -3404,12 +3626,15 @@ async function fetchPackages() {
3404
3626
  return cachedPackages || MOCK_PACKAGES;
3405
3627
  }
3406
3628
  function flattenPackages(data) {
3407
- if (Array.isArray(data)) return data;
3408
- if (data && Array.isArray(data.packages)) return data.packages;
3629
+ if (Array.isArray(data))
3630
+ return data;
3631
+ if (data && Array.isArray(data.packages))
3632
+ return data.packages;
3409
3633
  return [];
3410
3634
  }
3411
3635
  async function listPackages() {
3412
- if (!cad.connected) await cad.connect();
3636
+ if (!cad.connected)
3637
+ await cad.connect();
3413
3638
  if (!cad.connected) {
3414
3639
  const data2 = await fetchPackages();
3415
3640
  const items2 = flattenPackages(data2);
@@ -3417,7 +3642,8 @@ async function listPackages() {
3417
3642
  return { content: [{ type: "text", text: text2 }] };
3418
3643
  }
3419
3644
  const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
3420
- if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
3645
+ if (result && result !== "nil")
3646
+ return { content: [{ type: "text", text: result }] };
3421
3647
  const data = await fetchPackages();
3422
3648
  const items = flattenPackages(data);
3423
3649
  const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
@@ -3437,10 +3663,12 @@ async function searchPackages(query) {
3437
3663
  for (const p of items) {
3438
3664
  const name = (p.name || "").toLowerCase();
3439
3665
  const desc = (p.description || "").toLowerCase();
3440
- if (name.includes(q) || desc.includes(q)) results.push(p);
3666
+ if (name.includes(q) || desc.includes(q))
3667
+ results.push(p);
3441
3668
  }
3442
3669
  } else {
3443
- for (const p of items) results.push(p);
3670
+ for (const p of items)
3671
+ results.push(p);
3444
3672
  }
3445
3673
  if (results.length === 0) {
3446
3674
  return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
@@ -3492,7 +3720,8 @@ function writeCacheToDisk(data) {
3492
3720
  }
3493
3721
  async function fetchFunctions() {
3494
3722
  const diskCache = readCacheFromDisk();
3495
- if (diskCache) return diskCache;
3723
+ if (diskCache)
3724
+ return diskCache;
3496
3725
  try {
3497
3726
  const response = await fetch(FUNCTIONS_URL, { headers: { "User-Agent": "atlisp-mcp" } });
3498
3727
  if (response.ok) {
@@ -3512,7 +3741,8 @@ async function getFunctionUsage(funcName, packageName) {
3512
3741
  if (data) {
3513
3742
  const funcs = Object.values(data.all_functions || {});
3514
3743
  const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
3515
- if (func) results.push(func);
3744
+ if (func)
3745
+ results.push(func);
3516
3746
  }
3517
3747
  if (results.length === 0 && FUNCTIONS_DIR) {
3518
3748
  try {
@@ -3521,7 +3751,8 @@ async function getFunctionUsage(funcName, packageName) {
3521
3751
  const raw = fs6.readFileSync(path8.join(FUNCTIONS_DIR, file), "utf-8");
3522
3752
  const data2 = JSON.parse(raw);
3523
3753
  const func = data2.functions?.find((f2) => f2.name === funcName);
3524
- if (func) results.push(func);
3754
+ if (func)
3755
+ results.push(func);
3525
3756
  }
3526
3757
  } catch {
3527
3758
  }
@@ -3589,7 +3820,8 @@ async function getEntity(handle) {
3589
3820
  if (!cad.connected) {
3590
3821
  await cad.connect();
3591
3822
  }
3592
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3823
+ if (!cad.connected)
3824
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3593
3825
  const code = `(progn
3594
3826
  (vl-load-com)
3595
3827
  (if (setq ent (handent "${handle}"))
@@ -3621,7 +3853,8 @@ async function setEntityProperty(handle, property, value) {
3621
3853
  if (!cad.connected) {
3622
3854
  await cad.connect();
3623
3855
  }
3624
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3856
+ if (!cad.connected)
3857
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3625
3858
  let propCode = "";
3626
3859
  switch (property) {
3627
3860
  case "layer":
@@ -3664,7 +3897,8 @@ async function deleteEntity(handle) {
3664
3897
  if (!cad.connected) {
3665
3898
  await cad.connect();
3666
3899
  }
3667
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3900
+ if (!cad.connected)
3901
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3668
3902
  const code = `(progn
3669
3903
  (vl-load-com)
3670
3904
  (if (setq ent (handent "${handle}"))
@@ -3689,12 +3923,15 @@ async function selectEntities(filter) {
3689
3923
  if (!cad.connected) {
3690
3924
  await cad.connect();
3691
3925
  }
3692
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3926
+ if (!cad.connected)
3927
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3693
3928
  let filterCode = "nil";
3694
3929
  if (filter && (filter.type || filter.layer)) {
3695
3930
  const items = [];
3696
- if (filter.type) items.push(`'(0 . "${filter.type}")`);
3697
- if (filter.layer) items.push(`'(8 . "${filter.layer}")`);
3931
+ if (filter.type)
3932
+ items.push(`'(0 . "${filter.type}")`);
3933
+ if (filter.layer)
3934
+ items.push(`'(8 . "${filter.layer}")`);
3698
3935
  filterCode = `(list ${items.join(" ")})`;
3699
3936
  }
3700
3937
  const code = `(progn
@@ -3726,7 +3963,8 @@ async function createLayer(name, color = 7, linetype = "Continuous") {
3726
3963
  if (!cad.connected) {
3727
3964
  await cad.connect();
3728
3965
  }
3729
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3966
+ if (!cad.connected)
3967
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3730
3968
  const code = `(progn
3731
3969
  (vl-load-com)
3732
3970
  (if (not (tblsearch "LAYER" "${name}"))
@@ -3762,7 +4000,8 @@ async function deleteLayer(name) {
3762
4000
  if (!cad.connected) {
3763
4001
  await cad.connect();
3764
4002
  }
3765
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4003
+ if (!cad.connected)
4004
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3766
4005
  const code = `(progn
3767
4006
  (vl-load-com)
3768
4007
  (cond
@@ -3796,7 +4035,8 @@ async function setLayerProperty(name, property, value) {
3796
4035
  if (!cad.connected) {
3797
4036
  await cad.connect();
3798
4037
  }
3799
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4038
+ if (!cad.connected)
4039
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3800
4040
  let propCode = "";
3801
4041
  switch (property) {
3802
4042
  case "color":
@@ -3844,7 +4084,8 @@ async function setCurrentLayer(name) {
3844
4084
  if (!cad.connected) {
3845
4085
  await cad.connect();
3846
4086
  }
3847
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4087
+ if (!cad.connected)
4088
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3848
4089
  const code = `(progn
3849
4090
  (vl-load-com)
3850
4091
  (if (tblsearch "LAYER" "${name}")
@@ -3871,7 +4112,8 @@ async function createBlock(name, entities) {
3871
4112
  if (!cad.connected) {
3872
4113
  await cad.connect();
3873
4114
  }
3874
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4115
+ if (!cad.connected)
4116
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3875
4117
  const code = `(progn
3876
4118
  (vl-load-com)
3877
4119
  (if (not (tblsearch "BLOCK" "${name}"))
@@ -3908,7 +4150,8 @@ async function insertBlock(blockName, point, scale = 1, rotation = 0) {
3908
4150
  if (!cad.connected) {
3909
4151
  await cad.connect();
3910
4152
  }
3911
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4153
+ if (!cad.connected)
4154
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3912
4155
  const coords = Array.isArray(point) ? point : point.split(",").map((s) => parseFloat(s.trim()));
3913
4156
  if (coords.length < 2) {
3914
4157
  return { content: [{ type: "text", text: "\u63D2\u5165\u70B9\u683C\u5F0F\u9519\u8BEF\uFF0C\u9700\u8981 x,y \u6216 [x,y,z]" }], isError: true };
@@ -3938,7 +4181,8 @@ async function getBlocks() {
3938
4181
  if (!cad.connected) {
3939
4182
  await cad.connect();
3940
4183
  }
3941
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4184
+ if (!cad.connected)
4185
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3942
4186
  const code = `(progn
3943
4187
  (vl-load-com)
3944
4188
  (setq blocks nil)
@@ -3961,7 +4205,8 @@ async function explodeBlock(handle) {
3961
4205
  if (!cad.connected) {
3962
4206
  await cad.connect();
3963
4207
  }
3964
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4208
+ if (!cad.connected)
4209
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3965
4210
  const code = `(progn
3966
4211
  (vl-load-com)
3967
4212
  (if (setq ent (handent "${handle}"))
@@ -3988,7 +4233,8 @@ async function openDwg(filePath) {
3988
4233
  if (!cad.connected) {
3989
4234
  await cad.connect();
3990
4235
  }
3991
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4236
+ if (!cad.connected)
4237
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
3992
4238
  const normalizedPath = filePath.replace(/\\/g, "\\\\");
3993
4239
  const code = `(progn
3994
4240
  (vl-load-com)
@@ -4025,7 +4271,8 @@ async function saveDwg(filePath = null) {
4025
4271
  if (!cad.connected) {
4026
4272
  await cad.connect();
4027
4273
  }
4028
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4274
+ if (!cad.connected)
4275
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4029
4276
  const code = filePath ? `(progn
4030
4277
  (vl-load-com)
4031
4278
  (command "._SAVEAS" "${filePath.replace(/\\/g, "\\\\")}")
@@ -4049,7 +4296,8 @@ async function exportPdf(outputPath, layout = "Model") {
4049
4296
  if (!cad.connected) {
4050
4297
  await cad.connect();
4051
4298
  }
4052
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4299
+ if (!cad.connected)
4300
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4053
4301
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4054
4302
  const code = `(progn
4055
4303
  (vl-load-com)
@@ -4077,7 +4325,8 @@ async function closeDwg(save = false) {
4077
4325
  if (!cad.connected) {
4078
4326
  await cad.connect();
4079
4327
  }
4080
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4328
+ if (!cad.connected)
4329
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4081
4330
  const code = `(progn
4082
4331
  (vl-load-com)
4083
4332
  (if ${save ? "T" : "nil"}
@@ -4099,7 +4348,8 @@ async function createDimension(type, points, style = {}) {
4099
4348
  if (!cad.connected) {
4100
4349
  await cad.connect();
4101
4350
  }
4102
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4351
+ if (!cad.connected)
4352
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4103
4353
  let dimCode = "";
4104
4354
  const validTypes = ["ALIGNED", "LINEAR", "ORDINATE", "RADIAL", "DIAMETER", "ANGULAR"];
4105
4355
  const dimType = (type || "ALIGNED").toUpperCase();
@@ -4141,7 +4391,8 @@ async function getDimensionValue(handle) {
4141
4391
  if (!cad.connected) {
4142
4392
  await cad.connect();
4143
4393
  }
4144
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4394
+ if (!cad.connected)
4395
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4145
4396
  const code = `(progn
4146
4397
  (vl-load-com)
4147
4398
  (if (setq ent (handent "${handle}"))
@@ -4172,7 +4423,8 @@ async function createHatch(patternName, boundary, scale = 1, angle = 0) {
4172
4423
  if (!cad.connected) {
4173
4424
  await cad.connect();
4174
4425
  }
4175
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4426
+ if (!cad.connected)
4427
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4176
4428
  const code = `(progn
4177
4429
  (vl-load-com)
4178
4430
  (command "._BHATCH" "p" "${patternName}" "s" "s" "sc" ${scale} "an" ${angle} "")
@@ -4192,12 +4444,17 @@ async function setHatchProperties(handle, props) {
4192
4444
  if (!cad.connected) {
4193
4445
  await cad.connect();
4194
4446
  }
4195
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4447
+ if (!cad.connected)
4448
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4196
4449
  let propCode = "";
4197
- if (props.pattern) propCode += `(command "._HATCHEDIT" "${handle}" "p" "${props.pattern}")`;
4198
- if (props.scale) propCode += `(command "._HATCHEDIT" "${handle}" "s" ${props.scale})`;
4199
- if (props.angle) propCode += `(command "._HATCHEDIT" "${handle}" "an" ${props.angle})`;
4200
- if (props.color) propCode += `(command "._HATCHEDIT" "${handle}" "c" ${props.color})`;
4450
+ if (props.pattern)
4451
+ propCode += `(command "._HATCHEDIT" "${handle}" "p" "${props.pattern}")`;
4452
+ if (props.scale)
4453
+ propCode += `(command "._HATCHEDIT" "${handle}" "s" ${props.scale})`;
4454
+ if (props.angle)
4455
+ propCode += `(command "._HATCHEDIT" "${handle}" "an" ${props.angle})`;
4456
+ if (props.color)
4457
+ propCode += `(command "._HATCHEDIT" "${handle}" "c" ${props.color})`;
4201
4458
  const code = `(progn
4202
4459
  (vl-load-com)
4203
4460
  ${propCode}
@@ -4214,7 +4471,8 @@ async function getBlockAttributes(blockHandle) {
4214
4471
  if (!cad.connected) {
4215
4472
  await cad.connect();
4216
4473
  }
4217
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4474
+ if (!cad.connected)
4475
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4218
4476
  const code = `(progn
4219
4477
  (vl-load-com)
4220
4478
  (if (setq ent (handent "${blockHandle}"))
@@ -4243,7 +4501,8 @@ async function setBlockAttribute(blockHandle, tag, value) {
4243
4501
  if (!cad.connected) {
4244
4502
  await cad.connect();
4245
4503
  }
4246
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4504
+ if (!cad.connected)
4505
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4247
4506
  const code = `(progn
4248
4507
  (vl-load-com)
4249
4508
  (if (setq ent (handent "${blockHandle}"))
@@ -4279,7 +4538,8 @@ async function zoomToExtents() {
4279
4538
  if (!cad.connected) {
4280
4539
  await cad.connect();
4281
4540
  }
4282
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4541
+ if (!cad.connected)
4542
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4283
4543
  const code = `(progn
4284
4544
  (vl-load-com)
4285
4545
  (command "._ZOOM" "E")
@@ -4296,7 +4556,8 @@ async function zoomToWindow(p1, p2) {
4296
4556
  if (!cad.connected) {
4297
4557
  await cad.connect();
4298
4558
  }
4299
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4559
+ if (!cad.connected)
4560
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4300
4561
  const code = `(command "._ZOOM" "W" (list ${p1}) (list ${p2}))`;
4301
4562
  try {
4302
4563
  await cad.sendCommand(code + "\n");
@@ -4309,7 +4570,8 @@ async function createNamedView(viewName, center = null) {
4309
4570
  if (!cad.connected) {
4310
4571
  await cad.connect();
4311
4572
  }
4312
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4573
+ if (!cad.connected)
4574
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4313
4575
  const code = center ? `(command ".-VIEW" "S" "${viewName}" "C" (list ${center}))` : `(command ".-VIEW" "S" "${viewName}")`;
4314
4576
  try {
4315
4577
  await cad.sendCommand(code + "\n");
@@ -4322,7 +4584,8 @@ async function restoreNamedView(viewName) {
4322
4584
  if (!cad.connected) {
4323
4585
  await cad.connect();
4324
4586
  }
4325
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4587
+ if (!cad.connected)
4588
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4326
4589
  const code = `(command ".-VIEW" "R" "${viewName}")`;
4327
4590
  try {
4328
4591
  await cad.sendCommand(code + "\n");
@@ -4335,7 +4598,8 @@ async function listNamedViews() {
4335
4598
  if (!cad.connected) {
4336
4599
  await cad.connect();
4337
4600
  }
4338
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4601
+ if (!cad.connected)
4602
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4339
4603
  const code = `(progn
4340
4604
  (vl-load-com)
4341
4605
  (setq views nil)
@@ -4355,7 +4619,8 @@ async function exportDxf(outputPath, version2 = "R2018") {
4355
4619
  if (!cad.connected) {
4356
4620
  await cad.connect();
4357
4621
  }
4358
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4622
+ if (!cad.connected)
4623
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4359
4624
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4360
4625
  const versionMap = {
4361
4626
  "R2018": "AC1027",
@@ -4386,7 +4651,8 @@ async function exportDwf(outputPath) {
4386
4651
  if (!cad.connected) {
4387
4652
  await cad.connect();
4388
4653
  }
4389
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4654
+ if (!cad.connected)
4655
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4390
4656
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4391
4657
  const code = `(progn
4392
4658
  (vl-load-com)
@@ -4407,7 +4673,8 @@ async function batchSetLayer(handles, layerName) {
4407
4673
  if (!cad.connected) {
4408
4674
  await cad.connect();
4409
4675
  }
4410
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4676
+ if (!cad.connected)
4677
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4411
4678
  if (!Array.isArray(handles) || handles.length === 0) {
4412
4679
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
4413
4680
  }
@@ -4432,7 +4699,8 @@ async function createUcs(name, origin = "0,0,0", xAxis = "1,0,0", yAxis = "0,1,0
4432
4699
  if (!cad.connected) {
4433
4700
  await cad.connect();
4434
4701
  }
4435
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4702
+ if (!cad.connected)
4703
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4436
4704
  const code = `(progn
4437
4705
  (vl-load-com)
4438
4706
  (if (not (tblsearch "UCS" "${name}"))
@@ -4463,7 +4731,8 @@ async function setUcs(name) {
4463
4731
  if (!cad.connected) {
4464
4732
  await cad.connect();
4465
4733
  }
4466
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4734
+ if (!cad.connected)
4735
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4467
4736
  const code = `(progn
4468
4737
  (vl-load-com)
4469
4738
  (if (tblsearch "UCS" "${name}")
@@ -4488,7 +4757,8 @@ async function listUcs() {
4488
4757
  if (!cad.connected) {
4489
4758
  await cad.connect();
4490
4759
  }
4491
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4760
+ if (!cad.connected)
4761
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4492
4762
  const code = `(progn
4493
4763
  (vl-load-com)
4494
4764
  (setq ucsList nil)
@@ -4511,7 +4781,8 @@ async function deleteUcs(name) {
4511
4781
  if (!cad.connected) {
4512
4782
  await cad.connect();
4513
4783
  }
4514
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4784
+ if (!cad.connected)
4785
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4515
4786
  const code = `(progn
4516
4787
  (vl-load-com)
4517
4788
  (if (tblsearch "UCS" "${name}")
@@ -4536,7 +4807,8 @@ async function getCurrentUcs() {
4536
4807
  if (!cad.connected) {
4537
4808
  await cad.connect();
4538
4809
  }
4539
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4810
+ if (!cad.connected)
4811
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4540
4812
  const code = `(progn
4541
4813
  (vl-load-com)
4542
4814
  (vla-get-activeutilities (vla-get-document (vla-get-application (vlax-get-acad-object))))
@@ -4553,7 +4825,8 @@ async function createLayout(name) {
4553
4825
  if (!cad.connected) {
4554
4826
  await cad.connect();
4555
4827
  }
4556
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4828
+ if (!cad.connected)
4829
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4557
4830
  const code = `(progn
4558
4831
  (vl-load-com)
4559
4832
  (if (not (tblsearch "LAYOUT" "${name}"))
@@ -4581,7 +4854,8 @@ async function setLayout(name) {
4581
4854
  if (!cad.connected) {
4582
4855
  await cad.connect();
4583
4856
  }
4584
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4857
+ if (!cad.connected)
4858
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4585
4859
  const code = `(progn
4586
4860
  (vl-load-com)
4587
4861
  (vlax-for layout (vla-get-layouts (vla-get-activedocument (vla-get-application (vlax-get-acad-object))))
@@ -4611,7 +4885,8 @@ async function listLayouts() {
4611
4885
  if (!cad.connected) {
4612
4886
  await cad.connect();
4613
4887
  }
4614
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4888
+ if (!cad.connected)
4889
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4615
4890
  const code = `(progn
4616
4891
  (vl-load-com)
4617
4892
  (setq layouts nil)
@@ -4634,7 +4909,8 @@ async function deleteLayout(name) {
4634
4909
  if (!cad.connected) {
4635
4910
  await cad.connect();
4636
4911
  }
4637
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4912
+ if (!cad.connected)
4913
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4638
4914
  if (name === "Model" || name === "\u6A21\u578B") {
4639
4915
  return { content: [{ type: "text", text: "\u65E0\u6CD5\u5220\u9664\u6A21\u578B\u7A7A\u95F4" }], isError: true };
4640
4916
  }
@@ -4662,7 +4938,8 @@ async function getCurrentLayout() {
4662
4938
  if (!cad.connected) {
4663
4939
  await cad.connect();
4664
4940
  }
4665
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4941
+ if (!cad.connected)
4942
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4666
4943
  const code = `(vl-prin1-to-string (getvar "CTAB"))`;
4667
4944
  try {
4668
4945
  const result = await cad.sendCommandWithResult(code);
@@ -4675,7 +4952,8 @@ async function renameLayout(oldName, newName) {
4675
4952
  if (!cad.connected) {
4676
4953
  await cad.connect();
4677
4954
  }
4678
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4955
+ if (!cad.connected)
4956
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4679
4957
  const code = `(progn
4680
4958
  (vl-load-com)
4681
4959
  (if (tblsearch "LAYOUT" "${oldName}")
@@ -4702,7 +4980,8 @@ async function plotToPdf(outputPath, layout = "Model", style = {}) {
4702
4980
  if (!cad.connected) {
4703
4981
  await cad.connect();
4704
4982
  }
4705
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4983
+ if (!cad.connected)
4984
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4706
4985
  const normalizedPath = outputPath.replace(/\\/g, "\\\\");
4707
4986
  const paperSize = style.paperSize || "A4";
4708
4987
  const plotScale = style.plotScale || "1:1";
@@ -4735,7 +5014,8 @@ async function plotToPrinter(printerName, layout = "Model") {
4735
5014
  if (!cad.connected) {
4736
5015
  await cad.connect();
4737
5016
  }
4738
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5017
+ if (!cad.connected)
5018
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4739
5019
  const code = `(progn
4740
5020
  (vl-load-com)
4741
5021
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
@@ -4761,7 +5041,8 @@ async function createGroup(name, handles) {
4761
5041
  if (!cad.connected) {
4762
5042
  await cad.connect();
4763
5043
  }
4764
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5044
+ if (!cad.connected)
5045
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4765
5046
  if (!Array.isArray(handles) || handles.length === 0) {
4766
5047
  return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
4767
5048
  }
@@ -4787,7 +5068,8 @@ async function deleteGroup(name) {
4787
5068
  if (!cad.connected) {
4788
5069
  await cad.connect();
4789
5070
  }
4790
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5071
+ if (!cad.connected)
5072
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4791
5073
  const code = `(progn
4792
5074
  (vl-load-com)
4793
5075
  (if (tblsearch "GROUP" "${name}")
@@ -4812,7 +5094,8 @@ async function listGroups() {
4812
5094
  if (!cad.connected) {
4813
5095
  await cad.connect();
4814
5096
  }
4815
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5097
+ if (!cad.connected)
5098
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4816
5099
  const code = `(progn
4817
5100
  (vl-load-com)
4818
5101
  (setq groups nil)
@@ -4832,7 +5115,8 @@ async function getGroupEntities(groupName) {
4832
5115
  if (!cad.connected) {
4833
5116
  await cad.connect();
4834
5117
  }
4835
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5118
+ if (!cad.connected)
5119
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4836
5120
  const code = `(progn
4837
5121
  (vl-load-com)
4838
5122
  (if (tblsearch "GROUP" "${groupName}")
@@ -4870,7 +5154,8 @@ async function measureDistance(p1, p2) {
4870
5154
  if (!cad.connected) {
4871
5155
  await cad.connect();
4872
5156
  }
4873
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5157
+ if (!cad.connected)
5158
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4874
5159
  const code = `(progn
4875
5160
  (vl-load-com)
4876
5161
  (setq pt1 (list ${p1}) pt2 (list ${p2}))
@@ -4894,7 +5179,8 @@ async function measureArea(points) {
4894
5179
  if (!cad.connected) {
4895
5180
  await cad.connect();
4896
5181
  }
4897
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5182
+ if (!cad.connected)
5183
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4898
5184
  const pts = Array.isArray(points) ? points : points.split(/[\s,]+/).filter(Boolean);
4899
5185
  if (pts.length < 3) {
4900
5186
  return { content: [{ type: "text", text: "\u81F3\u5C11\u9700\u8981 3 \u4E2A\u70B9" }], isError: true };
@@ -4931,7 +5217,8 @@ async function getEntityInfo(handle) {
4931
5217
  if (!cad.connected) {
4932
5218
  await cad.connect();
4933
5219
  }
4934
- if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
5220
+ if (!cad.connected)
5221
+ return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
4935
5222
  const code = `(progn
4936
5223
  (vl-load-com)
4937
5224
  (if (setq ent (handent "${handle}"))
@@ -4966,7 +5253,8 @@ async function ensureConnected() {
4966
5253
  if (!cad.connected) {
4967
5254
  await cad.connect();
4968
5255
  }
4969
- if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5256
+ if (!cad.connected)
5257
+ throw new Error("CAD \u672A\u8FDE\u63A5");
4970
5258
  }
4971
5259
  function parseHandleList(handles) {
4972
5260
  if (typeof handles === "string") {
@@ -5207,7 +5495,8 @@ async function ensureConnected2() {
5207
5495
  if (!cad.connected) {
5208
5496
  await cad.connect();
5209
5497
  }
5210
- if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5498
+ if (!cad.connected)
5499
+ throw new Error("CAD \u672A\u8FDE\u63A5");
5211
5500
  }
5212
5501
  async function getXdata(handle, appName = "ACAD") {
5213
5502
  await ensureConnected2();
@@ -5413,10 +5702,11 @@ async function searchByXdata(appName, key, value) {
5413
5702
  async function exportXdataToFile(handle, filePath) {
5414
5703
  await ensureConnected2();
5415
5704
  const xdata = await getAllEntityXdata(handle);
5416
- if (!xdata.success) return xdata;
5705
+ if (!xdata.success)
5706
+ return xdata;
5417
5707
  try {
5418
- const fs8 = await import("fs");
5419
- fs8.writeFileSync(filePath, JSON.stringify(xdata.xdata, null, 2));
5708
+ const fs9 = await import("fs");
5709
+ fs9.writeFileSync(filePath, JSON.stringify(xdata.xdata, null, 2));
5420
5710
  return { handle, filePath, success: true };
5421
5711
  } catch (e) {
5422
5712
  return { error: e.message, success: false };
@@ -5425,8 +5715,8 @@ async function exportXdataToFile(handle, filePath) {
5425
5715
  async function importXdataFromFile(handle, filePath, appName) {
5426
5716
  await ensureConnected2();
5427
5717
  try {
5428
- const fs8 = await import("fs");
5429
- const data = fs8.readFileSync(filePath, "utf8");
5718
+ const fs9 = await import("fs");
5719
+ const data = fs9.readFileSync(filePath, "utf8");
5430
5720
  const xdata = JSON.parse(data);
5431
5721
  if (appName && xdata[appName]) {
5432
5722
  return await setXdata(handle, appName, xdata[appName]);
@@ -5446,7 +5736,8 @@ async function ensureConnected3() {
5446
5736
  if (!cad.connected) {
5447
5737
  await cad.connect();
5448
5738
  }
5449
- if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5739
+ if (!cad.connected)
5740
+ throw new Error("CAD \u672A\u8FDE\u63A5");
5450
5741
  }
5451
5742
  async function createSheetSet(name, description = "") {
5452
5743
  await ensureConnected3();
@@ -5647,11 +5938,14 @@ async function ensureConnected4() {
5647
5938
  if (!cad.connected) {
5648
5939
  await cad.connect();
5649
5940
  }
5650
- if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
5941
+ if (!cad.connected)
5942
+ throw new Error("CAD \u672A\u8FDE\u63A5");
5651
5943
  }
5652
5944
  function parsePoint(point) {
5653
- if (Array.isArray(point)) return point.join(" ");
5654
- if (typeof point === "string") return point;
5945
+ if (Array.isArray(point))
5946
+ return point.join(" ");
5947
+ if (typeof point === "string")
5948
+ return point;
5655
5949
  return "0,0,0";
5656
5950
  }
5657
5951
  async function createBox(center, length, width, height) {
@@ -5911,7 +6205,8 @@ async function ensureConnected5() {
5911
6205
  if (!cad.connected) {
5912
6206
  await cad.connect();
5913
6207
  }
5914
- if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
6208
+ if (!cad.connected)
6209
+ throw new Error("CAD \u672A\u8FDE\u63A5");
5915
6210
  }
5916
6211
  async function createDimensionStyle(name, color = "bylayer", arrow = "ClosedFilled", textStyle = "") {
5917
6212
  await ensureConnected5();
@@ -6137,7 +6432,8 @@ async function ensureConnected6() {
6137
6432
  if (!cad.connected) {
6138
6433
  await cad.connect();
6139
6434
  }
6140
- if (!cad.connected) throw new Error("CAD \u672A\u8FDE\u63A5");
6435
+ if (!cad.connected)
6436
+ throw new Error("CAD \u672A\u8FDE\u63A5");
6141
6437
  }
6142
6438
  async function attachPdf(point, pdfPath, scale = 1, rotation = 0) {
6143
6439
  await ensureConnected6();
@@ -6577,7 +6873,8 @@ function validateToolArgs(name, args) {
6577
6873
  const baseType = type.replace("?", "");
6578
6874
  const val = args[key];
6579
6875
  if (val === void 0 || val === null) {
6580
- if (isOptional) continue;
6876
+ if (isOptional)
6877
+ continue;
6581
6878
  throw new Error(`Missing required argument: ${key}`);
6582
6879
  }
6583
6880
  const actualType = typeof args[key];
@@ -6622,7 +6919,8 @@ ${CAD_PLATFORMS.join("\n")}
6622
6919
  },
6623
6920
  import_funlib: async (a) => {
6624
6921
  const data = await loadAtlibFunctionLib();
6625
- if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
6922
+ if (!data)
6923
+ return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
6626
6924
  if (a.format === "list") {
6627
6925
  const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
6628
6926
  return { content: [{ type: "text", text: items.join("\n") }] };
@@ -8447,7 +8745,8 @@ function notifyResourceChanges(toolName) {
8447
8745
  }
8448
8746
  async function handleToolCall(name, args) {
8449
8747
  const handler = TOOL_HANDLERS[name];
8450
- if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8748
+ if (!handler)
8749
+ return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
8451
8750
  try {
8452
8751
  validateToolArgs(name, args || {});
8453
8752
  const result = await handler(args || {});
@@ -8507,10 +8806,12 @@ var RateLimiter = class {
8507
8806
  this.keyLimits = /* @__PURE__ */ new Map();
8508
8807
  }
8509
8808
  getKeyLimit(apiKey2) {
8510
- if (!apiKey2) return this.defaultLimit;
8809
+ if (!apiKey2)
8810
+ return this.defaultLimit;
8511
8811
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8512
8812
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8513
- if (found) return found.limit;
8813
+ if (found)
8814
+ return found.limit;
8514
8815
  }
8515
8816
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8516
8817
  return config_default.apiKeyRateLimit || 1e3;
@@ -8518,10 +8819,12 @@ var RateLimiter = class {
8518
8819
  return this.defaultLimit;
8519
8820
  }
8520
8821
  getKeyInfo(apiKey2) {
8521
- if (!apiKey2) return { name: "anonymous", limit: this.defaultLimit };
8822
+ if (!apiKey2)
8823
+ return { name: "anonymous", limit: this.defaultLimit };
8522
8824
  if (config_default.apiKeys && config_default.apiKeys.length > 0) {
8523
8825
  const found = config_default.apiKeys.find((k) => k.key === apiKey2);
8524
- if (found) return { name: found.name || apiKey2, limit: found.limit };
8826
+ if (found)
8827
+ return { name: found.name || apiKey2, limit: found.limit };
8525
8828
  }
8526
8829
  if (config_default.apiKey && apiKey2 === config_default.apiKey) {
8527
8830
  return { name: "admin", limit: config_default.apiKeyRateLimit || 1e3 };
@@ -8617,7 +8920,8 @@ var JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "applicati
8617
8920
  function createJsonBodyParser() {
8618
8921
  return async (req, res, next) => {
8619
8922
  const ct = (req.headers["content-type"] || "").toLowerCase();
8620
- if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
8923
+ if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
8924
+ return next();
8621
8925
  try {
8622
8926
  const chunks = [];
8623
8927
  for await (const chunk of req) {
@@ -8650,9 +8954,11 @@ function createAuthMiddleware() {
8650
8954
  const PUBLIC_PATHS = ["/health"];
8651
8955
  return (req, res, next) => {
8652
8956
  if (apiKey) {
8653
- if (PUBLIC_PATHS.includes(req.path)) return next();
8957
+ if (PUBLIC_PATHS.includes(req.path))
8958
+ return next();
8654
8959
  const auth = req.get("Authorization");
8655
- if (auth === `Bearer ${apiKey}`) return next();
8960
+ if (auth === `Bearer ${apiKey}`)
8961
+ return next();
8656
8962
  return res.status(401).json({ error: "Unauthorized" });
8657
8963
  }
8658
8964
  next();
@@ -8660,14 +8966,16 @@ function createAuthMiddleware() {
8660
8966
  }
8661
8967
  function createCorsMiddleware() {
8662
8968
  return (req, res, next) => {
8663
- if (!enableCors) return next();
8969
+ if (!enableCors)
8970
+ return next();
8664
8971
  res.setHeader("Access-Control-Allow-Origin", corsOrigin);
8665
8972
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, CONNECT");
8666
8973
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, mcp-session-id, last-event-id");
8667
8974
  res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
8668
8975
  res.setHeader("Access-Control-Max-Age", "86400");
8669
8976
  res.setHeader("Vary", "Accept");
8670
- if (req.method === "OPTIONS") return res.status(204).end();
8977
+ if (req.method === "OPTIONS")
8978
+ return res.status(204).end();
8671
8979
  next();
8672
8980
  };
8673
8981
  }
@@ -9029,7 +9337,7 @@ Options:
9029
9337
  --port <port> HTTP port (default: 8110)
9030
9338
  --host <host> HTTP host (default: 0.0.0.0)
9031
9339
  --stdio Shorthand for --transport stdio
9032
- --config <path> Path to config file (default: ~/.@lisp/atlisp.config.json)
9340
+ --config <path> Path to config file (default: ~/.atlisp/atlisp.config.json)
9033
9341
  --debug Enable debug mode
9034
9342
 
9035
9343
  Environment Variables:
@@ -9079,7 +9387,8 @@ For more info: https://atlisp.cn
9079
9387
  }
9080
9388
  }
9081
9389
  }
9082
- if (config_default.apiKey) log("API Key authentication enabled");
9390
+ if (config_default.apiKey)
9391
+ log("API Key authentication enabled");
9083
9392
  async function initCadConnection() {
9084
9393
  log("Attempting to connect to CAD on startup...");
9085
9394
  try {