@atlisp/mcp 1.8.2 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atlisp-mcp.js +527 -287
- package/package.json +1 -1
package/dist/atlisp-mcp.js
CHANGED
|
@@ -70,7 +70,8 @@ function parseArgs() {
|
|
|
70
70
|
return result;
|
|
71
71
|
}
|
|
72
72
|
function loadConfigFile(filePath) {
|
|
73
|
-
if (!filePath || !fs.existsSync(filePath))
|
|
73
|
+
if (!filePath || !fs.existsSync(filePath))
|
|
74
|
+
return null;
|
|
74
75
|
try {
|
|
75
76
|
const raw = fs.readFileSync(filePath, "utf-8");
|
|
76
77
|
const parsed = JSON.parse(raw);
|
|
@@ -226,7 +227,8 @@ function onDocumentChanged(callback) {
|
|
|
226
227
|
_docChangeCallbacks.push(callback);
|
|
227
228
|
}
|
|
228
229
|
function emitDocumentChanged(info) {
|
|
229
|
-
if (info.docName === _activeDocName)
|
|
230
|
+
if (info.docName === _activeDocName)
|
|
231
|
+
return;
|
|
230
232
|
_activeDocName = info.docName || "";
|
|
231
233
|
for (const cb of _docChangeCallbacks) {
|
|
232
234
|
try {
|
|
@@ -285,7 +287,8 @@ function setupStdoutHandler(w) {
|
|
|
285
287
|
const lines = buffer.split("\n");
|
|
286
288
|
buffer = lines.pop() || "";
|
|
287
289
|
for (const line of lines) {
|
|
288
|
-
if (!line.trim())
|
|
290
|
+
if (!line.trim())
|
|
291
|
+
continue;
|
|
289
292
|
try {
|
|
290
293
|
const result = JSON.parse(line);
|
|
291
294
|
const rid = result.requestId;
|
|
@@ -313,7 +316,8 @@ function setupStdoutHandler(w) {
|
|
|
313
316
|
}
|
|
314
317
|
function getWorker(force = false) {
|
|
315
318
|
if (!worker || !worker.connected || force) {
|
|
316
|
-
if (worker)
|
|
319
|
+
if (worker)
|
|
320
|
+
worker.kill();
|
|
317
321
|
worker = spawn("node", [workerPath], {
|
|
318
322
|
stdio: ["pipe", "pipe", "pipe"]
|
|
319
323
|
});
|
|
@@ -321,7 +325,8 @@ function getWorker(force = false) {
|
|
|
321
325
|
const w = worker;
|
|
322
326
|
w.on("exit", (code) => {
|
|
323
327
|
console.error("worker exited with code:", code);
|
|
324
|
-
if (w !== worker)
|
|
328
|
+
if (w !== worker)
|
|
329
|
+
return;
|
|
325
330
|
w.connected = false;
|
|
326
331
|
for (const [id, { reject, timeout }] of pendingRequests) {
|
|
327
332
|
clearTimeout(timeout);
|
|
@@ -342,7 +347,8 @@ function getWorker(force = false) {
|
|
|
342
347
|
return worker;
|
|
343
348
|
}
|
|
344
349
|
function startHeartbeat() {
|
|
345
|
-
if (heartbeatTimer)
|
|
350
|
+
if (heartbeatTimer)
|
|
351
|
+
clearInterval(heartbeatTimer);
|
|
346
352
|
heartbeatTimer = setInterval(async () => {
|
|
347
353
|
try {
|
|
348
354
|
const result = await sendMessage({ type: "ping" });
|
|
@@ -443,13 +449,16 @@ var init_cad = __esm({
|
|
|
443
449
|
return null;
|
|
444
450
|
}
|
|
445
451
|
async _process() {
|
|
446
|
-
if (this.#processing)
|
|
452
|
+
if (this.#processing)
|
|
453
|
+
return;
|
|
447
454
|
this.#processing = true;
|
|
448
455
|
while (this._hasPending()) {
|
|
449
456
|
const cmd = this._dequeue();
|
|
450
|
-
if (!cmd)
|
|
457
|
+
if (!cmd)
|
|
458
|
+
continue;
|
|
451
459
|
const dedupKey = this._dedupKey(cmd);
|
|
452
|
-
if (dedupKey)
|
|
460
|
+
if (dedupKey)
|
|
461
|
+
this.#dedupMap.delete(dedupKey);
|
|
453
462
|
try {
|
|
454
463
|
const result = await sendMessage(cmd);
|
|
455
464
|
cmd.resolve(result);
|
|
@@ -464,7 +473,8 @@ var init_cad = __esm({
|
|
|
464
473
|
}
|
|
465
474
|
_dequeue() {
|
|
466
475
|
for (const q of this.#queues) {
|
|
467
|
-
if (q.length > 0)
|
|
476
|
+
if (q.length > 0)
|
|
477
|
+
return q.shift();
|
|
468
478
|
}
|
|
469
479
|
return null;
|
|
470
480
|
}
|
|
@@ -492,7 +502,8 @@ var init_cad = __esm({
|
|
|
492
502
|
return process.platform === "win32";
|
|
493
503
|
}
|
|
494
504
|
async connect(platform = null) {
|
|
495
|
-
if (!this.isAvailable())
|
|
505
|
+
if (!this.isAvailable())
|
|
506
|
+
return false;
|
|
496
507
|
try {
|
|
497
508
|
const msg = platform ? { type: "connect", platform } : { type: "connect" };
|
|
498
509
|
const result = await sendMessage(msg);
|
|
@@ -516,7 +527,8 @@ var init_cad = __esm({
|
|
|
516
527
|
return false;
|
|
517
528
|
}
|
|
518
529
|
async sendCommand(code) {
|
|
519
|
-
if (!this.connected)
|
|
530
|
+
if (!this.connected)
|
|
531
|
+
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
520
532
|
return new Promise((resolve, reject) => {
|
|
521
533
|
commandQueue.enqueue({
|
|
522
534
|
type: "send",
|
|
@@ -526,12 +538,14 @@ var init_cad = __esm({
|
|
|
526
538
|
reject
|
|
527
539
|
}, PRIORITY_NORMAL);
|
|
528
540
|
}).then((result) => {
|
|
529
|
-
if (result.success)
|
|
541
|
+
if (result.success)
|
|
542
|
+
return true;
|
|
530
543
|
throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
|
|
531
544
|
});
|
|
532
545
|
}
|
|
533
546
|
async sendCommandWithResult(code, encoding = null) {
|
|
534
|
-
if (!this.connected)
|
|
547
|
+
if (!this.connected)
|
|
548
|
+
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
535
549
|
return new Promise((resolve, reject) => {
|
|
536
550
|
commandQueue.enqueue({
|
|
537
551
|
type: "sendResult",
|
|
@@ -542,7 +556,8 @@ var init_cad = __esm({
|
|
|
542
556
|
reject
|
|
543
557
|
}, PRIORITY_NORMAL);
|
|
544
558
|
}).then((result) => {
|
|
545
|
-
if (result.success)
|
|
559
|
+
if (result.success)
|
|
560
|
+
return result.result || "";
|
|
546
561
|
throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
|
|
547
562
|
});
|
|
548
563
|
}
|
|
@@ -553,7 +568,8 @@ var init_cad = __esm({
|
|
|
553
568
|
return this.product;
|
|
554
569
|
}
|
|
555
570
|
async isBusy() {
|
|
556
|
-
if (!this.connected)
|
|
571
|
+
if (!this.connected)
|
|
572
|
+
return false;
|
|
557
573
|
try {
|
|
558
574
|
const result = await sendMessage({ type: "isBusy", platform: _platform });
|
|
559
575
|
return result && result.isBusy;
|
|
@@ -562,7 +578,8 @@ var init_cad = __esm({
|
|
|
562
578
|
}
|
|
563
579
|
}
|
|
564
580
|
async hasDoc() {
|
|
565
|
-
if (!this.connected)
|
|
581
|
+
if (!this.connected)
|
|
582
|
+
return { hasDoc: false, docCount: 0 };
|
|
566
583
|
try {
|
|
567
584
|
const result = await sendMessage({ type: "hasdoc", platform: _platform });
|
|
568
585
|
return result || { hasDoc: false, docCount: 0 };
|
|
@@ -571,7 +588,8 @@ var init_cad = __esm({
|
|
|
571
588
|
}
|
|
572
589
|
}
|
|
573
590
|
async newDoc() {
|
|
574
|
-
if (!this.connected)
|
|
591
|
+
if (!this.connected)
|
|
592
|
+
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
575
593
|
try {
|
|
576
594
|
const result = await sendMessage({ type: "newdoc", platform: _platform });
|
|
577
595
|
return result && result.success;
|
|
@@ -580,7 +598,8 @@ var init_cad = __esm({
|
|
|
580
598
|
}
|
|
581
599
|
}
|
|
582
600
|
async bringToFront() {
|
|
583
|
-
if (!this.connected)
|
|
601
|
+
if (!this.connected)
|
|
602
|
+
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
584
603
|
try {
|
|
585
604
|
const result = await sendMessage({ type: "bringToFront", platform: _platform });
|
|
586
605
|
return result && result.success;
|
|
@@ -589,7 +608,8 @@ var init_cad = __esm({
|
|
|
589
608
|
}
|
|
590
609
|
}
|
|
591
610
|
async getActiveDocInfo() {
|
|
592
|
-
if (!this.connected)
|
|
611
|
+
if (!this.connected)
|
|
612
|
+
return { docName: "", docPath: "", docCount: 0 };
|
|
593
613
|
try {
|
|
594
614
|
const result = await sendMessage({ type: "getActiveDocInfo", platform: _platform });
|
|
595
615
|
return result || { docName: "", docPath: "", docCount: 0 };
|
|
@@ -598,7 +618,8 @@ var init_cad = __esm({
|
|
|
598
618
|
}
|
|
599
619
|
}
|
|
600
620
|
async getInfo() {
|
|
601
|
-
if (!this.connected)
|
|
621
|
+
if (!this.connected)
|
|
622
|
+
return "CAD \u672A\u8FDE\u63A5";
|
|
602
623
|
return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
|
|
603
624
|
}
|
|
604
625
|
async disconnect() {
|
|
@@ -643,14 +664,16 @@ __export(renderer_exports, {
|
|
|
643
664
|
renderTemplate: () => renderTemplate
|
|
644
665
|
});
|
|
645
666
|
function escapeLispString2(str) {
|
|
646
|
-
if (typeof str !== "string")
|
|
667
|
+
if (typeof str !== "string")
|
|
668
|
+
return "";
|
|
647
669
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
648
670
|
}
|
|
649
671
|
function resolvePath(obj, path12) {
|
|
650
672
|
const parts = path12.split(/[.\[\]]/g).filter(Boolean);
|
|
651
673
|
let val = obj;
|
|
652
674
|
for (const p of parts) {
|
|
653
|
-
if (val == null)
|
|
675
|
+
if (val == null)
|
|
676
|
+
return void 0;
|
|
654
677
|
val = val[p];
|
|
655
678
|
}
|
|
656
679
|
return val;
|
|
@@ -659,9 +682,11 @@ function renderTemplate(template, args) {
|
|
|
659
682
|
return template.replace(PARAM_RE, (match, rawExpr, expr) => {
|
|
660
683
|
const path12 = rawExpr || expr;
|
|
661
684
|
const val = resolvePath(args, path12);
|
|
662
|
-
if (val == null)
|
|
685
|
+
if (val == null)
|
|
686
|
+
return "";
|
|
663
687
|
const strVal = String(val);
|
|
664
|
-
if (rawExpr)
|
|
688
|
+
if (rawExpr)
|
|
689
|
+
return strVal;
|
|
665
690
|
return escapeLispString2(strVal);
|
|
666
691
|
});
|
|
667
692
|
}
|
|
@@ -720,8 +745,9 @@ import express2 from "express";
|
|
|
720
745
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
721
746
|
|
|
722
747
|
// src/logger.js
|
|
723
|
-
import fs2 from "fs";
|
|
724
748
|
init_config();
|
|
749
|
+
import fs2 from "fs";
|
|
750
|
+
import fsp from "fs/promises";
|
|
725
751
|
import path3 from "path";
|
|
726
752
|
import os2 from "os";
|
|
727
753
|
var DEBUG_FILE = config_default.debugFile || path3.join(os2.tmpdir(), "mcp-server-debug.log");
|
|
@@ -730,9 +756,11 @@ var MAX_LOG_FILES = 5;
|
|
|
730
756
|
var stream = null;
|
|
731
757
|
function rotateLog() {
|
|
732
758
|
try {
|
|
733
|
-
if (!fs2.existsSync(DEBUG_FILE))
|
|
759
|
+
if (!fs2.existsSync(DEBUG_FILE))
|
|
760
|
+
return;
|
|
734
761
|
const stat = fs2.statSync(DEBUG_FILE);
|
|
735
|
-
if (stat.size < MAX_LOG_SIZE)
|
|
762
|
+
if (stat.size < MAX_LOG_SIZE)
|
|
763
|
+
return;
|
|
736
764
|
if (stream) {
|
|
737
765
|
stream.end();
|
|
738
766
|
stream = null;
|
|
@@ -806,9 +834,11 @@ function ensureRequestLogDir() {
|
|
|
806
834
|
}
|
|
807
835
|
function rotateRequestLog() {
|
|
808
836
|
try {
|
|
809
|
-
if (!fs2.existsSync(REQUEST_LOG_FILE))
|
|
837
|
+
if (!fs2.existsSync(REQUEST_LOG_FILE))
|
|
838
|
+
return;
|
|
810
839
|
const stat = fs2.statSync(REQUEST_LOG_FILE);
|
|
811
|
-
if (stat.size < 10 * 1024 * 1024)
|
|
840
|
+
if (stat.size < 10 * 1024 * 1024)
|
|
841
|
+
return;
|
|
812
842
|
if (requestStream) {
|
|
813
843
|
requestStream.end();
|
|
814
844
|
requestStream = null;
|
|
@@ -833,7 +863,8 @@ function rotateRequestLog() {
|
|
|
833
863
|
}
|
|
834
864
|
}
|
|
835
865
|
function logRequest(req) {
|
|
836
|
-
if (!config_default.requestLogEnabled)
|
|
866
|
+
if (!config_default.requestLogEnabled)
|
|
867
|
+
return;
|
|
837
868
|
try {
|
|
838
869
|
ensureRequestLogDir();
|
|
839
870
|
rotateRequestLog();
|
|
@@ -854,7 +885,8 @@ function logRequest(req) {
|
|
|
854
885
|
}
|
|
855
886
|
}
|
|
856
887
|
function logResponse(req, res, duration) {
|
|
857
|
-
if (!config_default.requestLogEnabled)
|
|
888
|
+
if (!config_default.requestLogEnabled)
|
|
889
|
+
return;
|
|
858
890
|
try {
|
|
859
891
|
ensureRequestLogDir();
|
|
860
892
|
if (!requestStream) {
|
|
@@ -1033,21 +1065,27 @@ async function ensureCadConnected() {
|
|
|
1033
1065
|
}
|
|
1034
1066
|
}
|
|
1035
1067
|
function escapeLispString(str) {
|
|
1036
|
-
if (typeof str !== "string")
|
|
1068
|
+
if (typeof str !== "string")
|
|
1069
|
+
return "";
|
|
1037
1070
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
1038
1071
|
}
|
|
1039
1072
|
function tryNumber(val) {
|
|
1040
|
-
if (typeof val === "number")
|
|
1073
|
+
if (typeof val === "number")
|
|
1074
|
+
return val;
|
|
1041
1075
|
const n = Number(val);
|
|
1042
|
-
if (!isNaN(n) && val !== "")
|
|
1076
|
+
if (!isNaN(n) && val !== "")
|
|
1077
|
+
return n;
|
|
1043
1078
|
return val;
|
|
1044
1079
|
}
|
|
1045
1080
|
function parseLispList(str) {
|
|
1046
|
-
if (!str || typeof str !== "string")
|
|
1081
|
+
if (!str || typeof str !== "string")
|
|
1082
|
+
return null;
|
|
1047
1083
|
const trimmed = str.trim();
|
|
1048
|
-
if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
|
|
1084
|
+
if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
|
|
1085
|
+
return null;
|
|
1049
1086
|
const content = trimmed.slice(1, -1).trim();
|
|
1050
|
-
if (!content)
|
|
1087
|
+
if (!content)
|
|
1088
|
+
return [];
|
|
1051
1089
|
const result = [];
|
|
1052
1090
|
let depth = 0;
|
|
1053
1091
|
let current = "";
|
|
@@ -1089,29 +1127,39 @@ function parseLispList(str) {
|
|
|
1089
1127
|
}
|
|
1090
1128
|
current += ch;
|
|
1091
1129
|
}
|
|
1092
|
-
if (current.trim())
|
|
1130
|
+
if (current.trim())
|
|
1131
|
+
result.push(current.trim());
|
|
1093
1132
|
return result.map((item) => {
|
|
1094
1133
|
const t = item.trim();
|
|
1095
|
-
if (t === "nil" || t === "NIL")
|
|
1096
|
-
|
|
1097
|
-
if (t
|
|
1134
|
+
if (t === "nil" || t === "NIL")
|
|
1135
|
+
return null;
|
|
1136
|
+
if (t === "t" || t === "T")
|
|
1137
|
+
return true;
|
|
1138
|
+
if (t.startsWith('"') && t.endsWith('"'))
|
|
1139
|
+
return t.slice(1, -1);
|
|
1098
1140
|
return tryNumber(t);
|
|
1099
1141
|
});
|
|
1100
1142
|
}
|
|
1101
1143
|
function parseLispRecursive(str) {
|
|
1102
|
-
if (!str || typeof str !== "string")
|
|
1144
|
+
if (!str || typeof str !== "string")
|
|
1145
|
+
return null;
|
|
1103
1146
|
str = str.trim();
|
|
1104
|
-
if (!str)
|
|
1147
|
+
if (!str)
|
|
1148
|
+
return null;
|
|
1105
1149
|
let pos = 0;
|
|
1106
1150
|
function skipWs() {
|
|
1107
|
-
while (pos < str.length && /\s/.test(str[pos]))
|
|
1151
|
+
while (pos < str.length && /\s/.test(str[pos]))
|
|
1152
|
+
pos++;
|
|
1108
1153
|
}
|
|
1109
1154
|
function parseValue() {
|
|
1110
1155
|
skipWs();
|
|
1111
|
-
if (pos >= str.length)
|
|
1156
|
+
if (pos >= str.length)
|
|
1157
|
+
return null;
|
|
1112
1158
|
const ch = str[pos];
|
|
1113
|
-
if (ch === "(")
|
|
1114
|
-
|
|
1159
|
+
if (ch === "(")
|
|
1160
|
+
return parseList();
|
|
1161
|
+
if (ch === '"')
|
|
1162
|
+
return parseString();
|
|
1115
1163
|
if (ch === "'") {
|
|
1116
1164
|
pos++;
|
|
1117
1165
|
return parseValue();
|
|
@@ -1124,11 +1172,16 @@ function parseLispRecursive(str) {
|
|
|
1124
1172
|
while (pos < str.length && str[pos] !== '"') {
|
|
1125
1173
|
if (str[pos] === "\\" && pos + 1 < str.length) {
|
|
1126
1174
|
pos++;
|
|
1127
|
-
if (str[pos] === '"')
|
|
1128
|
-
|
|
1129
|
-
else if (str[pos] === "
|
|
1130
|
-
|
|
1131
|
-
else
|
|
1175
|
+
if (str[pos] === '"')
|
|
1176
|
+
r += '"';
|
|
1177
|
+
else if (str[pos] === "n")
|
|
1178
|
+
r += "\n";
|
|
1179
|
+
else if (str[pos] === "t")
|
|
1180
|
+
r += " ";
|
|
1181
|
+
else if (str[pos] === "\\")
|
|
1182
|
+
r += "\\";
|
|
1183
|
+
else
|
|
1184
|
+
r += str[pos];
|
|
1132
1185
|
} else {
|
|
1133
1186
|
r += str[pos];
|
|
1134
1187
|
}
|
|
@@ -1139,10 +1192,13 @@ function parseLispRecursive(str) {
|
|
|
1139
1192
|
}
|
|
1140
1193
|
function parseAtom() {
|
|
1141
1194
|
const start = pos;
|
|
1142
|
-
while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
|
|
1195
|
+
while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
|
|
1196
|
+
pos++;
|
|
1143
1197
|
const atom = str.slice(start, pos);
|
|
1144
|
-
if (atom === "nil" || atom === "NIL")
|
|
1145
|
-
|
|
1198
|
+
if (atom === "nil" || atom === "NIL")
|
|
1199
|
+
return null;
|
|
1200
|
+
if (atom === "t" || atom === "T")
|
|
1201
|
+
return true;
|
|
1146
1202
|
return tryNumber(atom);
|
|
1147
1203
|
}
|
|
1148
1204
|
function parseList() {
|
|
@@ -1150,13 +1206,15 @@ function parseLispRecursive(str) {
|
|
|
1150
1206
|
const items = [];
|
|
1151
1207
|
while (pos < str.length) {
|
|
1152
1208
|
skipWs();
|
|
1153
|
-
if (pos >= str.length)
|
|
1209
|
+
if (pos >= str.length)
|
|
1210
|
+
break;
|
|
1154
1211
|
if (str[pos] === ")") {
|
|
1155
1212
|
pos++;
|
|
1156
1213
|
return items;
|
|
1157
1214
|
}
|
|
1158
1215
|
const left = parseValue();
|
|
1159
|
-
if (left === void 0)
|
|
1216
|
+
if (left === void 0)
|
|
1217
|
+
break;
|
|
1160
1218
|
skipWs();
|
|
1161
1219
|
if (str[pos] === "." && (pos + 1 >= str.length || /\s/.test(str[pos + 1]) || str[pos + 1] === ")")) {
|
|
1162
1220
|
pos++;
|
|
@@ -1233,7 +1291,8 @@ var ENTITY_PROPERTIES_LISP = `
|
|
|
1233
1291
|
result)
|
|
1234
1292
|
`;
|
|
1235
1293
|
function propertyPairsToObject(pairs) {
|
|
1236
|
-
if (!Array.isArray(pairs))
|
|
1294
|
+
if (!Array.isArray(pairs))
|
|
1295
|
+
return null;
|
|
1237
1296
|
const obj = {};
|
|
1238
1297
|
for (const pair of pairs) {
|
|
1239
1298
|
if (Array.isArray(pair) && pair.length >= 2) {
|
|
@@ -1244,8 +1303,10 @@ function propertyPairsToObject(pairs) {
|
|
|
1244
1303
|
}
|
|
1245
1304
|
function buildEntityPropertiesCode({ type, layer, bbox }) {
|
|
1246
1305
|
const items = [];
|
|
1247
|
-
if (type)
|
|
1248
|
-
|
|
1306
|
+
if (type)
|
|
1307
|
+
items.push(`(cons 0 "${escapeLispString(type)}")`);
|
|
1308
|
+
if (layer)
|
|
1309
|
+
items.push(`(cons 8 "${escapeLispString(layer)}")`);
|
|
1249
1310
|
if (bbox) {
|
|
1250
1311
|
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
1251
1312
|
if (parts.length === 4) {
|
|
@@ -1271,8 +1332,10 @@ ${ENTITY_PROPERTIES_LISP}
|
|
|
1271
1332
|
(vl-prin1-to-string (list @e:total (reverse @e:ents))))`;
|
|
1272
1333
|
}
|
|
1273
1334
|
async function getEntityByHandle(handle) {
|
|
1274
|
-
if (!cad.connected)
|
|
1275
|
-
|
|
1335
|
+
if (!cad.connected)
|
|
1336
|
+
await cad.connect();
|
|
1337
|
+
if (!cad.connected)
|
|
1338
|
+
return { error: "CAD \u672A\u8FDE\u63A5" };
|
|
1276
1339
|
const code = `(progn
|
|
1277
1340
|
(vl-load-com)
|
|
1278
1341
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -1292,7 +1355,8 @@ async function getEntityByHandle(handle) {
|
|
|
1292
1355
|
)`;
|
|
1293
1356
|
try {
|
|
1294
1357
|
const result = await cad.sendCommandWithResult(code);
|
|
1295
|
-
if (!result || result === "nil")
|
|
1358
|
+
if (!result || result === "nil")
|
|
1359
|
+
return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
|
|
1296
1360
|
try {
|
|
1297
1361
|
return JSON.parse(result);
|
|
1298
1362
|
} catch {
|
|
@@ -1304,7 +1368,8 @@ async function getEntityByHandle(handle) {
|
|
|
1304
1368
|
}
|
|
1305
1369
|
async function getCadInfo() {
|
|
1306
1370
|
const cached = getCached("cad:info");
|
|
1307
|
-
if (cached)
|
|
1371
|
+
if (cached)
|
|
1372
|
+
return cached;
|
|
1308
1373
|
if (!cad.connected) {
|
|
1309
1374
|
await cad.connect();
|
|
1310
1375
|
}
|
|
@@ -1329,8 +1394,10 @@ async function getCadInfo() {
|
|
|
1329
1394
|
async function getEntities(params = {}) {
|
|
1330
1395
|
const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
|
|
1331
1396
|
const cached = getCached(cacheKey);
|
|
1332
|
-
if (cached)
|
|
1333
|
-
|
|
1397
|
+
if (cached)
|
|
1398
|
+
return cached;
|
|
1399
|
+
if (!cad.connected)
|
|
1400
|
+
await cad.connect();
|
|
1334
1401
|
if (!cad.connected) {
|
|
1335
1402
|
return { total: 0, entities: [] };
|
|
1336
1403
|
}
|
|
@@ -1425,7 +1492,8 @@ function buildTextContentCode({ layer, bbox, offset, limit }) {
|
|
|
1425
1492
|
`'(0 . "ATTRIB")`,
|
|
1426
1493
|
`'(-4 . "OR>")`
|
|
1427
1494
|
];
|
|
1428
|
-
if (layer)
|
|
1495
|
+
if (layer)
|
|
1496
|
+
items.push(`(cons 8 "${escapeLispString(layer)}")`);
|
|
1429
1497
|
if (bbox) {
|
|
1430
1498
|
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
1431
1499
|
if (parts.length === 4) {
|
|
@@ -1455,8 +1523,10 @@ function buildTextContentCode({ layer, bbox, offset, limit }) {
|
|
|
1455
1523
|
async function getTextContent(params = {}) {
|
|
1456
1524
|
const cacheKey = `dwg:text-content:${JSON.stringify(params)}`;
|
|
1457
1525
|
const cached = getCached(cacheKey);
|
|
1458
|
-
if (cached)
|
|
1459
|
-
|
|
1526
|
+
if (cached)
|
|
1527
|
+
return cached;
|
|
1528
|
+
if (!cad.connected)
|
|
1529
|
+
await cad.connect();
|
|
1460
1530
|
if (!cad.connected) {
|
|
1461
1531
|
return { total: 0, offset: 0, limit: 5e3, texts: [] };
|
|
1462
1532
|
}
|
|
@@ -1484,12 +1554,14 @@ async function getTextContent(params = {}) {
|
|
|
1484
1554
|
}
|
|
1485
1555
|
}
|
|
1486
1556
|
data.texts = rawTexts.map((item) => {
|
|
1487
|
-
if (!Array.isArray(item))
|
|
1557
|
+
if (!Array.isArray(item))
|
|
1558
|
+
return null;
|
|
1488
1559
|
const obj = {};
|
|
1489
1560
|
for (let i = 0; i < item.length - 1; i += 2) {
|
|
1490
1561
|
const key = item[i];
|
|
1491
1562
|
const val = item[i + 1];
|
|
1492
|
-
if (key === "text")
|
|
1563
|
+
if (key === "text")
|
|
1564
|
+
obj.text = String(val || "");
|
|
1493
1565
|
else if (key === "position") {
|
|
1494
1566
|
obj.position = Array.isArray(val) ? val.map((v) => typeof v === "number" ? v : 0) : [];
|
|
1495
1567
|
}
|
|
@@ -1504,8 +1576,10 @@ async function getTextContent(params = {}) {
|
|
|
1504
1576
|
}
|
|
1505
1577
|
}
|
|
1506
1578
|
async function getDwgName() {
|
|
1507
|
-
if (!cad.connected)
|
|
1508
|
-
|
|
1579
|
+
if (!cad.connected)
|
|
1580
|
+
await cad.connect();
|
|
1581
|
+
if (!cad.connected)
|
|
1582
|
+
return { name: null };
|
|
1509
1583
|
try {
|
|
1510
1584
|
const code = `(vl-princ-to-string (getvar "dwgname"))`;
|
|
1511
1585
|
const name = await cad.sendCommandWithResult(code);
|
|
@@ -1515,8 +1589,10 @@ async function getDwgName() {
|
|
|
1515
1589
|
}
|
|
1516
1590
|
}
|
|
1517
1591
|
async function getDwgPath() {
|
|
1518
|
-
if (!cad.connected)
|
|
1519
|
-
|
|
1592
|
+
if (!cad.connected)
|
|
1593
|
+
await cad.connect();
|
|
1594
|
+
if (!cad.connected)
|
|
1595
|
+
return { path: null, name: null };
|
|
1520
1596
|
try {
|
|
1521
1597
|
const code = `(progn
|
|
1522
1598
|
(setq prefix (vl-princ-to-string (getvar "dwgprefix")))
|
|
@@ -1535,7 +1611,8 @@ async function getDwgPath() {
|
|
|
1535
1611
|
}
|
|
1536
1612
|
if (!parsed) {
|
|
1537
1613
|
const listResult = parseLispList(result);
|
|
1538
|
-
if (listResult && listResult.length >= 2)
|
|
1614
|
+
if (listResult && listResult.length >= 2)
|
|
1615
|
+
parsed = listResult;
|
|
1539
1616
|
}
|
|
1540
1617
|
if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
|
|
1541
1618
|
return { path: String(parsed[0]), name: String(parsed[1]) };
|
|
@@ -1554,51 +1631,30 @@ function buildBlockRefsCode(filterBlockName) {
|
|
|
1554
1631
|
return `(progn
|
|
1555
1632
|
(vl-load-com)
|
|
1556
1633
|
|
|
1557
|
-
(defun @br:try (
|
|
1558
|
-
(
|
|
1559
|
-
(setq r (vl-catch-all-apply
|
|
1560
|
-
(function (lambda () (vlax-get obj prop))))))
|
|
1561
|
-
nil
|
|
1562
|
-
r))
|
|
1563
|
-
|
|
1564
|
-
(defun @br:get-attrs (ent / att atts)
|
|
1565
|
-
(if (setq att (entnext ent))
|
|
1566
|
-
(progn
|
|
1567
|
-
(setq atts nil)
|
|
1568
|
-
(while (= (cdr (assoc 0 (entget att))) "ATTRIB")
|
|
1569
|
-
(setq atts (cons (cons (cdr (assoc 2 (entget att))) (cdr (assoc 1 (entget att)))) atts))
|
|
1570
|
-
att (entnext att))
|
|
1571
|
-
(reverse atts))
|
|
1572
|
-
nil))
|
|
1573
|
-
|
|
1574
|
-
(defun @br:get-dynprops (obj / r)
|
|
1575
|
-
(setq r (vl-catch-all-apply
|
|
1576
|
-
(function (lambda ()
|
|
1577
|
-
(mapcar '(lambda (x)
|
|
1578
|
-
(cons (vla-get-propertyname x)
|
|
1579
|
-
(list (cons "value" (vlax-get x 'value))
|
|
1580
|
-
(cons "readOnly" (vlax-get x 'readonly))
|
|
1581
|
-
(cons "show" (vlax-get x 'show)))))
|
|
1582
|
-
(vlax-safearray->list (vlax-invoke obj 'getdynamicblockproperties)))))))
|
|
1634
|
+
(defun @br:try-fn (fn arg / r)
|
|
1635
|
+
(setq r (vl-catch-all-apply (function (lambda () (apply fn (list arg))))))
|
|
1583
1636
|
(if (vl-catch-all-error-p r) nil r))
|
|
1584
1637
|
|
|
1585
|
-
(defun @br:props (ent /
|
|
1638
|
+
(defun @br:props (ent / ed r p2 p10 p50 p41 p42 p43)
|
|
1639
|
+
(setq ed (entget ent)
|
|
1640
|
+
p10 (cdr (assoc 10 ed))
|
|
1641
|
+
p50 (cdr (assoc 50 ed))
|
|
1642
|
+
p41 (cdr (assoc 41 ed))
|
|
1643
|
+
p42 (cdr (assoc 42 ed))
|
|
1644
|
+
p43 (cdr (assoc 43 ed)))
|
|
1586
1645
|
(setq r (vl-catch-all-apply
|
|
1587
1646
|
(function (lambda ()
|
|
1588
|
-
(setq obj (vlax-ename->vla-object ent)
|
|
1589
|
-
ed (entget ent))
|
|
1590
1647
|
(list
|
|
1591
1648
|
(cons "handle" (cdr (assoc 5 ed)))
|
|
1592
1649
|
(cons "layer" (cdr (assoc 8 ed)))
|
|
1593
|
-
(cons "blockName" (
|
|
1594
|
-
(cons "effectiveBlockName" (
|
|
1595
|
-
(cons "insertionPoint" (
|
|
1596
|
-
(cons "rotation"
|
|
1597
|
-
(cons "scale" (list
|
|
1598
|
-
(cons "
|
|
1599
|
-
(cons "
|
|
1600
|
-
|
|
1601
|
-
(if (vl-catch-all-error-p r) nil r))
|
|
1650
|
+
(cons "blockName" (cdr (assoc 2 ed)))
|
|
1651
|
+
(cons "effectiveBlockName" (cdr (assoc 2 ed)))
|
|
1652
|
+
(cons "insertionPoint" (list (car p10) (cadr p10) (caddr p10)))
|
|
1653
|
+
(cons "rotation" p50)
|
|
1654
|
+
(cons "scale" (list p41 p42 p43))
|
|
1655
|
+
(cons "attributes" (@br:try-fn 'block:get-attributes ent))
|
|
1656
|
+
(cons "dynamicProperties" (@br:try-fn 'block:get-properties ent)))))))
|
|
1657
|
+
(if (vl-catch-all-error-p r) (list (cons "handle" (cdr (assoc 5 ed)))) r))
|
|
1602
1658
|
|
|
1603
1659
|
(setq ss (ssget "_X" ${filterCode}))
|
|
1604
1660
|
(if (null ss)
|
|
@@ -1614,8 +1670,10 @@ function buildBlockRefsCode(filterBlockName) {
|
|
|
1614
1670
|
async function getBlockRefs(params = {}) {
|
|
1615
1671
|
const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
|
|
1616
1672
|
const cached = getCached(cacheKey);
|
|
1617
|
-
if (cached)
|
|
1618
|
-
|
|
1673
|
+
if (cached)
|
|
1674
|
+
return cached;
|
|
1675
|
+
if (!cad.connected)
|
|
1676
|
+
await cad.connect();
|
|
1619
1677
|
if (!cad.connected) {
|
|
1620
1678
|
return { total: 0, blockRefs: [] };
|
|
1621
1679
|
}
|
|
@@ -1648,6 +1706,20 @@ async function getBlockRefs(params = {}) {
|
|
|
1648
1706
|
val = val.map((v) => typeof v === "number" ? v : 1);
|
|
1649
1707
|
} else if (key === "isDynamic") {
|
|
1650
1708
|
val = val === true || val === "true" || val === 1;
|
|
1709
|
+
} else if (key === "attributes" && Array.isArray(val)) {
|
|
1710
|
+
const o = {};
|
|
1711
|
+
val.forEach((p) => {
|
|
1712
|
+
if (Array.isArray(p) && p.length >= 2)
|
|
1713
|
+
o[String(p[0])] = p[1];
|
|
1714
|
+
});
|
|
1715
|
+
val = o;
|
|
1716
|
+
} else if (key === "dynamicProperties" && Array.isArray(val)) {
|
|
1717
|
+
const o = {};
|
|
1718
|
+
val.forEach((p) => {
|
|
1719
|
+
if (Array.isArray(p) && p.length >= 2)
|
|
1720
|
+
o[String(p[0])] = p[1];
|
|
1721
|
+
});
|
|
1722
|
+
val = o;
|
|
1651
1723
|
}
|
|
1652
1724
|
obj[key] = val;
|
|
1653
1725
|
}
|
|
@@ -1692,7 +1764,8 @@ function buildTablesCode(tblName) {
|
|
|
1692
1764
|
return `(progn (vl-load-com) ${VLA_HELPER_LISP} (list ${parts.join(" ")}))`;
|
|
1693
1765
|
}
|
|
1694
1766
|
function parseTableRecord(rec, tableName) {
|
|
1695
|
-
if (!rec || !Array.isArray(rec))
|
|
1767
|
+
if (!rec || !Array.isArray(rec))
|
|
1768
|
+
return null;
|
|
1696
1769
|
const obj = {};
|
|
1697
1770
|
const isLayer = tableName === "layer";
|
|
1698
1771
|
for (const pair of rec) {
|
|
@@ -1701,24 +1774,35 @@ function parseTableRecord(rec, tableName) {
|
|
|
1701
1774
|
const val = pair[1];
|
|
1702
1775
|
const isDxfCode = typeof pair[0] === "number";
|
|
1703
1776
|
if (isDxfCode) {
|
|
1704
|
-
if (key === "2")
|
|
1705
|
-
|
|
1706
|
-
else if (key === "
|
|
1777
|
+
if (key === "2")
|
|
1778
|
+
obj.name = String(val);
|
|
1779
|
+
else if (key === "62")
|
|
1780
|
+
obj.color = typeof val === "number" ? val : 7;
|
|
1781
|
+
else if (key === "6")
|
|
1782
|
+
obj.linetype = String(val);
|
|
1707
1783
|
else if (key === "70") {
|
|
1708
1784
|
obj.flags = typeof val === "number" ? val : 0;
|
|
1709
1785
|
if (isLayer) {
|
|
1710
1786
|
obj.frozen = (val & 1) !== 0;
|
|
1711
1787
|
obj.locked = (val & 4) !== 0;
|
|
1712
1788
|
}
|
|
1713
|
-
} else if (key === "60")
|
|
1714
|
-
|
|
1715
|
-
else if (key === "
|
|
1716
|
-
|
|
1717
|
-
else if (key === "
|
|
1718
|
-
|
|
1719
|
-
else if (key === "
|
|
1789
|
+
} else if (key === "60")
|
|
1790
|
+
obj.on = val === 0;
|
|
1791
|
+
else if (key === "1")
|
|
1792
|
+
obj.font = String(val);
|
|
1793
|
+
else if (key === "40")
|
|
1794
|
+
obj.height = typeof val === "number" ? val : 0;
|
|
1795
|
+
else if (key === "41")
|
|
1796
|
+
obj.width = typeof val === "number" ? val : 1;
|
|
1797
|
+
else if (key === "42")
|
|
1798
|
+
obj.oblique = typeof val === "number" ? val : 0;
|
|
1799
|
+
else if (key === "3")
|
|
1800
|
+
obj.bigfont = String(val);
|
|
1801
|
+
else if (key === "50")
|
|
1802
|
+
obj.flags = typeof val === "number" ? val : 0;
|
|
1720
1803
|
} else {
|
|
1721
|
-
if (key === "Name")
|
|
1804
|
+
if (key === "Name")
|
|
1805
|
+
obj.name = val;
|
|
1722
1806
|
obj[key] = val;
|
|
1723
1807
|
}
|
|
1724
1808
|
}
|
|
@@ -1729,9 +1813,12 @@ async function getTables(params = {}) {
|
|
|
1729
1813
|
const tblName = params.tbl || params.type || "all";
|
|
1730
1814
|
const cacheKey = `dwg:tbl:${tblName}`;
|
|
1731
1815
|
const cached = getCached(cacheKey);
|
|
1732
|
-
if (cached)
|
|
1733
|
-
|
|
1734
|
-
if (!cad.connected)
|
|
1816
|
+
if (cached)
|
|
1817
|
+
return cached;
|
|
1818
|
+
if (!cad.connected)
|
|
1819
|
+
await cad.connect();
|
|
1820
|
+
if (!cad.connected)
|
|
1821
|
+
return { table: tblName, data: [] };
|
|
1735
1822
|
try {
|
|
1736
1823
|
const code = buildTablesCode(tblName);
|
|
1737
1824
|
const resultStr = await cad.sendCommandWithResult(code);
|
|
@@ -1750,7 +1837,8 @@ async function getTables(params = {}) {
|
|
|
1750
1837
|
for (const item of parsed) {
|
|
1751
1838
|
if (Array.isArray(item) && item.length >= 2) {
|
|
1752
1839
|
const key = String(item[0]).toUpperCase();
|
|
1753
|
-
if (key === "TOTAL")
|
|
1840
|
+
if (key === "TOTAL")
|
|
1841
|
+
total = typeof item[1] === "number" ? item[1] : 0;
|
|
1754
1842
|
else if (key === "DATA") {
|
|
1755
1843
|
if (Array.isArray(item[1]) && item[1].length > 0) {
|
|
1756
1844
|
tblData = item[1];
|
|
@@ -1769,16 +1857,19 @@ async function getTables(params = {}) {
|
|
|
1769
1857
|
} else {
|
|
1770
1858
|
const allData = {};
|
|
1771
1859
|
parsed.forEach((item) => {
|
|
1772
|
-
if (!Array.isArray(item) || item.length < 2)
|
|
1860
|
+
if (!Array.isArray(item) || item.length < 2)
|
|
1861
|
+
return;
|
|
1773
1862
|
let tableKey = null;
|
|
1774
1863
|
const entry = { total: 0, data: [] };
|
|
1775
1864
|
if (Array.isArray(item[0]) && item[0].length >= 2 && String(item[0][0]).toLowerCase() === "table") {
|
|
1776
1865
|
tableKey = String(item[0][1]).toLowerCase();
|
|
1777
1866
|
for (let i = 1; i < item.length; i++) {
|
|
1778
1867
|
const sub = item[i];
|
|
1779
|
-
if (!Array.isArray(sub) || sub.length < 2)
|
|
1868
|
+
if (!Array.isArray(sub) || sub.length < 2)
|
|
1869
|
+
continue;
|
|
1780
1870
|
const subKey = String(sub[0]).toUpperCase();
|
|
1781
|
-
if (subKey === "TOTAL")
|
|
1871
|
+
if (subKey === "TOTAL")
|
|
1872
|
+
entry.total = typeof sub[1] === "number" ? sub[1] : 0;
|
|
1782
1873
|
else if (subKey === "DATA") {
|
|
1783
1874
|
const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
|
|
1784
1875
|
entry.data = raw.map((r) => parseTableRecord(r, tableKey)).filter(Boolean);
|
|
@@ -1788,7 +1879,8 @@ async function getTables(params = {}) {
|
|
|
1788
1879
|
tableKey = String(item[0]).toLowerCase();
|
|
1789
1880
|
for (let i = 1; i < item.length; i++) {
|
|
1790
1881
|
const sub = item[i];
|
|
1791
|
-
if (!Array.isArray(sub) || sub.length < 2)
|
|
1882
|
+
if (!Array.isArray(sub) || sub.length < 2)
|
|
1883
|
+
continue;
|
|
1792
1884
|
const subKey = String(sub[0]).toUpperCase();
|
|
1793
1885
|
if (subKey === "TOTAL") {
|
|
1794
1886
|
entry.total = typeof sub[1] === "number" ? sub[1] : 0;
|
|
@@ -1798,7 +1890,8 @@ async function getTables(params = {}) {
|
|
|
1798
1890
|
}
|
|
1799
1891
|
}
|
|
1800
1892
|
}
|
|
1801
|
-
if (tableKey)
|
|
1893
|
+
if (tableKey)
|
|
1894
|
+
allData[tableKey] = entry;
|
|
1802
1895
|
});
|
|
1803
1896
|
result = allData;
|
|
1804
1897
|
}
|
|
@@ -1812,9 +1905,12 @@ async function getTables(params = {}) {
|
|
|
1812
1905
|
async function getPackages(filterName = null) {
|
|
1813
1906
|
const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
|
|
1814
1907
|
const cached = getCached(cacheKey);
|
|
1815
|
-
if (cached)
|
|
1816
|
-
|
|
1817
|
-
if (!cad.connected)
|
|
1908
|
+
if (cached)
|
|
1909
|
+
return cached;
|
|
1910
|
+
if (!cad.connected)
|
|
1911
|
+
await cad.connect();
|
|
1912
|
+
if (!cad.connected)
|
|
1913
|
+
return [];
|
|
1818
1914
|
try {
|
|
1819
1915
|
const code = `(mapcar 'cdr @::*local-pkgs*)`;
|
|
1820
1916
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -1827,7 +1923,8 @@ async function getPackages(filterName = null) {
|
|
|
1827
1923
|
} catch {
|
|
1828
1924
|
raw = parseLispList(result) || [];
|
|
1829
1925
|
}
|
|
1830
|
-
if (!Array.isArray(raw))
|
|
1926
|
+
if (!Array.isArray(raw))
|
|
1927
|
+
raw = [];
|
|
1831
1928
|
const packages = raw.map((item) => {
|
|
1832
1929
|
if (Array.isArray(item)) {
|
|
1833
1930
|
const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
|
|
@@ -1836,13 +1933,20 @@ async function getPackages(filterName = null) {
|
|
|
1836
1933
|
const [[key, val]] = Object.entries(entry);
|
|
1837
1934
|
const k = String(key);
|
|
1838
1935
|
const v = String(val);
|
|
1839
|
-
if (k === ":NAME")
|
|
1840
|
-
|
|
1841
|
-
else if (k === ":
|
|
1842
|
-
|
|
1843
|
-
else if (k === ":
|
|
1844
|
-
|
|
1845
|
-
else if (k === ":
|
|
1936
|
+
if (k === ":NAME")
|
|
1937
|
+
pkg.name = v;
|
|
1938
|
+
else if (k === ":VERSION")
|
|
1939
|
+
pkg.version = v;
|
|
1940
|
+
else if (k === ":DESCRIPTION")
|
|
1941
|
+
pkg.description = v;
|
|
1942
|
+
else if (k === ":FULL-NAME")
|
|
1943
|
+
pkg.fullName = v;
|
|
1944
|
+
else if (k === ":AUTHOR")
|
|
1945
|
+
pkg.author = v;
|
|
1946
|
+
else if (k === ":CATEGORY")
|
|
1947
|
+
pkg.category = v;
|
|
1948
|
+
else if (k === ":URL")
|
|
1949
|
+
pkg.url = v;
|
|
1846
1950
|
}
|
|
1847
1951
|
}
|
|
1848
1952
|
return pkg;
|
|
@@ -1853,15 +1957,22 @@ async function getPackages(filterName = null) {
|
|
|
1853
1957
|
if (item && typeof item === "object") {
|
|
1854
1958
|
const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
|
|
1855
1959
|
const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
|
|
1856
|
-
if (nameVal)
|
|
1960
|
+
if (nameVal)
|
|
1961
|
+
pkg.name = String(nameVal);
|
|
1857
1962
|
const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
|
|
1858
|
-
if (verVal)
|
|
1963
|
+
if (verVal)
|
|
1964
|
+
pkg.version = String(verVal);
|
|
1859
1965
|
const descVal = item.description || item.Description || item.DESCRIPTION || item[":DESCRIPTION"];
|
|
1860
|
-
if (descVal)
|
|
1861
|
-
|
|
1862
|
-
if (item.
|
|
1863
|
-
|
|
1864
|
-
if (item.
|
|
1966
|
+
if (descVal)
|
|
1967
|
+
pkg.description = String(descVal);
|
|
1968
|
+
if (item.fullName || item.full_name)
|
|
1969
|
+
pkg.fullName = String(item.fullName || item.full_name);
|
|
1970
|
+
if (item.author || item.Author)
|
|
1971
|
+
pkg.author = String(item.author || item.Author);
|
|
1972
|
+
if (item.category || item.Category)
|
|
1973
|
+
pkg.category = String(item.category || item.Category);
|
|
1974
|
+
if (item.url || item.Url || item.URL)
|
|
1975
|
+
pkg.url = String(item.url || item.Url || item.URL);
|
|
1865
1976
|
return pkg;
|
|
1866
1977
|
}
|
|
1867
1978
|
return null;
|
|
@@ -1886,9 +1997,12 @@ function getPlatforms() {
|
|
|
1886
1997
|
async function getDwgList() {
|
|
1887
1998
|
const cacheKey = "cad:dwgs";
|
|
1888
1999
|
const cached = getCached(cacheKey);
|
|
1889
|
-
if (cached)
|
|
1890
|
-
|
|
1891
|
-
if (!cad.connected)
|
|
2000
|
+
if (cached)
|
|
2001
|
+
return cached;
|
|
2002
|
+
if (!cad.connected)
|
|
2003
|
+
await cad.connect();
|
|
2004
|
+
if (!cad.connected)
|
|
2005
|
+
return [];
|
|
1892
2006
|
try {
|
|
1893
2007
|
const code = `(progn
|
|
1894
2008
|
(vl-load-com)
|
|
@@ -1911,7 +2025,8 @@ async function getDwgList() {
|
|
|
1911
2025
|
parsed = listResult;
|
|
1912
2026
|
}
|
|
1913
2027
|
}
|
|
1914
|
-
if (!Array.isArray(parsed))
|
|
2028
|
+
if (!Array.isArray(parsed))
|
|
2029
|
+
parsed = [];
|
|
1915
2030
|
const dwgList = parsed.map((item) => {
|
|
1916
2031
|
if (Array.isArray(item) && item.length >= 2) {
|
|
1917
2032
|
return { name: String(item[0]), path: String(item[1]) };
|
|
@@ -1937,7 +2052,8 @@ function loadStandardsFile(filename) {
|
|
|
1937
2052
|
var standardsCache = /* @__PURE__ */ new Map();
|
|
1938
2053
|
function getCachedStandards(key) {
|
|
1939
2054
|
const entry = standardsCache.get(key);
|
|
1940
|
-
if (entry && Date.now() - entry.timestamp < 3e4)
|
|
2055
|
+
if (entry && Date.now() - entry.timestamp < 3e4)
|
|
2056
|
+
return entry.data;
|
|
1941
2057
|
standardsCache.delete(key);
|
|
1942
2058
|
return null;
|
|
1943
2059
|
}
|
|
@@ -1946,40 +2062,49 @@ function setCachedStandards(key, data) {
|
|
|
1946
2062
|
}
|
|
1947
2063
|
function getDraftingStandards() {
|
|
1948
2064
|
const cached = getCachedStandards("drafting");
|
|
1949
|
-
if (cached)
|
|
2065
|
+
if (cached)
|
|
2066
|
+
return cached;
|
|
1950
2067
|
const data = loadStandardsFile("drafting.json");
|
|
1951
|
-
if (data)
|
|
2068
|
+
if (data)
|
|
2069
|
+
setCachedStandards("drafting", data);
|
|
1952
2070
|
return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
|
|
1953
2071
|
}
|
|
1954
2072
|
function getCodingStandards() {
|
|
1955
2073
|
const cached = getCachedStandards("coding");
|
|
1956
|
-
if (cached)
|
|
2074
|
+
if (cached)
|
|
2075
|
+
return cached;
|
|
1957
2076
|
const data = loadStandardsFile("coding.json");
|
|
1958
|
-
if (data)
|
|
2077
|
+
if (data)
|
|
2078
|
+
setCachedStandards("coding", data);
|
|
1959
2079
|
return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
|
|
1960
2080
|
}
|
|
1961
2081
|
|
|
1962
2082
|
// src/handlers/resource-handlers.js
|
|
1963
2083
|
function parseQuery(uri) {
|
|
1964
2084
|
const qIdx = uri.indexOf("?");
|
|
1965
|
-
if (qIdx === -1)
|
|
2085
|
+
if (qIdx === -1)
|
|
2086
|
+
return { base: uri, params: {} };
|
|
1966
2087
|
const base = uri.substring(0, qIdx);
|
|
1967
2088
|
const params = {};
|
|
1968
2089
|
uri.substring(qIdx + 1).split("&").forEach((p) => {
|
|
1969
2090
|
const eqIdx = p.indexOf("=");
|
|
1970
2091
|
const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
|
|
1971
2092
|
const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
|
|
1972
|
-
if (k)
|
|
2093
|
+
if (k)
|
|
2094
|
+
params[k] = decodeURIComponent(v);
|
|
1973
2095
|
});
|
|
1974
2096
|
return { base, params };
|
|
1975
2097
|
}
|
|
1976
2098
|
function parseTemplateUri(uri) {
|
|
1977
2099
|
const entityMatch = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
|
|
1978
|
-
if (entityMatch)
|
|
2100
|
+
if (entityMatch)
|
|
2101
|
+
return { type: "entity", handle: entityMatch[1] };
|
|
1979
2102
|
const tblMatch = uri.match(/^atlisp:\/\/dwg\/tbl\/([^?]+)$/);
|
|
1980
|
-
if (tblMatch)
|
|
2103
|
+
if (tblMatch)
|
|
2104
|
+
return { type: "tbl", tblName: tblMatch[1] };
|
|
1981
2105
|
const blockRefMatch = uri.match(/^atlisp:\/\/dwg\/block-refs\/([^?]+)$/);
|
|
1982
|
-
if (blockRefMatch)
|
|
2106
|
+
if (blockRefMatch)
|
|
2107
|
+
return { type: "block-refs", blockName: blockRefMatch[1] };
|
|
1983
2108
|
return null;
|
|
1984
2109
|
}
|
|
1985
2110
|
async function listResources(subscribedUris = []) {
|
|
@@ -2139,8 +2264,10 @@ function isPrefixUri(uri) {
|
|
|
2139
2264
|
return uri.endsWith("/");
|
|
2140
2265
|
}
|
|
2141
2266
|
function matchesSubscription(subscribedUri, targetUri) {
|
|
2142
|
-
if (subscribedUri === targetUri)
|
|
2143
|
-
|
|
2267
|
+
if (subscribedUri === targetUri)
|
|
2268
|
+
return true;
|
|
2269
|
+
if (isPrefixUri(subscribedUri) && targetUri.startsWith(subscribedUri))
|
|
2270
|
+
return true;
|
|
2144
2271
|
return false;
|
|
2145
2272
|
}
|
|
2146
2273
|
function isSubscribed(uri, sessionId) {
|
|
@@ -2150,7 +2277,8 @@ function isSubscribed(uri, sessionId) {
|
|
|
2150
2277
|
}
|
|
2151
2278
|
const allUris = sessionManager.getAllSubscribedUris();
|
|
2152
2279
|
for (const su of allUris) {
|
|
2153
|
-
if (matchesSubscription(su, uri))
|
|
2280
|
+
if (matchesSubscription(su, uri))
|
|
2281
|
+
return true;
|
|
2154
2282
|
}
|
|
2155
2283
|
return false;
|
|
2156
2284
|
}
|
|
@@ -2259,9 +2387,11 @@ var SseSession = class {
|
|
|
2259
2387
|
return lines.join("\n") + "\n\n";
|
|
2260
2388
|
}
|
|
2261
2389
|
_setupDrain() {
|
|
2262
|
-
if (typeof this.#res.on !== "function")
|
|
2390
|
+
if (typeof this.#res.on !== "function")
|
|
2391
|
+
return;
|
|
2263
2392
|
this.#drainHandler = () => {
|
|
2264
|
-
if (!this.#active)
|
|
2393
|
+
if (!this.#active)
|
|
2394
|
+
return;
|
|
2265
2395
|
if (this.#backpressureBuffer.length > 0) {
|
|
2266
2396
|
this._drainBuffer();
|
|
2267
2397
|
}
|
|
@@ -2283,7 +2413,8 @@ var SseSession = class {
|
|
|
2283
2413
|
}
|
|
2284
2414
|
}
|
|
2285
2415
|
_write(content) {
|
|
2286
|
-
if (!this.#active)
|
|
2416
|
+
if (!this.#active)
|
|
2417
|
+
return false;
|
|
2287
2418
|
try {
|
|
2288
2419
|
if (this.#backpressureBuffer.length > 0) {
|
|
2289
2420
|
this.#backpressureBuffer.push(content);
|
|
@@ -2412,7 +2543,8 @@ function persistSessionData(clientId, sessionData) {
|
|
|
2412
2543
|
function loadPersistedSessionData(clientId) {
|
|
2413
2544
|
try {
|
|
2414
2545
|
const filePath = getSessionStorePath(clientId);
|
|
2415
|
-
if (!fs4.existsSync(filePath))
|
|
2546
|
+
if (!fs4.existsSync(filePath))
|
|
2547
|
+
return null;
|
|
2416
2548
|
const raw = fs4.readFileSync(filePath, "utf-8");
|
|
2417
2549
|
const store = JSON.parse(raw);
|
|
2418
2550
|
if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
|
|
@@ -2476,7 +2608,8 @@ var SseSessionManager = class {
|
|
|
2476
2608
|
session.close();
|
|
2477
2609
|
this.#sessions.delete(clientId);
|
|
2478
2610
|
const idx = this.#accessOrder.indexOf(clientId);
|
|
2479
|
-
if (idx !== -1)
|
|
2611
|
+
if (idx !== -1)
|
|
2612
|
+
this.#accessOrder.splice(idx, 1);
|
|
2480
2613
|
return true;
|
|
2481
2614
|
}
|
|
2482
2615
|
return false;
|
|
@@ -2563,7 +2696,8 @@ var SseSessionManager = class {
|
|
|
2563
2696
|
session.close();
|
|
2564
2697
|
this.#sessions.delete(clientId);
|
|
2565
2698
|
const idx = this.#accessOrder.indexOf(clientId);
|
|
2566
|
-
if (idx !== -1)
|
|
2699
|
+
if (idx !== -1)
|
|
2700
|
+
this.#accessOrder.splice(idx, 1);
|
|
2567
2701
|
}
|
|
2568
2702
|
}
|
|
2569
2703
|
}
|
|
@@ -2611,7 +2745,8 @@ var SessionTransport = class {
|
|
|
2611
2745
|
this._started = true;
|
|
2612
2746
|
}
|
|
2613
2747
|
async send(message) {
|
|
2614
|
-
if (this._closed)
|
|
2748
|
+
if (this._closed)
|
|
2749
|
+
return;
|
|
2615
2750
|
if (this._pendingRequest) {
|
|
2616
2751
|
const { resolve, reject, timeout } = this._pendingRequest;
|
|
2617
2752
|
clearTimeout(timeout);
|
|
@@ -2620,7 +2755,8 @@ var SessionTransport = class {
|
|
|
2620
2755
|
}
|
|
2621
2756
|
}
|
|
2622
2757
|
async close() {
|
|
2623
|
-
if (this._closed)
|
|
2758
|
+
if (this._closed)
|
|
2759
|
+
return;
|
|
2624
2760
|
this._closed = true;
|
|
2625
2761
|
if (this._pendingRequest) {
|
|
2626
2762
|
const { reject, timeout } = this._pendingRequest;
|
|
@@ -2694,10 +2830,12 @@ var DEFS_DIR = path7.join(__dirname3, "definitions");
|
|
|
2694
2830
|
var PROMPTS_DIR = path7.join(__dirname3, "..", "..", "prompts");
|
|
2695
2831
|
var builtinDefs = null;
|
|
2696
2832
|
function loadBuiltinDefs() {
|
|
2697
|
-
if (builtinDefs)
|
|
2833
|
+
if (builtinDefs)
|
|
2834
|
+
return builtinDefs;
|
|
2698
2835
|
builtinDefs = {};
|
|
2699
2836
|
try {
|
|
2700
|
-
if (!fs5.existsSync(DEFS_DIR))
|
|
2837
|
+
if (!fs5.existsSync(DEFS_DIR))
|
|
2838
|
+
return builtinDefs;
|
|
2701
2839
|
const files = fs5.readdirSync(DEFS_DIR).filter((f) => f.endsWith(".json"));
|
|
2702
2840
|
for (const file of files) {
|
|
2703
2841
|
try {
|
|
@@ -2759,12 +2897,15 @@ function formatLispPoints(pointsStr) {
|
|
|
2759
2897
|
return `(list ${ptList.join(" ")})`;
|
|
2760
2898
|
}
|
|
2761
2899
|
function getDimensionStyleLisp(style) {
|
|
2762
|
-
if (style === "horizontal" || style === "vertical")
|
|
2900
|
+
if (style === "horizontal" || style === "vertical")
|
|
2901
|
+
return "DIMLINEAR";
|
|
2763
2902
|
return "DIMALIGNED";
|
|
2764
2903
|
}
|
|
2765
2904
|
function getDimensionStyleLabel(style) {
|
|
2766
|
-
if (style === "horizontal")
|
|
2767
|
-
|
|
2905
|
+
if (style === "horizontal")
|
|
2906
|
+
return "\u6C34\u5E73";
|
|
2907
|
+
if (style === "vertical")
|
|
2908
|
+
return "\u5782\u76F4";
|
|
2768
2909
|
return "aligned";
|
|
2769
2910
|
}
|
|
2770
2911
|
async function handleComplexPrompt(def, args) {
|
|
@@ -2798,10 +2939,14 @@ async function handleComplexPrompt(def, args) {
|
|
|
2798
2939
|
} catch {
|
|
2799
2940
|
}
|
|
2800
2941
|
const suggestions = [];
|
|
2801
|
-
if (entities.total > 1e3)
|
|
2802
|
-
|
|
2803
|
-
if (
|
|
2804
|
-
|
|
2942
|
+
if (entities.total > 1e3)
|
|
2943
|
+
suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
|
|
2944
|
+
if (layers.length > 20)
|
|
2945
|
+
suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
|
|
2946
|
+
if (entities.byType.LINE && entities.byType.LINE > 500)
|
|
2947
|
+
suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
|
|
2948
|
+
if (!entities.byType.DIMENSION)
|
|
2949
|
+
suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
|
|
2805
2950
|
return {
|
|
2806
2951
|
messages: [{
|
|
2807
2952
|
role: "user",
|
|
@@ -2994,7 +3139,8 @@ ${code}
|
|
|
2994
3139
|
}
|
|
2995
3140
|
const defs = loadBuiltinDefs();
|
|
2996
3141
|
const def = defs[name];
|
|
2997
|
-
if (!def)
|
|
3142
|
+
if (!def)
|
|
3143
|
+
throw new Error(`Unknown prompt: ${name}`);
|
|
2998
3144
|
if (def.handler) {
|
|
2999
3145
|
return handleComplexPrompt(def, args);
|
|
3000
3146
|
}
|
|
@@ -3019,7 +3165,8 @@ import path8 from "path";
|
|
|
3019
3165
|
init_config();
|
|
3020
3166
|
var MAX_HISTORY_VALUES = 1e3;
|
|
3021
3167
|
function percentile(sorted, p) {
|
|
3022
|
-
if (sorted.length === 0)
|
|
3168
|
+
if (sorted.length === 0)
|
|
3169
|
+
return 0;
|
|
3023
3170
|
const idx = Math.ceil(p * sorted.length) - 1;
|
|
3024
3171
|
return sorted[Math.max(0, Math.min(idx, sorted.length - 1))];
|
|
3025
3172
|
}
|
|
@@ -3310,7 +3457,8 @@ async function evalLisp(code, withResult = false, encoding = null) {
|
|
|
3310
3457
|
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3311
3458
|
}
|
|
3312
3459
|
const trimmed = (code || "").trim();
|
|
3313
|
-
if (!trimmed)
|
|
3460
|
+
if (!trimmed)
|
|
3461
|
+
return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
3314
3462
|
try {
|
|
3315
3463
|
if (withResult) {
|
|
3316
3464
|
const result = await cad.sendCommandWithResult(trimmed, encoding);
|
|
@@ -3330,14 +3478,17 @@ async function getCadInfo2() {
|
|
|
3330
3478
|
if (!cad.connected) {
|
|
3331
3479
|
await cad.connect();
|
|
3332
3480
|
}
|
|
3333
|
-
if (!cad.connected)
|
|
3481
|
+
if (!cad.connected)
|
|
3482
|
+
return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
|
|
3334
3483
|
const info = await cad.getInfo();
|
|
3335
3484
|
return { content: [{ type: "text", text: info }] };
|
|
3336
3485
|
}
|
|
3337
3486
|
async function atCommand(command) {
|
|
3338
|
-
if (!cad.connected)
|
|
3487
|
+
if (!cad.connected)
|
|
3488
|
+
return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
|
|
3339
3489
|
const trimmed = (command || "").trim();
|
|
3340
|
-
if (!trimmed)
|
|
3490
|
+
if (!trimmed)
|
|
3491
|
+
return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
3341
3492
|
await cad.sendCommand(trimmed + "\n");
|
|
3342
3493
|
return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
|
|
3343
3494
|
}
|
|
@@ -3345,7 +3496,8 @@ async function newDocument() {
|
|
|
3345
3496
|
if (!cad.connected) {
|
|
3346
3497
|
await cad.connect();
|
|
3347
3498
|
}
|
|
3348
|
-
if (!cad.connected)
|
|
3499
|
+
if (!cad.connected)
|
|
3500
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3349
3501
|
const result = await cad.newDoc();
|
|
3350
3502
|
if (result) {
|
|
3351
3503
|
return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
|
|
@@ -3356,7 +3508,8 @@ async function bringToFront() {
|
|
|
3356
3508
|
if (!cad.connected) {
|
|
3357
3509
|
await cad.connect();
|
|
3358
3510
|
}
|
|
3359
|
-
if (!cad.connected)
|
|
3511
|
+
if (!cad.connected)
|
|
3512
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3360
3513
|
const result = await cad.bringToFront();
|
|
3361
3514
|
if (result) {
|
|
3362
3515
|
return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
|
|
@@ -3367,7 +3520,8 @@ async function installAtlisp() {
|
|
|
3367
3520
|
if (!cad.connected) {
|
|
3368
3521
|
await cad.connect();
|
|
3369
3522
|
}
|
|
3370
|
-
if (!cad.connected)
|
|
3523
|
+
if (!cad.connected)
|
|
3524
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3371
3525
|
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))))`;
|
|
3372
3526
|
await cad.sendCommand(installCode + "\n");
|
|
3373
3527
|
return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
|
|
@@ -3376,10 +3530,12 @@ async function listFunctionsInCad() {
|
|
|
3376
3530
|
if (!cad.connected) {
|
|
3377
3531
|
await cad.connect();
|
|
3378
3532
|
}
|
|
3379
|
-
if (!cad.connected)
|
|
3533
|
+
if (!cad.connected)
|
|
3534
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3380
3535
|
try {
|
|
3381
3536
|
const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
|
|
3382
|
-
if (result)
|
|
3537
|
+
if (result)
|
|
3538
|
+
return { content: [{ type: "text", text: result }] };
|
|
3383
3539
|
return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
|
|
3384
3540
|
} catch (e) {
|
|
3385
3541
|
return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
|
|
@@ -3436,7 +3592,8 @@ async function initAtlisp() {
|
|
|
3436
3592
|
if (!cad.connected) {
|
|
3437
3593
|
await cad.connect();
|
|
3438
3594
|
}
|
|
3439
|
-
if (!cad.connected)
|
|
3595
|
+
if (!cad.connected)
|
|
3596
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3440
3597
|
const code = `(if (null @::load-module)
|
|
3441
3598
|
(progn
|
|
3442
3599
|
(vl-load-com)
|
|
@@ -3478,12 +3635,15 @@ async function fetchPackages() {
|
|
|
3478
3635
|
return cachedPackages || MOCK_PACKAGES;
|
|
3479
3636
|
}
|
|
3480
3637
|
function flattenPackages(data) {
|
|
3481
|
-
if (Array.isArray(data))
|
|
3482
|
-
|
|
3638
|
+
if (Array.isArray(data))
|
|
3639
|
+
return data;
|
|
3640
|
+
if (data && Array.isArray(data.packages))
|
|
3641
|
+
return data.packages;
|
|
3483
3642
|
return [];
|
|
3484
3643
|
}
|
|
3485
3644
|
async function listPackages() {
|
|
3486
|
-
if (!cad.connected)
|
|
3645
|
+
if (!cad.connected)
|
|
3646
|
+
await cad.connect();
|
|
3487
3647
|
if (!cad.connected) {
|
|
3488
3648
|
const data2 = await fetchPackages();
|
|
3489
3649
|
const items2 = flattenPackages(data2);
|
|
@@ -3491,7 +3651,8 @@ async function listPackages() {
|
|
|
3491
3651
|
return { content: [{ type: "text", text: text2 }] };
|
|
3492
3652
|
}
|
|
3493
3653
|
const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
|
|
3494
|
-
if (result && result !== "nil")
|
|
3654
|
+
if (result && result !== "nil")
|
|
3655
|
+
return { content: [{ type: "text", text: result }] };
|
|
3495
3656
|
const data = await fetchPackages();
|
|
3496
3657
|
const items = flattenPackages(data);
|
|
3497
3658
|
const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
|
|
@@ -3511,10 +3672,12 @@ async function searchPackages(query) {
|
|
|
3511
3672
|
for (const p of items) {
|
|
3512
3673
|
const name = (p.name || "").toLowerCase();
|
|
3513
3674
|
const desc = (p.description || "").toLowerCase();
|
|
3514
|
-
if (name.includes(q) || desc.includes(q))
|
|
3675
|
+
if (name.includes(q) || desc.includes(q))
|
|
3676
|
+
results.push(p);
|
|
3515
3677
|
}
|
|
3516
3678
|
} else {
|
|
3517
|
-
for (const p of items)
|
|
3679
|
+
for (const p of items)
|
|
3680
|
+
results.push(p);
|
|
3518
3681
|
}
|
|
3519
3682
|
if (results.length === 0) {
|
|
3520
3683
|
return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
|
|
@@ -3603,7 +3766,8 @@ async function getFunctionUsage(funcName, packageName) {
|
|
|
3603
3766
|
if (data) {
|
|
3604
3767
|
const funcs = Object.values(data.all_functions || {});
|
|
3605
3768
|
const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
|
|
3606
|
-
if (func)
|
|
3769
|
+
if (func)
|
|
3770
|
+
results.push(func);
|
|
3607
3771
|
}
|
|
3608
3772
|
if (results.length === 0 && FUNCTIONS_DIR) {
|
|
3609
3773
|
try {
|
|
@@ -3612,7 +3776,8 @@ async function getFunctionUsage(funcName, packageName) {
|
|
|
3612
3776
|
const raw = fs6.readFileSync(path9.join(FUNCTIONS_DIR, file), "utf-8");
|
|
3613
3777
|
const data2 = JSON.parse(raw);
|
|
3614
3778
|
const func = data2.functions?.find((f2) => f2.name === funcName);
|
|
3615
|
-
if (func)
|
|
3779
|
+
if (func)
|
|
3780
|
+
results.push(func);
|
|
3616
3781
|
}
|
|
3617
3782
|
} catch (e) {
|
|
3618
3783
|
log(`function-handlers: FUNCTIONS_DIR read error: ${e.message}`);
|
|
@@ -3682,7 +3847,8 @@ async function getEntity(handle) {
|
|
|
3682
3847
|
if (!cad.connected) {
|
|
3683
3848
|
await cad.connect();
|
|
3684
3849
|
}
|
|
3685
|
-
if (!cad.connected)
|
|
3850
|
+
if (!cad.connected)
|
|
3851
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3686
3852
|
const code = `(progn
|
|
3687
3853
|
(vl-load-com)
|
|
3688
3854
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -3714,7 +3880,8 @@ async function setEntityProperty(handle, property, value) {
|
|
|
3714
3880
|
if (!cad.connected) {
|
|
3715
3881
|
await cad.connect();
|
|
3716
3882
|
}
|
|
3717
|
-
if (!cad.connected)
|
|
3883
|
+
if (!cad.connected)
|
|
3884
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3718
3885
|
let propCode = "";
|
|
3719
3886
|
switch (property) {
|
|
3720
3887
|
case "layer":
|
|
@@ -3757,7 +3924,8 @@ async function deleteEntity(handle) {
|
|
|
3757
3924
|
if (!cad.connected) {
|
|
3758
3925
|
await cad.connect();
|
|
3759
3926
|
}
|
|
3760
|
-
if (!cad.connected)
|
|
3927
|
+
if (!cad.connected)
|
|
3928
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3761
3929
|
const code = `(progn
|
|
3762
3930
|
(vl-load-com)
|
|
3763
3931
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -3782,12 +3950,15 @@ async function selectEntities(filter) {
|
|
|
3782
3950
|
if (!cad.connected) {
|
|
3783
3951
|
await cad.connect();
|
|
3784
3952
|
}
|
|
3785
|
-
if (!cad.connected)
|
|
3953
|
+
if (!cad.connected)
|
|
3954
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3786
3955
|
let filterCode = "nil";
|
|
3787
3956
|
if (filter && (filter.type || filter.layer)) {
|
|
3788
3957
|
const items = [];
|
|
3789
|
-
if (filter.type)
|
|
3790
|
-
|
|
3958
|
+
if (filter.type)
|
|
3959
|
+
items.push(`'(0 . "${escapeLispString(filter.type)}")`);
|
|
3960
|
+
if (filter.layer)
|
|
3961
|
+
items.push(`'(8 . "${escapeLispString(filter.layer)}")`);
|
|
3791
3962
|
filterCode = `(list ${items.join(" ")})`;
|
|
3792
3963
|
}
|
|
3793
3964
|
const code = `(progn
|
|
@@ -3820,7 +3991,8 @@ async function createLayer(name, color = 7, linetype = "Continuous") {
|
|
|
3820
3991
|
if (!cad.connected) {
|
|
3821
3992
|
await cad.connect();
|
|
3822
3993
|
}
|
|
3823
|
-
if (!cad.connected)
|
|
3994
|
+
if (!cad.connected)
|
|
3995
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3824
3996
|
const code = `(progn
|
|
3825
3997
|
(vl-load-com)
|
|
3826
3998
|
(if (not (tblsearch "LAYER" "${escapeLispString(name)}"))
|
|
@@ -3856,7 +4028,8 @@ async function deleteLayer(name) {
|
|
|
3856
4028
|
if (!cad.connected) {
|
|
3857
4029
|
await cad.connect();
|
|
3858
4030
|
}
|
|
3859
|
-
if (!cad.connected)
|
|
4031
|
+
if (!cad.connected)
|
|
4032
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3860
4033
|
const code = `(progn
|
|
3861
4034
|
(vl-load-com)
|
|
3862
4035
|
(cond
|
|
@@ -3890,7 +4063,8 @@ async function setLayerProperty(name, property, value) {
|
|
|
3890
4063
|
if (!cad.connected) {
|
|
3891
4064
|
await cad.connect();
|
|
3892
4065
|
}
|
|
3893
|
-
if (!cad.connected)
|
|
4066
|
+
if (!cad.connected)
|
|
4067
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3894
4068
|
let propCode = "";
|
|
3895
4069
|
switch (property) {
|
|
3896
4070
|
case "color":
|
|
@@ -3938,7 +4112,8 @@ async function setCurrentLayer(name) {
|
|
|
3938
4112
|
if (!cad.connected) {
|
|
3939
4113
|
await cad.connect();
|
|
3940
4114
|
}
|
|
3941
|
-
if (!cad.connected)
|
|
4115
|
+
if (!cad.connected)
|
|
4116
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3942
4117
|
const code = `(progn
|
|
3943
4118
|
(vl-load-com)
|
|
3944
4119
|
(if (tblsearch "LAYER" "${escapeLispString(name)}")
|
|
@@ -3966,7 +4141,8 @@ async function createBlock(name, entities) {
|
|
|
3966
4141
|
if (!cad.connected) {
|
|
3967
4142
|
await cad.connect();
|
|
3968
4143
|
}
|
|
3969
|
-
if (!cad.connected)
|
|
4144
|
+
if (!cad.connected)
|
|
4145
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3970
4146
|
const code = `(progn
|
|
3971
4147
|
(vl-load-com)
|
|
3972
4148
|
(if (not (tblsearch "BLOCK" "${escapeLispString(name)}"))
|
|
@@ -4003,7 +4179,8 @@ async function insertBlock(blockName, point, scale = 1, rotation = 0) {
|
|
|
4003
4179
|
if (!cad.connected) {
|
|
4004
4180
|
await cad.connect();
|
|
4005
4181
|
}
|
|
4006
|
-
if (!cad.connected)
|
|
4182
|
+
if (!cad.connected)
|
|
4183
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4007
4184
|
const coords = Array.isArray(point) ? point : point.split(",").map((s) => parseFloat(s.trim()));
|
|
4008
4185
|
if (coords.length < 2) {
|
|
4009
4186
|
return { content: [{ type: "text", text: "\u63D2\u5165\u70B9\u683C\u5F0F\u9519\u8BEF\uFF0C\u9700\u8981 x,y \u6216 [x,y,z]" }], isError: true };
|
|
@@ -4033,7 +4210,8 @@ async function getBlocks() {
|
|
|
4033
4210
|
if (!cad.connected) {
|
|
4034
4211
|
await cad.connect();
|
|
4035
4212
|
}
|
|
4036
|
-
if (!cad.connected)
|
|
4213
|
+
if (!cad.connected)
|
|
4214
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4037
4215
|
const code = `(progn
|
|
4038
4216
|
(vl-load-com)
|
|
4039
4217
|
(setq blocks nil)
|
|
@@ -4056,7 +4234,8 @@ async function explodeBlock(handle) {
|
|
|
4056
4234
|
if (!cad.connected) {
|
|
4057
4235
|
await cad.connect();
|
|
4058
4236
|
}
|
|
4059
|
-
if (!cad.connected)
|
|
4237
|
+
if (!cad.connected)
|
|
4238
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4060
4239
|
const code = `(progn
|
|
4061
4240
|
(vl-load-com)
|
|
4062
4241
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -4092,7 +4271,8 @@ async function openDwg(filePath) {
|
|
|
4092
4271
|
if (!cad.connected) {
|
|
4093
4272
|
await cad.connect();
|
|
4094
4273
|
}
|
|
4095
|
-
if (!cad.connected)
|
|
4274
|
+
if (!cad.connected)
|
|
4275
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4096
4276
|
try {
|
|
4097
4277
|
validateFilePath(filePath);
|
|
4098
4278
|
} catch (e) {
|
|
@@ -4133,7 +4313,8 @@ async function saveDwg(filePath = null) {
|
|
|
4133
4313
|
if (!cad.connected) {
|
|
4134
4314
|
await cad.connect();
|
|
4135
4315
|
}
|
|
4136
|
-
if (!cad.connected)
|
|
4316
|
+
if (!cad.connected)
|
|
4317
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4137
4318
|
if (filePath) {
|
|
4138
4319
|
try {
|
|
4139
4320
|
validateFilePath(filePath);
|
|
@@ -4164,7 +4345,8 @@ async function exportPdf(outputPath, layout = "Model") {
|
|
|
4164
4345
|
if (!cad.connected) {
|
|
4165
4346
|
await cad.connect();
|
|
4166
4347
|
}
|
|
4167
|
-
if (!cad.connected)
|
|
4348
|
+
if (!cad.connected)
|
|
4349
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4168
4350
|
try {
|
|
4169
4351
|
validateFilePath(outputPath);
|
|
4170
4352
|
} catch (e) {
|
|
@@ -4196,7 +4378,8 @@ async function closeDwg(save = false) {
|
|
|
4196
4378
|
if (!cad.connected) {
|
|
4197
4379
|
await cad.connect();
|
|
4198
4380
|
}
|
|
4199
|
-
if (!cad.connected)
|
|
4381
|
+
if (!cad.connected)
|
|
4382
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4200
4383
|
const code = `(progn
|
|
4201
4384
|
(vl-load-com)
|
|
4202
4385
|
(if ${save ? "T" : "nil"}
|
|
@@ -4223,7 +4406,8 @@ async function createDimension(type, points, style = {}) {
|
|
|
4223
4406
|
if (!cad.connected) {
|
|
4224
4407
|
await cad.connect();
|
|
4225
4408
|
}
|
|
4226
|
-
if (!cad.connected)
|
|
4409
|
+
if (!cad.connected)
|
|
4410
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4227
4411
|
let dimCode = "";
|
|
4228
4412
|
const validTypes = ["ALIGNED", "LINEAR", "ORDINATE", "RADIAL", "DIAMETER", "ANGULAR"];
|
|
4229
4413
|
const dimType = (type || "ALIGNED").toUpperCase();
|
|
@@ -4265,7 +4449,8 @@ async function getDimensionValue(handle) {
|
|
|
4265
4449
|
if (!cad.connected) {
|
|
4266
4450
|
await cad.connect();
|
|
4267
4451
|
}
|
|
4268
|
-
if (!cad.connected)
|
|
4452
|
+
if (!cad.connected)
|
|
4453
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4269
4454
|
const code = `(progn
|
|
4270
4455
|
(vl-load-com)
|
|
4271
4456
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -4296,7 +4481,8 @@ async function createHatch(patternName, boundary, scale = 1, angle = 0) {
|
|
|
4296
4481
|
if (!cad.connected) {
|
|
4297
4482
|
await cad.connect();
|
|
4298
4483
|
}
|
|
4299
|
-
if (!cad.connected)
|
|
4484
|
+
if (!cad.connected)
|
|
4485
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4300
4486
|
const code = `(progn
|
|
4301
4487
|
(vl-load-com)
|
|
4302
4488
|
(command "._BHATCH" "p" "${escapeLispString(patternName)}" "s" "s" "sc" ${scale} "an" ${angle} "")
|
|
@@ -4316,12 +4502,17 @@ async function setHatchProperties(handle, props) {
|
|
|
4316
4502
|
if (!cad.connected) {
|
|
4317
4503
|
await cad.connect();
|
|
4318
4504
|
}
|
|
4319
|
-
if (!cad.connected)
|
|
4505
|
+
if (!cad.connected)
|
|
4506
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4320
4507
|
let propCode = "";
|
|
4321
|
-
if (props.pattern)
|
|
4322
|
-
|
|
4323
|
-
if (props.
|
|
4324
|
-
|
|
4508
|
+
if (props.pattern)
|
|
4509
|
+
propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "p" "${escapeLispString(props.pattern)}")`;
|
|
4510
|
+
if (props.scale)
|
|
4511
|
+
propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "s" ${parseFloat(props.scale) || 1})`;
|
|
4512
|
+
if (props.angle)
|
|
4513
|
+
propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "an" ${parseFloat(props.angle) || 0})`;
|
|
4514
|
+
if (props.color)
|
|
4515
|
+
propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "c" ${parseInt(props.color) || 256})`;
|
|
4325
4516
|
const code = `(progn
|
|
4326
4517
|
(vl-load-com)
|
|
4327
4518
|
${propCode}
|
|
@@ -4338,7 +4529,8 @@ async function getBlockAttributes(blockHandle) {
|
|
|
4338
4529
|
if (!cad.connected) {
|
|
4339
4530
|
await cad.connect();
|
|
4340
4531
|
}
|
|
4341
|
-
if (!cad.connected)
|
|
4532
|
+
if (!cad.connected)
|
|
4533
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4342
4534
|
const code = `(progn
|
|
4343
4535
|
(vl-load-com)
|
|
4344
4536
|
(if (setq ent (handent "${escapeLispString(blockHandle)}"))
|
|
@@ -4367,7 +4559,8 @@ async function setBlockAttribute(blockHandle, tag, value) {
|
|
|
4367
4559
|
if (!cad.connected) {
|
|
4368
4560
|
await cad.connect();
|
|
4369
4561
|
}
|
|
4370
|
-
if (!cad.connected)
|
|
4562
|
+
if (!cad.connected)
|
|
4563
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4371
4564
|
const code = `(progn
|
|
4372
4565
|
(vl-load-com)
|
|
4373
4566
|
(if (setq ent (handent "${escapeLispString(blockHandle)}"))
|
|
@@ -4403,7 +4596,8 @@ async function zoomToExtents() {
|
|
|
4403
4596
|
if (!cad.connected) {
|
|
4404
4597
|
await cad.connect();
|
|
4405
4598
|
}
|
|
4406
|
-
if (!cad.connected)
|
|
4599
|
+
if (!cad.connected)
|
|
4600
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4407
4601
|
const code = `(progn
|
|
4408
4602
|
(vl-load-com)
|
|
4409
4603
|
(command "._ZOOM" "E")
|
|
@@ -4420,7 +4614,8 @@ async function zoomToWindow(p1, p2) {
|
|
|
4420
4614
|
if (!cad.connected) {
|
|
4421
4615
|
await cad.connect();
|
|
4422
4616
|
}
|
|
4423
|
-
if (!cad.connected)
|
|
4617
|
+
if (!cad.connected)
|
|
4618
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4424
4619
|
const code = `(command "._ZOOM" "W" (list ${toSafePoint(p1)}) (list ${toSafePoint(p2)}))`;
|
|
4425
4620
|
try {
|
|
4426
4621
|
await cad.sendCommand(code + "\n");
|
|
@@ -4433,7 +4628,8 @@ async function createNamedView(viewName, center = null) {
|
|
|
4433
4628
|
if (!cad.connected) {
|
|
4434
4629
|
await cad.connect();
|
|
4435
4630
|
}
|
|
4436
|
-
if (!cad.connected)
|
|
4631
|
+
if (!cad.connected)
|
|
4632
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4437
4633
|
const code = center ? `(command ".-VIEW" "S" "${escapeLispString(viewName)}" "C" (list ${toSafePoint(center)}))` : `(command ".-VIEW" "S" "${escapeLispString(viewName)}")`;
|
|
4438
4634
|
try {
|
|
4439
4635
|
await cad.sendCommand(code + "\n");
|
|
@@ -4446,7 +4642,8 @@ async function restoreNamedView(viewName) {
|
|
|
4446
4642
|
if (!cad.connected) {
|
|
4447
4643
|
await cad.connect();
|
|
4448
4644
|
}
|
|
4449
|
-
if (!cad.connected)
|
|
4645
|
+
if (!cad.connected)
|
|
4646
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4450
4647
|
const code = `(command ".-VIEW" "R" "${escapeLispString(viewName)}")`;
|
|
4451
4648
|
try {
|
|
4452
4649
|
await cad.sendCommand(code + "\n");
|
|
@@ -4459,7 +4656,8 @@ async function listNamedViews() {
|
|
|
4459
4656
|
if (!cad.connected) {
|
|
4460
4657
|
await cad.connect();
|
|
4461
4658
|
}
|
|
4462
|
-
if (!cad.connected)
|
|
4659
|
+
if (!cad.connected)
|
|
4660
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4463
4661
|
const code = `(progn
|
|
4464
4662
|
(vl-load-com)
|
|
4465
4663
|
(setq views nil)
|
|
@@ -4479,7 +4677,8 @@ async function exportDxf(outputPath, version2 = "R2018") {
|
|
|
4479
4677
|
if (!cad.connected) {
|
|
4480
4678
|
await cad.connect();
|
|
4481
4679
|
}
|
|
4482
|
-
if (!cad.connected)
|
|
4680
|
+
if (!cad.connected)
|
|
4681
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4483
4682
|
const versionMap = {
|
|
4484
4683
|
"R2018": "AC1027",
|
|
4485
4684
|
"R2015": "AC1024",
|
|
@@ -4509,7 +4708,8 @@ async function exportDwf(outputPath) {
|
|
|
4509
4708
|
if (!cad.connected) {
|
|
4510
4709
|
await cad.connect();
|
|
4511
4710
|
}
|
|
4512
|
-
if (!cad.connected)
|
|
4711
|
+
if (!cad.connected)
|
|
4712
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4513
4713
|
const code = `(progn
|
|
4514
4714
|
(vl-load-com)
|
|
4515
4715
|
(vla-export (vla-get-activedocument (vlax-get-acad-object)) "${escapeLispString(outputPath)}" "dwf")
|
|
@@ -4529,7 +4729,8 @@ async function batchSetLayer(handles, layerName) {
|
|
|
4529
4729
|
if (!cad.connected) {
|
|
4530
4730
|
await cad.connect();
|
|
4531
4731
|
}
|
|
4532
|
-
if (!cad.connected)
|
|
4732
|
+
if (!cad.connected)
|
|
4733
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4533
4734
|
if (!Array.isArray(handles) || handles.length === 0) {
|
|
4534
4735
|
return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
|
|
4535
4736
|
}
|
|
@@ -4559,7 +4760,8 @@ async function createUcs(name, origin = "0,0,0", xAxis = "1,0,0", yAxis = "0,1,0
|
|
|
4559
4760
|
if (!cad.connected) {
|
|
4560
4761
|
await cad.connect();
|
|
4561
4762
|
}
|
|
4562
|
-
if (!cad.connected)
|
|
4763
|
+
if (!cad.connected)
|
|
4764
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4563
4765
|
const code = `(progn
|
|
4564
4766
|
(vl-load-com)
|
|
4565
4767
|
(if (not (tblsearch "UCS" "${escapeLispString(name)}"))
|
|
@@ -4590,7 +4792,8 @@ async function setUcs(name) {
|
|
|
4590
4792
|
if (!cad.connected) {
|
|
4591
4793
|
await cad.connect();
|
|
4592
4794
|
}
|
|
4593
|
-
if (!cad.connected)
|
|
4795
|
+
if (!cad.connected)
|
|
4796
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4594
4797
|
const code = `(progn
|
|
4595
4798
|
(vl-load-com)
|
|
4596
4799
|
(if (tblsearch "UCS" "${escapeLispString(name)}")
|
|
@@ -4615,7 +4818,8 @@ async function listUcs() {
|
|
|
4615
4818
|
if (!cad.connected) {
|
|
4616
4819
|
await cad.connect();
|
|
4617
4820
|
}
|
|
4618
|
-
if (!cad.connected)
|
|
4821
|
+
if (!cad.connected)
|
|
4822
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4619
4823
|
const code = `(progn
|
|
4620
4824
|
(vl-load-com)
|
|
4621
4825
|
(setq ucsList nil)
|
|
@@ -4638,7 +4842,8 @@ async function deleteUcs(name) {
|
|
|
4638
4842
|
if (!cad.connected) {
|
|
4639
4843
|
await cad.connect();
|
|
4640
4844
|
}
|
|
4641
|
-
if (!cad.connected)
|
|
4845
|
+
if (!cad.connected)
|
|
4846
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4642
4847
|
const code = `(progn
|
|
4643
4848
|
(vl-load-com)
|
|
4644
4849
|
(if (tblsearch "UCS" "${escapeLispString(name)}")
|
|
@@ -4663,7 +4868,8 @@ async function getCurrentUcs() {
|
|
|
4663
4868
|
if (!cad.connected) {
|
|
4664
4869
|
await cad.connect();
|
|
4665
4870
|
}
|
|
4666
|
-
if (!cad.connected)
|
|
4871
|
+
if (!cad.connected)
|
|
4872
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4667
4873
|
const code = `(progn
|
|
4668
4874
|
(vl-load-com)
|
|
4669
4875
|
(vla-get-activeutilities (vla-get-document (vla-get-application (vlax-get-acad-object))))
|
|
@@ -4680,7 +4886,8 @@ async function createLayout(name) {
|
|
|
4680
4886
|
if (!cad.connected) {
|
|
4681
4887
|
await cad.connect();
|
|
4682
4888
|
}
|
|
4683
|
-
if (!cad.connected)
|
|
4889
|
+
if (!cad.connected)
|
|
4890
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4684
4891
|
const code = `(progn
|
|
4685
4892
|
(vl-load-com)
|
|
4686
4893
|
(if (not (tblsearch "LAYOUT" "${escapeLispString(name)}"))
|
|
@@ -4708,7 +4915,8 @@ async function setLayout(name) {
|
|
|
4708
4915
|
if (!cad.connected) {
|
|
4709
4916
|
await cad.connect();
|
|
4710
4917
|
}
|
|
4711
|
-
if (!cad.connected)
|
|
4918
|
+
if (!cad.connected)
|
|
4919
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4712
4920
|
const code = `(progn
|
|
4713
4921
|
(vl-load-com)
|
|
4714
4922
|
(vlax-for layout (vla-get-layouts (vla-get-activedocument (vla-get-application (vlax-get-acad-object))))
|
|
@@ -4738,7 +4946,8 @@ async function listLayouts() {
|
|
|
4738
4946
|
if (!cad.connected) {
|
|
4739
4947
|
await cad.connect();
|
|
4740
4948
|
}
|
|
4741
|
-
if (!cad.connected)
|
|
4949
|
+
if (!cad.connected)
|
|
4950
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4742
4951
|
const code = `(progn
|
|
4743
4952
|
(vl-load-com)
|
|
4744
4953
|
(setq layouts nil)
|
|
@@ -4761,7 +4970,8 @@ async function deleteLayout(name) {
|
|
|
4761
4970
|
if (!cad.connected) {
|
|
4762
4971
|
await cad.connect();
|
|
4763
4972
|
}
|
|
4764
|
-
if (!cad.connected)
|
|
4973
|
+
if (!cad.connected)
|
|
4974
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4765
4975
|
if (name === "Model" || name === "\u6A21\u578B") {
|
|
4766
4976
|
return { content: [{ type: "text", text: "\u65E0\u6CD5\u5220\u9664\u6A21\u578B\u7A7A\u95F4" }], isError: true };
|
|
4767
4977
|
}
|
|
@@ -4789,7 +4999,8 @@ async function getCurrentLayout() {
|
|
|
4789
4999
|
if (!cad.connected) {
|
|
4790
5000
|
await cad.connect();
|
|
4791
5001
|
}
|
|
4792
|
-
if (!cad.connected)
|
|
5002
|
+
if (!cad.connected)
|
|
5003
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4793
5004
|
const code = `(vl-prin1-to-string (getvar "CTAB"))`;
|
|
4794
5005
|
try {
|
|
4795
5006
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -4802,7 +5013,8 @@ async function renameLayout(oldName, newName) {
|
|
|
4802
5013
|
if (!cad.connected) {
|
|
4803
5014
|
await cad.connect();
|
|
4804
5015
|
}
|
|
4805
|
-
if (!cad.connected)
|
|
5016
|
+
if (!cad.connected)
|
|
5017
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4806
5018
|
const code = `(progn
|
|
4807
5019
|
(vl-load-com)
|
|
4808
5020
|
(if (tblsearch "LAYOUT" "${escapeLispString(oldName)}")
|
|
@@ -4834,7 +5046,8 @@ async function plotToPdf(outputPath, layout = "Model", style = {}) {
|
|
|
4834
5046
|
if (!cad.connected) {
|
|
4835
5047
|
await cad.connect();
|
|
4836
5048
|
}
|
|
4837
|
-
if (!cad.connected)
|
|
5049
|
+
if (!cad.connected)
|
|
5050
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4838
5051
|
const paperSize = style.paperSize || "A4";
|
|
4839
5052
|
const code = `(progn
|
|
4840
5053
|
(vl-load-com)
|
|
@@ -4864,7 +5077,8 @@ async function plotToPrinter(printerName, layout = "Model") {
|
|
|
4864
5077
|
if (!cad.connected) {
|
|
4865
5078
|
await cad.connect();
|
|
4866
5079
|
}
|
|
4867
|
-
if (!cad.connected)
|
|
5080
|
+
if (!cad.connected)
|
|
5081
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4868
5082
|
const code = `(progn
|
|
4869
5083
|
(vl-load-com)
|
|
4870
5084
|
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
|
|
@@ -4890,7 +5104,8 @@ async function createGroup(name, handles) {
|
|
|
4890
5104
|
if (!cad.connected) {
|
|
4891
5105
|
await cad.connect();
|
|
4892
5106
|
}
|
|
4893
|
-
if (!cad.connected)
|
|
5107
|
+
if (!cad.connected)
|
|
5108
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4894
5109
|
if (!Array.isArray(handles) || handles.length === 0) {
|
|
4895
5110
|
return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
|
|
4896
5111
|
}
|
|
@@ -4916,7 +5131,8 @@ async function deleteGroup(name) {
|
|
|
4916
5131
|
if (!cad.connected) {
|
|
4917
5132
|
await cad.connect();
|
|
4918
5133
|
}
|
|
4919
|
-
if (!cad.connected)
|
|
5134
|
+
if (!cad.connected)
|
|
5135
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4920
5136
|
const code = `(progn
|
|
4921
5137
|
(vl-load-com)
|
|
4922
5138
|
(if (tblsearch "GROUP" "${escapeLispString(name)}")
|
|
@@ -4941,7 +5157,8 @@ async function listGroups() {
|
|
|
4941
5157
|
if (!cad.connected) {
|
|
4942
5158
|
await cad.connect();
|
|
4943
5159
|
}
|
|
4944
|
-
if (!cad.connected)
|
|
5160
|
+
if (!cad.connected)
|
|
5161
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4945
5162
|
const code = `(progn
|
|
4946
5163
|
(vl-load-com)
|
|
4947
5164
|
(setq groups nil)
|
|
@@ -4961,7 +5178,8 @@ async function getGroupEntities(groupName) {
|
|
|
4961
5178
|
if (!cad.connected) {
|
|
4962
5179
|
await cad.connect();
|
|
4963
5180
|
}
|
|
4964
|
-
if (!cad.connected)
|
|
5181
|
+
if (!cad.connected)
|
|
5182
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4965
5183
|
const code = `(progn
|
|
4966
5184
|
(vl-load-com)
|
|
4967
5185
|
(if (tblsearch "GROUP" "${escapeLispString(groupName)}")
|
|
@@ -4999,15 +5217,16 @@ async function measureDistance(p1, p2) {
|
|
|
4999
5217
|
if (!cad.connected) {
|
|
5000
5218
|
await cad.connect();
|
|
5001
5219
|
}
|
|
5002
|
-
if (!cad.connected)
|
|
5220
|
+
if (!cad.connected)
|
|
5221
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5003
5222
|
const code = `(progn
|
|
5004
5223
|
(vl-load-com)
|
|
5005
5224
|
(setq pt1 (list ${toSafePoint3(p1)}) pt2 (list ${toSafePoint3(p2)}))
|
|
5006
5225
|
(setq dist (distance pt1 pt2))
|
|
5007
|
-
(setq
|
|
5226
|
+
(setq ang (angle pt1 pt2))
|
|
5008
5227
|
(list
|
|
5009
5228
|
(strcat "Distance: " (rtos dist 2 4))
|
|
5010
|
-
(strcat "Angle: " (rtos (* 180 (/
|
|
5229
|
+
(strcat "Angle: " (rtos (* 180 (/ ang pi)) 2 2) "\xB0")
|
|
5011
5230
|
(strcat "DX: " (rtos (- (car pt2) (car pt1)) 2 4))
|
|
5012
5231
|
(strcat "DY: " (rtos (- (cadr pt2) (cadr pt1)) 2 4))
|
|
5013
5232
|
)
|
|
@@ -5023,7 +5242,8 @@ async function measureArea(points) {
|
|
|
5023
5242
|
if (!cad.connected) {
|
|
5024
5243
|
await cad.connect();
|
|
5025
5244
|
}
|
|
5026
|
-
if (!cad.connected)
|
|
5245
|
+
if (!cad.connected)
|
|
5246
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5027
5247
|
const pts = Array.isArray(points) ? points : points.split(/[\s,]+/).filter(Boolean);
|
|
5028
5248
|
if (pts.length < 3) {
|
|
5029
5249
|
return { content: [{ type: "text", text: "\u81F3\u5C11\u9700\u8981 3 \u4E2A\u70B9" }], isError: true };
|
|
@@ -5060,7 +5280,8 @@ async function getEntityInfo(handle) {
|
|
|
5060
5280
|
if (!cad.connected) {
|
|
5061
5281
|
await cad.connect();
|
|
5062
5282
|
}
|
|
5063
|
-
if (!cad.connected)
|
|
5283
|
+
if (!cad.connected)
|
|
5284
|
+
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5064
5285
|
const code = `(progn
|
|
5065
5286
|
(vl-load-com)
|
|
5066
5287
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -5100,7 +5321,8 @@ function parseHandleList(handles) {
|
|
|
5100
5321
|
handles = handles.split(",").map((h) => h.trim());
|
|
5101
5322
|
}
|
|
5102
5323
|
}
|
|
5103
|
-
if (!Array.isArray(handles))
|
|
5324
|
+
if (!Array.isArray(handles))
|
|
5325
|
+
handles = [handles];
|
|
5104
5326
|
return handles;
|
|
5105
5327
|
}
|
|
5106
5328
|
async function batchRename(handles, newNameTemplate, startNum = 1) {
|
|
@@ -5474,7 +5696,8 @@ async function copyXdata(sourceHandle, targetHandle, appName = null) {
|
|
|
5474
5696
|
const xdataResult = await getXdata(sourceHandle, appName);
|
|
5475
5697
|
if (xdataResult.content?.[0]) {
|
|
5476
5698
|
const parsed = JSON.parse(xdataResult.content[0].text);
|
|
5477
|
-
if (parsed.xdata)
|
|
5699
|
+
if (parsed.xdata)
|
|
5700
|
+
return await setXdata(targetHandle, appName, parsed.xdata);
|
|
5478
5701
|
}
|
|
5479
5702
|
return mcpError("\u6E90\u5B9E\u4F53\u672A\u627E\u5230\u6269\u5C55\u6570\u636E");
|
|
5480
5703
|
} else {
|
|
@@ -5709,8 +5932,10 @@ async function createSheetSetArchive(sheetSetName, archivePath) {
|
|
|
5709
5932
|
// src/handlers/3d-handlers.js
|
|
5710
5933
|
init_cad();
|
|
5711
5934
|
function parsePoint(point) {
|
|
5712
|
-
if (Array.isArray(point))
|
|
5713
|
-
|
|
5935
|
+
if (Array.isArray(point))
|
|
5936
|
+
return point.join(" ");
|
|
5937
|
+
if (typeof point === "string")
|
|
5938
|
+
return point;
|
|
5714
5939
|
return "0,0,0";
|
|
5715
5940
|
}
|
|
5716
5941
|
async function createBox(center, length, width, height) {
|
|
@@ -8182,7 +8407,8 @@ function validateToolArgs(name, args) {
|
|
|
8182
8407
|
const baseType = type.replace("?", "");
|
|
8183
8408
|
const val = args[key];
|
|
8184
8409
|
if (val === void 0 || val === null) {
|
|
8185
|
-
if (isOptional)
|
|
8410
|
+
if (isOptional)
|
|
8411
|
+
continue;
|
|
8186
8412
|
throw new Error(`Missing required argument: ${key}`);
|
|
8187
8413
|
}
|
|
8188
8414
|
const actualType = typeof args[key];
|
|
@@ -8227,7 +8453,8 @@ ${CAD_PLATFORMS.join("\n")}
|
|
|
8227
8453
|
},
|
|
8228
8454
|
import_funlib: async (a) => {
|
|
8229
8455
|
const data = await loadAtlibFunctionLib();
|
|
8230
|
-
if (!data)
|
|
8456
|
+
if (!data)
|
|
8457
|
+
return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
|
|
8231
8458
|
if (a.format === "list") {
|
|
8232
8459
|
const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
|
|
8233
8460
|
return { content: [{ type: "text", text: items.join("\n") }] };
|
|
@@ -8437,7 +8664,8 @@ function notifyResourceChanges(toolName) {
|
|
|
8437
8664
|
}
|
|
8438
8665
|
async function handleToolCall(name, args) {
|
|
8439
8666
|
const handler = TOOL_HANDLERS[name];
|
|
8440
|
-
if (!handler)
|
|
8667
|
+
if (!handler)
|
|
8668
|
+
return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
|
|
8441
8669
|
try {
|
|
8442
8670
|
validateToolArgs(name, args || {});
|
|
8443
8671
|
const result = await handler(args || {});
|
|
@@ -8498,10 +8726,12 @@ var RateLimiter = class {
|
|
|
8498
8726
|
this.keyLimits = /* @__PURE__ */ new Map();
|
|
8499
8727
|
}
|
|
8500
8728
|
getKeyLimit(apiKey2) {
|
|
8501
|
-
if (!apiKey2)
|
|
8729
|
+
if (!apiKey2)
|
|
8730
|
+
return this.defaultLimit;
|
|
8502
8731
|
if (config_default.apiKeys && config_default.apiKeys.length > 0) {
|
|
8503
8732
|
const found = config_default.apiKeys.find((k) => k.key === apiKey2);
|
|
8504
|
-
if (found)
|
|
8733
|
+
if (found)
|
|
8734
|
+
return found.limit;
|
|
8505
8735
|
}
|
|
8506
8736
|
if (config_default.apiKey && apiKey2 === config_default.apiKey) {
|
|
8507
8737
|
return config_default.apiKeyRateLimit || 1e3;
|
|
@@ -8509,10 +8739,12 @@ var RateLimiter = class {
|
|
|
8509
8739
|
return this.defaultLimit;
|
|
8510
8740
|
}
|
|
8511
8741
|
getKeyInfo(apiKey2) {
|
|
8512
|
-
if (!apiKey2)
|
|
8742
|
+
if (!apiKey2)
|
|
8743
|
+
return { name: "anonymous", limit: this.defaultLimit };
|
|
8513
8744
|
if (config_default.apiKeys && config_default.apiKeys.length > 0) {
|
|
8514
8745
|
const found = config_default.apiKeys.find((k) => k.key === apiKey2);
|
|
8515
|
-
if (found)
|
|
8746
|
+
if (found)
|
|
8747
|
+
return { name: found.name || apiKey2, limit: found.limit };
|
|
8516
8748
|
}
|
|
8517
8749
|
if (config_default.apiKey && apiKey2 === config_default.apiKey) {
|
|
8518
8750
|
return { name: "admin", limit: config_default.apiKeyRateLimit || 1e3 };
|
|
@@ -8608,7 +8840,8 @@ var JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "applicati
|
|
|
8608
8840
|
function createJsonBodyParser() {
|
|
8609
8841
|
return async (req, res, next) => {
|
|
8610
8842
|
const ct = (req.headers["content-type"] || "").toLowerCase();
|
|
8611
|
-
if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
|
|
8843
|
+
if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
|
|
8844
|
+
return next();
|
|
8612
8845
|
try {
|
|
8613
8846
|
const chunks = [];
|
|
8614
8847
|
for await (const chunk of req) {
|
|
@@ -8641,9 +8874,11 @@ function createAuthMiddleware() {
|
|
|
8641
8874
|
const PUBLIC_PATHS = ["/health"];
|
|
8642
8875
|
return (req, res, next) => {
|
|
8643
8876
|
if (apiKey) {
|
|
8644
|
-
if (PUBLIC_PATHS.includes(req.path))
|
|
8877
|
+
if (PUBLIC_PATHS.includes(req.path))
|
|
8878
|
+
return next();
|
|
8645
8879
|
const auth = req.get("Authorization");
|
|
8646
|
-
if (auth === `Bearer ${apiKey}`)
|
|
8880
|
+
if (auth === `Bearer ${apiKey}`)
|
|
8881
|
+
return next();
|
|
8647
8882
|
return res.status(401).json({ error: "Unauthorized" });
|
|
8648
8883
|
}
|
|
8649
8884
|
next();
|
|
@@ -8651,14 +8886,16 @@ function createAuthMiddleware() {
|
|
|
8651
8886
|
}
|
|
8652
8887
|
function createCorsMiddleware() {
|
|
8653
8888
|
return (req, res, next) => {
|
|
8654
|
-
if (!enableCors)
|
|
8889
|
+
if (!enableCors)
|
|
8890
|
+
return next();
|
|
8655
8891
|
res.setHeader("Access-Control-Allow-Origin", corsOrigin);
|
|
8656
8892
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, CONNECT");
|
|
8657
8893
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, mcp-session-id, last-event-id");
|
|
8658
8894
|
res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
|
|
8659
8895
|
res.setHeader("Access-Control-Max-Age", "86400");
|
|
8660
8896
|
res.setHeader("Vary", "Accept");
|
|
8661
|
-
if (req.method === "OPTIONS")
|
|
8897
|
+
if (req.method === "OPTIONS")
|
|
8898
|
+
return res.status(204).end();
|
|
8662
8899
|
next();
|
|
8663
8900
|
};
|
|
8664
8901
|
}
|
|
@@ -9075,7 +9312,8 @@ For more info: https://atlisp.cn
|
|
|
9075
9312
|
}
|
|
9076
9313
|
}
|
|
9077
9314
|
}
|
|
9078
|
-
if (config_default.apiKey)
|
|
9315
|
+
if (config_default.apiKey)
|
|
9316
|
+
log("API Key authentication enabled");
|
|
9079
9317
|
async function initCadConnection() {
|
|
9080
9318
|
log("Attempting to connect to CAD on startup...");
|
|
9081
9319
|
try {
|
|
@@ -9140,8 +9378,10 @@ async function startServer() {
|
|
|
9140
9378
|
await cad.disconnect();
|
|
9141
9379
|
closeLog();
|
|
9142
9380
|
httpServer.close(() => {
|
|
9143
|
-
if (httpsServer)
|
|
9144
|
-
|
|
9381
|
+
if (httpsServer)
|
|
9382
|
+
httpsServer.close(() => process.exit(0));
|
|
9383
|
+
else
|
|
9384
|
+
process.exit(0);
|
|
9145
9385
|
});
|
|
9146
9386
|
setTimeout(() => process.exit(1), 5e3);
|
|
9147
9387
|
}
|