@atlisp/mcp 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atlisp-mcp.js +448 -611
- package/dist/cad-worker.js +73 -0
- package/package.json +1 -1
package/dist/atlisp-mcp.js
CHANGED
|
@@ -70,8 +70,7 @@ function parseArgs() {
|
|
|
70
70
|
return result;
|
|
71
71
|
}
|
|
72
72
|
function loadConfigFile(filePath) {
|
|
73
|
-
if (!filePath || !fs.existsSync(filePath))
|
|
74
|
-
return null;
|
|
73
|
+
if (!filePath || !fs.existsSync(filePath)) return null;
|
|
75
74
|
try {
|
|
76
75
|
const raw = fs.readFileSync(filePath, "utf-8");
|
|
77
76
|
const parsed = JSON.parse(raw);
|
|
@@ -215,6 +214,7 @@ __export(cad_exports, {
|
|
|
215
214
|
cad: () => cad,
|
|
216
215
|
default: () => cad_default,
|
|
217
216
|
getWorker: () => getWorker,
|
|
217
|
+
onDocumentChanged: () => onDocumentChanged,
|
|
218
218
|
resetWorker: () => resetWorker,
|
|
219
219
|
sendMessage: () => sendMessage
|
|
220
220
|
});
|
|
@@ -222,6 +222,20 @@ import { spawn } from "child_process";
|
|
|
222
222
|
import path2 from "path";
|
|
223
223
|
import { fileURLToPath } from "url";
|
|
224
224
|
import { randomUUID } from "crypto";
|
|
225
|
+
function onDocumentChanged(callback) {
|
|
226
|
+
_docChangeCallbacks.push(callback);
|
|
227
|
+
}
|
|
228
|
+
function emitDocumentChanged(info) {
|
|
229
|
+
if (info.docName === _activeDocName) return;
|
|
230
|
+
_activeDocName = info.docName || "";
|
|
231
|
+
for (const cb of _docChangeCallbacks) {
|
|
232
|
+
try {
|
|
233
|
+
cb(info);
|
|
234
|
+
} catch (e) {
|
|
235
|
+
console.error("doc change callback error:", e.message);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
225
239
|
function resetWorker() {
|
|
226
240
|
for (const [id, { reject, timeout }] of pendingRequests) {
|
|
227
241
|
clearTimeout(timeout);
|
|
@@ -271,8 +285,7 @@ function setupStdoutHandler(w) {
|
|
|
271
285
|
const lines = buffer.split("\n");
|
|
272
286
|
buffer = lines.pop() || "";
|
|
273
287
|
for (const line of lines) {
|
|
274
|
-
if (!line.trim())
|
|
275
|
-
continue;
|
|
288
|
+
if (!line.trim()) continue;
|
|
276
289
|
try {
|
|
277
290
|
const result = JSON.parse(line);
|
|
278
291
|
const rid = result.requestId;
|
|
@@ -285,6 +298,8 @@ function setupStdoutHandler(w) {
|
|
|
285
298
|
} else {
|
|
286
299
|
resolve(result);
|
|
287
300
|
}
|
|
301
|
+
} else if (result.type === "event" && result.eventType === "documentChanged") {
|
|
302
|
+
emitDocumentChanged({ docName: result.docName, docPath: result.docPath });
|
|
288
303
|
}
|
|
289
304
|
} catch (parseErr) {
|
|
290
305
|
console.error("JSON parse error in worker output:", parseErr.message);
|
|
@@ -298,8 +313,7 @@ function setupStdoutHandler(w) {
|
|
|
298
313
|
}
|
|
299
314
|
function getWorker(force = false) {
|
|
300
315
|
if (!worker || !worker.connected || force) {
|
|
301
|
-
if (worker)
|
|
302
|
-
worker.kill();
|
|
316
|
+
if (worker) worker.kill();
|
|
303
317
|
worker = spawn("node", [workerPath], {
|
|
304
318
|
stdio: ["pipe", "pipe", "pipe"]
|
|
305
319
|
});
|
|
@@ -307,8 +321,7 @@ function getWorker(force = false) {
|
|
|
307
321
|
const w = worker;
|
|
308
322
|
w.on("exit", (code) => {
|
|
309
323
|
console.error("worker exited with code:", code);
|
|
310
|
-
if (w !== worker)
|
|
311
|
-
return;
|
|
324
|
+
if (w !== worker) return;
|
|
312
325
|
w.connected = false;
|
|
313
326
|
for (const [id, { reject, timeout }] of pendingRequests) {
|
|
314
327
|
clearTimeout(timeout);
|
|
@@ -329,14 +342,23 @@ function getWorker(force = false) {
|
|
|
329
342
|
return worker;
|
|
330
343
|
}
|
|
331
344
|
function startHeartbeat() {
|
|
332
|
-
if (heartbeatTimer)
|
|
333
|
-
clearInterval(heartbeatTimer);
|
|
345
|
+
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
334
346
|
heartbeatTimer = setInterval(async () => {
|
|
335
347
|
try {
|
|
336
348
|
const result = await sendMessage({ type: "ping" });
|
|
337
349
|
if (!result?.pong) {
|
|
338
350
|
console.error("heartbeat failed, worker may be dead");
|
|
339
351
|
resetWorker();
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (_platform) {
|
|
355
|
+
try {
|
|
356
|
+
const docResult = await sendMessage({ type: "getActiveDocInfo", platform: _platform });
|
|
357
|
+
if (docResult?.docName) {
|
|
358
|
+
emitDocumentChanged({ docName: docResult.docName, docPath: docResult.docPath || "" });
|
|
359
|
+
}
|
|
360
|
+
} catch (e) {
|
|
361
|
+
}
|
|
340
362
|
}
|
|
341
363
|
} catch (e) {
|
|
342
364
|
console.error("heartbeat error:", e.message);
|
|
@@ -365,7 +387,7 @@ function sendMessage(msg) {
|
|
|
365
387
|
}
|
|
366
388
|
});
|
|
367
389
|
}
|
|
368
|
-
var MESSAGE_TIMEOUT, HEARTBEAT_INTERVAL, MAX_RESTART_ATTEMPTS, RESTART_BACKOFF_BASE, __dirname, workerPath, worker, _platform, heartbeatTimer, pendingRequests, stdoutHandlerSetup, MAX_BUFFER_SIZE, restartCount, restartTimer, PRIORITY_NORMAL, MAX_QUEUE_SIZE, CommandQueue, commandQueue, CadConnection, cad, cad_default;
|
|
390
|
+
var MESSAGE_TIMEOUT, HEARTBEAT_INTERVAL, MAX_RESTART_ATTEMPTS, RESTART_BACKOFF_BASE, __dirname, workerPath, worker, _platform, heartbeatTimer, pendingRequests, stdoutHandlerSetup, MAX_BUFFER_SIZE, restartCount, restartTimer, PRIORITY_NORMAL, MAX_QUEUE_SIZE, _docChangeCallbacks, _activeDocName, _monitorStarted, CommandQueue, commandQueue, CadConnection, cad, cad_default;
|
|
369
391
|
var init_cad = __esm({
|
|
370
392
|
"src/cad.js"() {
|
|
371
393
|
init_constants();
|
|
@@ -386,6 +408,9 @@ var init_cad = __esm({
|
|
|
386
408
|
restartTimer = null;
|
|
387
409
|
PRIORITY_NORMAL = 1;
|
|
388
410
|
MAX_QUEUE_SIZE = 500;
|
|
411
|
+
_docChangeCallbacks = [];
|
|
412
|
+
_activeDocName = null;
|
|
413
|
+
_monitorStarted = false;
|
|
389
414
|
CommandQueue = class {
|
|
390
415
|
#queues = [[], [], []];
|
|
391
416
|
#processing = false;
|
|
@@ -418,16 +443,13 @@ var init_cad = __esm({
|
|
|
418
443
|
return null;
|
|
419
444
|
}
|
|
420
445
|
async _process() {
|
|
421
|
-
if (this.#processing)
|
|
422
|
-
return;
|
|
446
|
+
if (this.#processing) return;
|
|
423
447
|
this.#processing = true;
|
|
424
448
|
while (this._hasPending()) {
|
|
425
449
|
const cmd = this._dequeue();
|
|
426
|
-
if (!cmd)
|
|
427
|
-
continue;
|
|
450
|
+
if (!cmd) continue;
|
|
428
451
|
const dedupKey = this._dedupKey(cmd);
|
|
429
|
-
if (dedupKey)
|
|
430
|
-
this.#dedupMap.delete(dedupKey);
|
|
452
|
+
if (dedupKey) this.#dedupMap.delete(dedupKey);
|
|
431
453
|
try {
|
|
432
454
|
const result = await sendMessage(cmd);
|
|
433
455
|
cmd.resolve(result);
|
|
@@ -442,8 +464,7 @@ var init_cad = __esm({
|
|
|
442
464
|
}
|
|
443
465
|
_dequeue() {
|
|
444
466
|
for (const q of this.#queues) {
|
|
445
|
-
if (q.length > 0)
|
|
446
|
-
return q.shift();
|
|
467
|
+
if (q.length > 0) return q.shift();
|
|
447
468
|
}
|
|
448
469
|
return null;
|
|
449
470
|
}
|
|
@@ -471,8 +492,7 @@ var init_cad = __esm({
|
|
|
471
492
|
return process.platform === "win32";
|
|
472
493
|
}
|
|
473
494
|
async connect(platform = null) {
|
|
474
|
-
if (!this.isAvailable())
|
|
475
|
-
return false;
|
|
495
|
+
if (!this.isAvailable()) return false;
|
|
476
496
|
try {
|
|
477
497
|
const msg = platform ? { type: "connect", platform } : { type: "connect" };
|
|
478
498
|
const result = await sendMessage(msg);
|
|
@@ -481,6 +501,13 @@ var init_cad = __esm({
|
|
|
481
501
|
this.product = result.platform;
|
|
482
502
|
_platform = result.platform;
|
|
483
503
|
this.connected = true;
|
|
504
|
+
_activeDocName = null;
|
|
505
|
+
if (!_monitorStarted) {
|
|
506
|
+
_monitorStarted = true;
|
|
507
|
+
sendMessage({ type: "startMonitor", platform: _platform }).catch(() => {
|
|
508
|
+
_monitorStarted = false;
|
|
509
|
+
});
|
|
510
|
+
}
|
|
484
511
|
return true;
|
|
485
512
|
}
|
|
486
513
|
} catch (e) {
|
|
@@ -489,8 +516,7 @@ var init_cad = __esm({
|
|
|
489
516
|
return false;
|
|
490
517
|
}
|
|
491
518
|
async sendCommand(code) {
|
|
492
|
-
if (!this.connected)
|
|
493
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
519
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
494
520
|
return new Promise((resolve, reject) => {
|
|
495
521
|
commandQueue.enqueue({
|
|
496
522
|
type: "send",
|
|
@@ -500,14 +526,12 @@ var init_cad = __esm({
|
|
|
500
526
|
reject
|
|
501
527
|
}, PRIORITY_NORMAL);
|
|
502
528
|
}).then((result) => {
|
|
503
|
-
if (result.success)
|
|
504
|
-
return true;
|
|
529
|
+
if (result.success) return true;
|
|
505
530
|
throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
|
|
506
531
|
});
|
|
507
532
|
}
|
|
508
533
|
async sendCommandWithResult(code, encoding = null) {
|
|
509
|
-
if (!this.connected)
|
|
510
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
534
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
511
535
|
return new Promise((resolve, reject) => {
|
|
512
536
|
commandQueue.enqueue({
|
|
513
537
|
type: "sendResult",
|
|
@@ -518,8 +542,7 @@ var init_cad = __esm({
|
|
|
518
542
|
reject
|
|
519
543
|
}, PRIORITY_NORMAL);
|
|
520
544
|
}).then((result) => {
|
|
521
|
-
if (result.success)
|
|
522
|
-
return result.result || "";
|
|
545
|
+
if (result.success) return result.result || "";
|
|
523
546
|
throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
|
|
524
547
|
});
|
|
525
548
|
}
|
|
@@ -530,8 +553,7 @@ var init_cad = __esm({
|
|
|
530
553
|
return this.product;
|
|
531
554
|
}
|
|
532
555
|
async isBusy() {
|
|
533
|
-
if (!this.connected)
|
|
534
|
-
return false;
|
|
556
|
+
if (!this.connected) return false;
|
|
535
557
|
try {
|
|
536
558
|
const result = await sendMessage({ type: "isBusy", platform: _platform });
|
|
537
559
|
return result && result.isBusy;
|
|
@@ -540,8 +562,7 @@ var init_cad = __esm({
|
|
|
540
562
|
}
|
|
541
563
|
}
|
|
542
564
|
async hasDoc() {
|
|
543
|
-
if (!this.connected)
|
|
544
|
-
return { hasDoc: false, docCount: 0 };
|
|
565
|
+
if (!this.connected) return { hasDoc: false, docCount: 0 };
|
|
545
566
|
try {
|
|
546
567
|
const result = await sendMessage({ type: "hasdoc", platform: _platform });
|
|
547
568
|
return result || { hasDoc: false, docCount: 0 };
|
|
@@ -550,8 +571,7 @@ var init_cad = __esm({
|
|
|
550
571
|
}
|
|
551
572
|
}
|
|
552
573
|
async newDoc() {
|
|
553
|
-
if (!this.connected)
|
|
554
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
574
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
555
575
|
try {
|
|
556
576
|
const result = await sendMessage({ type: "newdoc", platform: _platform });
|
|
557
577
|
return result && result.success;
|
|
@@ -560,8 +580,7 @@ var init_cad = __esm({
|
|
|
560
580
|
}
|
|
561
581
|
}
|
|
562
582
|
async bringToFront() {
|
|
563
|
-
if (!this.connected)
|
|
564
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
583
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
565
584
|
try {
|
|
566
585
|
const result = await sendMessage({ type: "bringToFront", platform: _platform });
|
|
567
586
|
return result && result.success;
|
|
@@ -569,9 +588,17 @@ var init_cad = __esm({
|
|
|
569
588
|
return false;
|
|
570
589
|
}
|
|
571
590
|
}
|
|
591
|
+
async getActiveDocInfo() {
|
|
592
|
+
if (!this.connected) return { docName: "", docPath: "", docCount: 0 };
|
|
593
|
+
try {
|
|
594
|
+
const result = await sendMessage({ type: "getActiveDocInfo", platform: _platform });
|
|
595
|
+
return result || { docName: "", docPath: "", docCount: 0 };
|
|
596
|
+
} catch (e) {
|
|
597
|
+
return { docName: "", docPath: "", docCount: 0 };
|
|
598
|
+
}
|
|
599
|
+
}
|
|
572
600
|
async getInfo() {
|
|
573
|
-
if (!this.connected)
|
|
574
|
-
return "CAD \u672A\u8FDE\u63A5";
|
|
601
|
+
if (!this.connected) return "CAD \u672A\u8FDE\u63A5";
|
|
575
602
|
return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
|
|
576
603
|
}
|
|
577
604
|
async disconnect() {
|
|
@@ -579,6 +606,8 @@ var init_cad = __esm({
|
|
|
579
606
|
this.version = null;
|
|
580
607
|
this.product = null;
|
|
581
608
|
_platform = null;
|
|
609
|
+
_activeDocName = null;
|
|
610
|
+
_monitorStarted = false;
|
|
582
611
|
commandQueue.clear();
|
|
583
612
|
resetWorker();
|
|
584
613
|
}
|
|
@@ -595,6 +624,8 @@ var init_cad = __esm({
|
|
|
595
624
|
this.version = null;
|
|
596
625
|
this.product = null;
|
|
597
626
|
_platform = null;
|
|
627
|
+
_activeDocName = null;
|
|
628
|
+
_monitorStarted = false;
|
|
598
629
|
commandQueue.clear();
|
|
599
630
|
resetWorker();
|
|
600
631
|
}
|
|
@@ -612,16 +643,14 @@ __export(renderer_exports, {
|
|
|
612
643
|
renderTemplate: () => renderTemplate
|
|
613
644
|
});
|
|
614
645
|
function escapeLispString2(str) {
|
|
615
|
-
if (typeof str !== "string")
|
|
616
|
-
return "";
|
|
646
|
+
if (typeof str !== "string") return "";
|
|
617
647
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
618
648
|
}
|
|
619
649
|
function resolvePath(obj, path12) {
|
|
620
650
|
const parts = path12.split(/[.\[\]]/g).filter(Boolean);
|
|
621
651
|
let val = obj;
|
|
622
652
|
for (const p of parts) {
|
|
623
|
-
if (val == null)
|
|
624
|
-
return void 0;
|
|
653
|
+
if (val == null) return void 0;
|
|
625
654
|
val = val[p];
|
|
626
655
|
}
|
|
627
656
|
return val;
|
|
@@ -630,11 +659,9 @@ function renderTemplate(template, args) {
|
|
|
630
659
|
return template.replace(PARAM_RE, (match, rawExpr, expr) => {
|
|
631
660
|
const path12 = rawExpr || expr;
|
|
632
661
|
const val = resolvePath(args, path12);
|
|
633
|
-
if (val == null)
|
|
634
|
-
return "";
|
|
662
|
+
if (val == null) return "";
|
|
635
663
|
const strVal = String(val);
|
|
636
|
-
if (rawExpr)
|
|
637
|
-
return strVal;
|
|
664
|
+
if (rawExpr) return strVal;
|
|
638
665
|
return escapeLispString2(strVal);
|
|
639
666
|
});
|
|
640
667
|
}
|
|
@@ -693,9 +720,8 @@ import express2 from "express";
|
|
|
693
720
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
694
721
|
|
|
695
722
|
// src/logger.js
|
|
696
|
-
init_config();
|
|
697
723
|
import fs2 from "fs";
|
|
698
|
-
|
|
724
|
+
init_config();
|
|
699
725
|
import path3 from "path";
|
|
700
726
|
import os2 from "os";
|
|
701
727
|
var DEBUG_FILE = config_default.debugFile || path3.join(os2.tmpdir(), "mcp-server-debug.log");
|
|
@@ -704,11 +730,9 @@ var MAX_LOG_FILES = 5;
|
|
|
704
730
|
var stream = null;
|
|
705
731
|
function rotateLog() {
|
|
706
732
|
try {
|
|
707
|
-
if (!fs2.existsSync(DEBUG_FILE))
|
|
708
|
-
return;
|
|
733
|
+
if (!fs2.existsSync(DEBUG_FILE)) return;
|
|
709
734
|
const stat = fs2.statSync(DEBUG_FILE);
|
|
710
|
-
if (stat.size < MAX_LOG_SIZE)
|
|
711
|
-
return;
|
|
735
|
+
if (stat.size < MAX_LOG_SIZE) return;
|
|
712
736
|
if (stream) {
|
|
713
737
|
stream.end();
|
|
714
738
|
stream = null;
|
|
@@ -782,11 +806,9 @@ function ensureRequestLogDir() {
|
|
|
782
806
|
}
|
|
783
807
|
function rotateRequestLog() {
|
|
784
808
|
try {
|
|
785
|
-
if (!fs2.existsSync(REQUEST_LOG_FILE))
|
|
786
|
-
return;
|
|
809
|
+
if (!fs2.existsSync(REQUEST_LOG_FILE)) return;
|
|
787
810
|
const stat = fs2.statSync(REQUEST_LOG_FILE);
|
|
788
|
-
if (stat.size < 10 * 1024 * 1024)
|
|
789
|
-
return;
|
|
811
|
+
if (stat.size < 10 * 1024 * 1024) return;
|
|
790
812
|
if (requestStream) {
|
|
791
813
|
requestStream.end();
|
|
792
814
|
requestStream = null;
|
|
@@ -811,8 +833,7 @@ function rotateRequestLog() {
|
|
|
811
833
|
}
|
|
812
834
|
}
|
|
813
835
|
function logRequest(req) {
|
|
814
|
-
if (!config_default.requestLogEnabled)
|
|
815
|
-
return;
|
|
836
|
+
if (!config_default.requestLogEnabled) return;
|
|
816
837
|
try {
|
|
817
838
|
ensureRequestLogDir();
|
|
818
839
|
rotateRequestLog();
|
|
@@ -833,8 +854,7 @@ function logRequest(req) {
|
|
|
833
854
|
}
|
|
834
855
|
}
|
|
835
856
|
function logResponse(req, res, duration) {
|
|
836
|
-
if (!config_default.requestLogEnabled)
|
|
837
|
-
return;
|
|
857
|
+
if (!config_default.requestLogEnabled) return;
|
|
838
858
|
try {
|
|
839
859
|
ensureRequestLogDir();
|
|
840
860
|
if (!requestStream) {
|
|
@@ -890,36 +910,27 @@ var TBL_QUERIES = {
|
|
|
890
910
|
(setq @d nil)
|
|
891
911
|
(vlax-for e (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
|
|
892
912
|
(if (not (and (vlax-property-available-p e 'isfoundation) (vlax-get e 'isfoundation)))
|
|
893
|
-
(setq @d (cons (
|
|
913
|
+
(setq @d (cons (@:get-props e '("Name" "Count" "Handle" "ObjectName" "IsXRef" "IsXRefOverlay" "IsDynamicBlock" "HasAttributes" "HasExtensionDictionary" "Path" "Description" "Layout" "BlockScope")) @d))))
|
|
894
914
|
(list (cons 'table 'block) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
|
|
895
915
|
style: { name: "style", lisp: `(progn
|
|
896
916
|
(setq @d nil)
|
|
897
917
|
(vlax-for e (vla-get-textstyles (vla-get-activedocument (vlax-get-acad-object)))
|
|
898
|
-
(setq @d (cons (
|
|
899
|
-
(cons 2 (vla-get-name e))
|
|
900
|
-
(cons 1 (vla-get-fontfile e))
|
|
901
|
-
(cons 3 (vla-get-bigfontfile e))
|
|
902
|
-
(cons 40 (vla-get-height e))
|
|
903
|
-
(cons 41 (vla-get-width e))
|
|
904
|
-
(cons 42 (/ (* 180.0 (vla-get-obliqueangle e)) pi))
|
|
905
|
-
(cons 70 (vla-get-textgenerationflag e))
|
|
906
|
-
) @d)))
|
|
918
|
+
(setq @d (cons (@:get-props e '("Name" "FontFile" "BigFontFile" "Height" "Width" "ObliqueAngle" "TextGenerationFlag" "Handle" "ObjectName")) @d)))
|
|
907
919
|
(list (cons 'table 'style) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
|
|
908
920
|
dimstyle: { name: "dimstyle", lisp: `(progn
|
|
909
921
|
(setq @d nil)
|
|
910
922
|
(vlax-for e (vla-get-dimstyles (vla-get-activedocument (vlax-get-acad-object)))
|
|
911
|
-
(setq @d (cons (
|
|
923
|
+
(setq @d (cons (@:get-props e '("Name" "Handle" "ObjectName")) @d)))
|
|
912
924
|
(list (cons 'table 'dimstyle) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
|
|
913
925
|
ltype: { name: "linetype", lisp: `(progn
|
|
914
926
|
(setq @d nil)
|
|
915
927
|
(vlax-for e (vla-get-linetypes (vla-get-activedocument (vlax-get-acad-object)))
|
|
916
|
-
(setq @d (cons (
|
|
928
|
+
(setq @d (cons (@:get-props e '("Name" "Description" "PatternLength" "Handle" "ObjectName")) @d)))
|
|
917
929
|
(list (cons 'table 'linetype) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` }
|
|
918
930
|
};
|
|
919
931
|
var TBL_KEY_ALIAS = {
|
|
920
932
|
textstyle: "style",
|
|
921
933
|
textstyles: "style",
|
|
922
|
-
ltype: "linetype",
|
|
923
934
|
linetype: "ltype"
|
|
924
935
|
};
|
|
925
936
|
|
|
@@ -1022,27 +1033,21 @@ async function ensureCadConnected() {
|
|
|
1022
1033
|
}
|
|
1023
1034
|
}
|
|
1024
1035
|
function escapeLispString(str) {
|
|
1025
|
-
if (typeof str !== "string")
|
|
1026
|
-
return "";
|
|
1036
|
+
if (typeof str !== "string") return "";
|
|
1027
1037
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
1028
1038
|
}
|
|
1029
1039
|
function tryNumber(val) {
|
|
1030
|
-
if (typeof val === "number")
|
|
1031
|
-
return val;
|
|
1040
|
+
if (typeof val === "number") return val;
|
|
1032
1041
|
const n = Number(val);
|
|
1033
|
-
if (!isNaN(n) && val !== "")
|
|
1034
|
-
return n;
|
|
1042
|
+
if (!isNaN(n) && val !== "") return n;
|
|
1035
1043
|
return val;
|
|
1036
1044
|
}
|
|
1037
1045
|
function parseLispList(str) {
|
|
1038
|
-
if (!str || typeof str !== "string")
|
|
1039
|
-
return null;
|
|
1046
|
+
if (!str || typeof str !== "string") return null;
|
|
1040
1047
|
const trimmed = str.trim();
|
|
1041
|
-
if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
|
|
1042
|
-
return null;
|
|
1048
|
+
if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) return null;
|
|
1043
1049
|
const content = trimmed.slice(1, -1).trim();
|
|
1044
|
-
if (!content)
|
|
1045
|
-
return [];
|
|
1050
|
+
if (!content) return [];
|
|
1046
1051
|
const result = [];
|
|
1047
1052
|
let depth = 0;
|
|
1048
1053
|
let current = "";
|
|
@@ -1084,39 +1089,29 @@ function parseLispList(str) {
|
|
|
1084
1089
|
}
|
|
1085
1090
|
current += ch;
|
|
1086
1091
|
}
|
|
1087
|
-
if (current.trim())
|
|
1088
|
-
result.push(current.trim());
|
|
1092
|
+
if (current.trim()) result.push(current.trim());
|
|
1089
1093
|
return result.map((item) => {
|
|
1090
1094
|
const t = item.trim();
|
|
1091
|
-
if (t === "nil" || t === "NIL")
|
|
1092
|
-
|
|
1093
|
-
if (t
|
|
1094
|
-
return true;
|
|
1095
|
-
if (t.startsWith('"') && t.endsWith('"'))
|
|
1096
|
-
return t.slice(1, -1);
|
|
1095
|
+
if (t === "nil" || t === "NIL") return null;
|
|
1096
|
+
if (t === "t" || t === "T") return true;
|
|
1097
|
+
if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
|
|
1097
1098
|
return tryNumber(t);
|
|
1098
1099
|
});
|
|
1099
1100
|
}
|
|
1100
1101
|
function parseLispRecursive(str) {
|
|
1101
|
-
if (!str || typeof str !== "string")
|
|
1102
|
-
return null;
|
|
1102
|
+
if (!str || typeof str !== "string") return null;
|
|
1103
1103
|
str = str.trim();
|
|
1104
|
-
if (!str)
|
|
1105
|
-
return null;
|
|
1104
|
+
if (!str) return null;
|
|
1106
1105
|
let pos = 0;
|
|
1107
1106
|
function skipWs() {
|
|
1108
|
-
while (pos < str.length && /\s/.test(str[pos]))
|
|
1109
|
-
pos++;
|
|
1107
|
+
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
|
1110
1108
|
}
|
|
1111
1109
|
function parseValue() {
|
|
1112
1110
|
skipWs();
|
|
1113
|
-
if (pos >= str.length)
|
|
1114
|
-
return null;
|
|
1111
|
+
if (pos >= str.length) return null;
|
|
1115
1112
|
const ch = str[pos];
|
|
1116
|
-
if (ch === "(")
|
|
1117
|
-
|
|
1118
|
-
if (ch === '"')
|
|
1119
|
-
return parseString();
|
|
1113
|
+
if (ch === "(") return parseList();
|
|
1114
|
+
if (ch === '"') return parseString();
|
|
1120
1115
|
if (ch === "'") {
|
|
1121
1116
|
pos++;
|
|
1122
1117
|
return parseValue();
|
|
@@ -1129,16 +1124,11 @@ function parseLispRecursive(str) {
|
|
|
1129
1124
|
while (pos < str.length && str[pos] !== '"') {
|
|
1130
1125
|
if (str[pos] === "\\" && pos + 1 < str.length) {
|
|
1131
1126
|
pos++;
|
|
1132
|
-
if (str[pos] === '"')
|
|
1133
|
-
|
|
1134
|
-
else if (str[pos] === "
|
|
1135
|
-
|
|
1136
|
-
else
|
|
1137
|
-
r += " ";
|
|
1138
|
-
else if (str[pos] === "\\")
|
|
1139
|
-
r += "\\";
|
|
1140
|
-
else
|
|
1141
|
-
r += str[pos];
|
|
1127
|
+
if (str[pos] === '"') r += '"';
|
|
1128
|
+
else if (str[pos] === "n") r += "\n";
|
|
1129
|
+
else if (str[pos] === "t") r += " ";
|
|
1130
|
+
else if (str[pos] === "\\") r += "\\";
|
|
1131
|
+
else r += str[pos];
|
|
1142
1132
|
} else {
|
|
1143
1133
|
r += str[pos];
|
|
1144
1134
|
}
|
|
@@ -1149,13 +1139,10 @@ function parseLispRecursive(str) {
|
|
|
1149
1139
|
}
|
|
1150
1140
|
function parseAtom() {
|
|
1151
1141
|
const start = pos;
|
|
1152
|
-
while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
|
|
1153
|
-
pos++;
|
|
1142
|
+
while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(") pos++;
|
|
1154
1143
|
const atom = str.slice(start, pos);
|
|
1155
|
-
if (atom === "nil" || atom === "NIL")
|
|
1156
|
-
|
|
1157
|
-
if (atom === "t" || atom === "T")
|
|
1158
|
-
return true;
|
|
1144
|
+
if (atom === "nil" || atom === "NIL") return null;
|
|
1145
|
+
if (atom === "t" || atom === "T") return true;
|
|
1159
1146
|
return tryNumber(atom);
|
|
1160
1147
|
}
|
|
1161
1148
|
function parseList() {
|
|
@@ -1163,15 +1150,13 @@ function parseLispRecursive(str) {
|
|
|
1163
1150
|
const items = [];
|
|
1164
1151
|
while (pos < str.length) {
|
|
1165
1152
|
skipWs();
|
|
1166
|
-
if (pos >= str.length)
|
|
1167
|
-
break;
|
|
1153
|
+
if (pos >= str.length) break;
|
|
1168
1154
|
if (str[pos] === ")") {
|
|
1169
1155
|
pos++;
|
|
1170
1156
|
return items;
|
|
1171
1157
|
}
|
|
1172
1158
|
const left = parseValue();
|
|
1173
|
-
if (left === void 0)
|
|
1174
|
-
break;
|
|
1159
|
+
if (left === void 0) break;
|
|
1175
1160
|
skipWs();
|
|
1176
1161
|
if (str[pos] === "." && (pos + 1 >= str.length || /\s/.test(str[pos + 1]) || str[pos + 1] === ")")) {
|
|
1177
1162
|
pos++;
|
|
@@ -1193,19 +1178,6 @@ function parseLispRecursive(str) {
|
|
|
1193
1178
|
}
|
|
1194
1179
|
return parseValue();
|
|
1195
1180
|
}
|
|
1196
|
-
function lispPairsToObject(pairs) {
|
|
1197
|
-
if (!Array.isArray(pairs))
|
|
1198
|
-
return pairs;
|
|
1199
|
-
const obj = {};
|
|
1200
|
-
for (let i = 0; i < pairs.length - 1; i += 2) {
|
|
1201
|
-
const key = pairs[i];
|
|
1202
|
-
const val = pairs[i + 1];
|
|
1203
|
-
if (typeof key === "string" || typeof key === "number") {
|
|
1204
|
-
obj[String(key)] = Array.isArray(val) ? lispPairsToObject(val) : val;
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
return obj;
|
|
1208
|
-
}
|
|
1209
1181
|
|
|
1210
1182
|
// src/handlers/resource-readers.js
|
|
1211
1183
|
var ENTITY_PROPERTIES_LISP = `
|
|
@@ -1261,8 +1233,7 @@ var ENTITY_PROPERTIES_LISP = `
|
|
|
1261
1233
|
result)
|
|
1262
1234
|
`;
|
|
1263
1235
|
function propertyPairsToObject(pairs) {
|
|
1264
|
-
if (!Array.isArray(pairs))
|
|
1265
|
-
return null;
|
|
1236
|
+
if (!Array.isArray(pairs)) return null;
|
|
1266
1237
|
const obj = {};
|
|
1267
1238
|
for (const pair of pairs) {
|
|
1268
1239
|
if (Array.isArray(pair) && pair.length >= 2) {
|
|
@@ -1273,10 +1244,8 @@ function propertyPairsToObject(pairs) {
|
|
|
1273
1244
|
}
|
|
1274
1245
|
function buildEntityPropertiesCode({ type, layer, bbox }) {
|
|
1275
1246
|
const items = [];
|
|
1276
|
-
if (type)
|
|
1277
|
-
|
|
1278
|
-
if (layer)
|
|
1279
|
-
items.push(`(cons 8 "${escapeLispString(layer)}")`);
|
|
1247
|
+
if (type) items.push(`(cons 0 "${escapeLispString(type)}")`);
|
|
1248
|
+
if (layer) items.push(`(cons 8 "${escapeLispString(layer)}")`);
|
|
1280
1249
|
if (bbox) {
|
|
1281
1250
|
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
1282
1251
|
if (parts.length === 4) {
|
|
@@ -1302,10 +1271,8 @@ ${ENTITY_PROPERTIES_LISP}
|
|
|
1302
1271
|
(vl-prin1-to-string (list @e:total (reverse @e:ents))))`;
|
|
1303
1272
|
}
|
|
1304
1273
|
async function getEntityByHandle(handle) {
|
|
1305
|
-
if (!cad.connected)
|
|
1306
|
-
|
|
1307
|
-
if (!cad.connected)
|
|
1308
|
-
return { error: "CAD \u672A\u8FDE\u63A5" };
|
|
1274
|
+
if (!cad.connected) await cad.connect();
|
|
1275
|
+
if (!cad.connected) return { error: "CAD \u672A\u8FDE\u63A5" };
|
|
1309
1276
|
const code = `(progn
|
|
1310
1277
|
(vl-load-com)
|
|
1311
1278
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -1325,8 +1292,7 @@ async function getEntityByHandle(handle) {
|
|
|
1325
1292
|
)`;
|
|
1326
1293
|
try {
|
|
1327
1294
|
const result = await cad.sendCommandWithResult(code);
|
|
1328
|
-
if (!result || result === "nil")
|
|
1329
|
-
return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
|
|
1295
|
+
if (!result || result === "nil") return { error: `\u672A\u627E\u5230\u5B9E\u4F53: ${handle}` };
|
|
1330
1296
|
try {
|
|
1331
1297
|
return JSON.parse(result);
|
|
1332
1298
|
} catch {
|
|
@@ -1338,8 +1304,7 @@ async function getEntityByHandle(handle) {
|
|
|
1338
1304
|
}
|
|
1339
1305
|
async function getCadInfo() {
|
|
1340
1306
|
const cached = getCached("cad:info");
|
|
1341
|
-
if (cached)
|
|
1342
|
-
return cached;
|
|
1307
|
+
if (cached) return cached;
|
|
1343
1308
|
if (!cad.connected) {
|
|
1344
1309
|
await cad.connect();
|
|
1345
1310
|
}
|
|
@@ -1364,10 +1329,8 @@ async function getCadInfo() {
|
|
|
1364
1329
|
async function getEntities(params = {}) {
|
|
1365
1330
|
const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
|
|
1366
1331
|
const cached = getCached(cacheKey);
|
|
1367
|
-
if (cached)
|
|
1368
|
-
|
|
1369
|
-
if (!cad.connected)
|
|
1370
|
-
await cad.connect();
|
|
1332
|
+
if (cached) return cached;
|
|
1333
|
+
if (!cad.connected) await cad.connect();
|
|
1371
1334
|
if (!cad.connected) {
|
|
1372
1335
|
return { total: 0, entities: [] };
|
|
1373
1336
|
}
|
|
@@ -1455,9 +1418,14 @@ async function getEntitiesSummary(cacheKey) {
|
|
|
1455
1418
|
}
|
|
1456
1419
|
}
|
|
1457
1420
|
function buildTextContentCode({ layer, bbox, offset, limit }) {
|
|
1458
|
-
const items = [
|
|
1459
|
-
|
|
1460
|
-
|
|
1421
|
+
const items = [
|
|
1422
|
+
`'(-4 . "<OR")`,
|
|
1423
|
+
`'(0 . "TEXT")`,
|
|
1424
|
+
`'(0 . "MTEXT")`,
|
|
1425
|
+
`'(0 . "ATTRIB")`,
|
|
1426
|
+
`'(-4 . "OR>")`
|
|
1427
|
+
];
|
|
1428
|
+
if (layer) items.push(`(cons 8 "${escapeLispString(layer)}")`);
|
|
1461
1429
|
if (bbox) {
|
|
1462
1430
|
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
1463
1431
|
if (parts.length === 4) {
|
|
@@ -1472,6 +1440,7 @@ function buildTextContentCode({ layer, bbox, offset, limit }) {
|
|
|
1472
1440
|
}
|
|
1473
1441
|
const filterExpr = `(list ${items.join(" ")})`;
|
|
1474
1442
|
return `(progn
|
|
1443
|
+
(vl-load-com)
|
|
1475
1444
|
(setq ss (ssget "_X" ${filterExpr}))
|
|
1476
1445
|
(if (null ss)
|
|
1477
1446
|
(list "total" 0 "offset" ${offset} "limit" ${limit} "texts" nil)
|
|
@@ -1481,15 +1450,13 @@ function buildTextContentCode({ layer, bbox, offset, limit }) {
|
|
|
1481
1450
|
(setq ent (ssname ss i) ed (entget ent) ins (cdr (assoc 10 ed)))
|
|
1482
1451
|
(setq texts (append texts (list (list "text" (vl-prin1-to-string (cdr (assoc 1 ed))) "position" (list (car ins) (cadr ins) (caddr ins))))) i (1+ i)))
|
|
1483
1452
|
(list "total" total "offset" ${offset} "limit" ${limit} "texts" texts))))
|
|
1484
|
-
|
|
1453
|
+
`;
|
|
1485
1454
|
}
|
|
1486
1455
|
async function getTextContent(params = {}) {
|
|
1487
1456
|
const cacheKey = `dwg:text-content:${JSON.stringify(params)}`;
|
|
1488
1457
|
const cached = getCached(cacheKey);
|
|
1489
|
-
if (cached)
|
|
1490
|
-
|
|
1491
|
-
if (!cad.connected)
|
|
1492
|
-
await cad.connect();
|
|
1458
|
+
if (cached) return cached;
|
|
1459
|
+
if (!cad.connected) await cad.connect();
|
|
1493
1460
|
if (!cad.connected) {
|
|
1494
1461
|
return { total: 0, offset: 0, limit: 5e3, texts: [] };
|
|
1495
1462
|
}
|
|
@@ -1498,42 +1465,47 @@ async function getTextContent(params = {}) {
|
|
|
1498
1465
|
try {
|
|
1499
1466
|
const code = buildTextContentCode({ layer: params.layer, bbox: params.bbox, offset, limit });
|
|
1500
1467
|
const resultStr = await cad.sendCommandWithResult(code);
|
|
1501
|
-
|
|
1502
|
-
return { total: 0, offset, limit, texts: [] };
|
|
1503
|
-
}
|
|
1468
|
+
log(`[DEBUG text-content] resultStr length=${resultStr?.length} first300=${resultStr?.substring(0, 300)}`);
|
|
1504
1469
|
const parsed = parseLispRecursive(resultStr);
|
|
1505
1470
|
if (!parsed || !Array.isArray(parsed)) {
|
|
1506
|
-
|
|
1471
|
+
throw new Error(`text-content: \u89E3\u6790 Lisp \u7ED3\u679C\u5931\u8D25: raw="${String(resultStr).substring(0, 500)}"`);
|
|
1472
|
+
}
|
|
1473
|
+
const data = {};
|
|
1474
|
+
let rawTexts = [];
|
|
1475
|
+
for (let i = 0; i < parsed.length - 1; i += 2) {
|
|
1476
|
+
const key = parsed[i];
|
|
1477
|
+
const val = parsed[i + 1];
|
|
1478
|
+
if (typeof key === "string" || typeof key === "number") {
|
|
1479
|
+
if (key === "texts" && Array.isArray(val)) {
|
|
1480
|
+
rawTexts = val;
|
|
1481
|
+
} else {
|
|
1482
|
+
data[String(key)] = val;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1507
1485
|
}
|
|
1508
|
-
const data = lispPairsToObject(parsed);
|
|
1509
|
-
const rawTexts = Array.isArray(data.texts) ? data.texts : [];
|
|
1510
1486
|
data.texts = rawTexts.map((item) => {
|
|
1511
|
-
if (!Array.isArray(item))
|
|
1512
|
-
return null;
|
|
1487
|
+
if (!Array.isArray(item)) return null;
|
|
1513
1488
|
const obj = {};
|
|
1514
|
-
item.
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
}
|
|
1489
|
+
for (let i = 0; i < item.length - 1; i += 2) {
|
|
1490
|
+
const key = item[i];
|
|
1491
|
+
const val = item[i + 1];
|
|
1492
|
+
if (key === "text") obj.text = String(val || "");
|
|
1493
|
+
else if (key === "position") {
|
|
1494
|
+
obj.position = Array.isArray(val) ? val.map((v) => typeof v === "number" ? v : 0) : [];
|
|
1521
1495
|
}
|
|
1522
|
-
}
|
|
1496
|
+
}
|
|
1523
1497
|
return obj.text ? obj : null;
|
|
1524
1498
|
}).filter(Boolean);
|
|
1525
1499
|
setCache(cacheKey, data);
|
|
1526
1500
|
return data;
|
|
1527
1501
|
} catch (e) {
|
|
1528
1502
|
log(`getTextContent error: ${e.message}`);
|
|
1529
|
-
|
|
1503
|
+
throw e;
|
|
1530
1504
|
}
|
|
1531
1505
|
}
|
|
1532
1506
|
async function getDwgName() {
|
|
1533
|
-
if (!cad.connected)
|
|
1534
|
-
|
|
1535
|
-
if (!cad.connected)
|
|
1536
|
-
return { name: null };
|
|
1507
|
+
if (!cad.connected) await cad.connect();
|
|
1508
|
+
if (!cad.connected) return { name: null };
|
|
1537
1509
|
try {
|
|
1538
1510
|
const code = `(vl-princ-to-string (getvar "dwgname"))`;
|
|
1539
1511
|
const name = await cad.sendCommandWithResult(code);
|
|
@@ -1543,10 +1515,8 @@ async function getDwgName() {
|
|
|
1543
1515
|
}
|
|
1544
1516
|
}
|
|
1545
1517
|
async function getDwgPath() {
|
|
1546
|
-
if (!cad.connected)
|
|
1547
|
-
|
|
1548
|
-
if (!cad.connected)
|
|
1549
|
-
return { path: null, name: null };
|
|
1518
|
+
if (!cad.connected) await cad.connect();
|
|
1519
|
+
if (!cad.connected) return { path: null, name: null };
|
|
1550
1520
|
try {
|
|
1551
1521
|
const code = `(progn
|
|
1552
1522
|
(setq prefix (vl-princ-to-string (getvar "dwgprefix")))
|
|
@@ -1565,8 +1535,7 @@ async function getDwgPath() {
|
|
|
1565
1535
|
}
|
|
1566
1536
|
if (!parsed) {
|
|
1567
1537
|
const listResult = parseLispList(result);
|
|
1568
|
-
if (listResult && listResult.length >= 2)
|
|
1569
|
-
parsed = listResult;
|
|
1538
|
+
if (listResult && listResult.length >= 2) parsed = listResult;
|
|
1570
1539
|
}
|
|
1571
1540
|
if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
|
|
1572
1541
|
return { path: String(parsed[0]), name: String(parsed[1]) };
|
|
@@ -1577,100 +1546,92 @@ async function getDwgPath() {
|
|
|
1577
1546
|
}
|
|
1578
1547
|
}
|
|
1579
1548
|
function buildBlockRefsCode(filterBlockName) {
|
|
1580
|
-
const
|
|
1549
|
+
const filterItems = ['(cons 0 "INSERT")'];
|
|
1550
|
+
if (filterBlockName) {
|
|
1551
|
+
filterItems.push(`(cons 2 "${escapeLispString(filterBlockName)}")`);
|
|
1552
|
+
}
|
|
1553
|
+
const filterCode = `(list ${filterItems.join(" ")})`;
|
|
1581
1554
|
return `(progn
|
|
1582
1555
|
(vl-load-com)
|
|
1583
|
-
(defun @br:attr (ent / atts)
|
|
1584
|
-
(if (= (type ent) 'VLA-OBJECT)
|
|
1585
|
-
(progn
|
|
1586
|
-
(setq atts (vlax-variant-value (vla-getattributes ent)))
|
|
1587
|
-
(if (safearray-value atts)
|
|
1588
|
-
(mapcar '(lambda (x) (cons (vla-get-tagstring x) (vla-get-textstring x)))
|
|
1589
|
-
(vlax-safearray->list atts))
|
|
1590
|
-
nil))
|
|
1591
|
-
(if (setq att (entnext ent))
|
|
1592
|
-
(progn
|
|
1593
|
-
(setq atts nil)
|
|
1594
|
-
(while (= (cdr (assoc 0 (entget att))) "ATTRIB")
|
|
1595
|
-
(setq atts (cons (cons (cdr (assoc 2 (entget att))) (cdr (assoc 1 (entget att)))) atts))
|
|
1596
|
-
att (entnext att))
|
|
1597
|
-
(reverse atts))
|
|
1598
|
-
nil))))
|
|
1599
1556
|
|
|
1600
|
-
(defun @br:
|
|
1601
|
-
(if (
|
|
1557
|
+
(defun @br:try (obj prop / r)
|
|
1558
|
+
(if (vl-catch-all-error-p
|
|
1559
|
+
(setq r (vl-catch-all-apply
|
|
1560
|
+
(function (lambda () (vlax-get obj prop))))))
|
|
1561
|
+
nil
|
|
1562
|
+
r))
|
|
1563
|
+
|
|
1564
|
+
(defun @br:get-attrs (ent / att atts)
|
|
1565
|
+
(if (setq att (entnext ent))
|
|
1602
1566
|
(progn
|
|
1603
|
-
(setq
|
|
1604
|
-
(
|
|
1605
|
-
(
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
(cons (vla-get-propertyname x)
|
|
1610
|
-
(list (cons "value" (vla-get-value x))
|
|
1611
|
-
(cons "readOnly" (vla-get-readonly x))
|
|
1612
|
-
(cons "show" (vla-get-show x)))))
|
|
1613
|
-
(vlax-safearray->list props)))
|
|
1614
|
-
nil)
|
|
1615
|
-
nil))
|
|
1616
|
-
(if (and (setq obj (vlax-ename->vla-object ent))
|
|
1617
|
-
(vlax-property-available-p obj 'isdynamicblock)
|
|
1618
|
-
(vla-get-isdynamicblock obj))
|
|
1619
|
-
(progn
|
|
1620
|
-
(setq props (vlax-invoke obj 'getdynamicblockproperties))
|
|
1621
|
-
(mapcar '(lambda (x)
|
|
1622
|
-
(cons (vla-get-propertyname x)
|
|
1623
|
-
(list (cons "value" (vla-get-value x))
|
|
1624
|
-
(cons "readOnly" (vla-get-readonly x))
|
|
1625
|
-
(cons "show" (vla-get-show x)))))
|
|
1626
|
-
(vlax-safearray->list props)))
|
|
1627
|
-
nil)))
|
|
1567
|
+
(setq atts nil)
|
|
1568
|
+
(while (= (cdr (assoc 0 (entget att))) "ATTRIB")
|
|
1569
|
+
(setq atts (cons (cons (cdr (assoc 2 (entget att))) (cdr (assoc 1 (entget att)))) atts))
|
|
1570
|
+
att (entnext att))
|
|
1571
|
+
(reverse atts))
|
|
1572
|
+
nil))
|
|
1628
1573
|
|
|
1629
|
-
(defun @br:
|
|
1630
|
-
(setq
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1574
|
+
(defun @br:get-dynprops (obj / r)
|
|
1575
|
+
(setq r (vl-catch-all-apply
|
|
1576
|
+
(function (lambda ()
|
|
1577
|
+
(mapcar '(lambda (x)
|
|
1578
|
+
(cons (vla-get-propertyname x)
|
|
1579
|
+
(list (cons "value" (vlax-get x 'value))
|
|
1580
|
+
(cons "readOnly" (vlax-get x 'readonly))
|
|
1581
|
+
(cons "show" (vlax-get x 'show)))))
|
|
1582
|
+
(vlax-safearray->list (vlax-invoke obj 'getdynamicblockproperties)))))))
|
|
1583
|
+
(if (vl-catch-all-error-p r) nil r))
|
|
1584
|
+
|
|
1585
|
+
(defun @br:props (ent / obj ed r)
|
|
1586
|
+
(setq r (vl-catch-all-apply
|
|
1587
|
+
(function (lambda ()
|
|
1588
|
+
(setq obj (vlax-ename->vla-object ent)
|
|
1589
|
+
ed (entget ent))
|
|
1590
|
+
(list
|
|
1591
|
+
(cons "handle" (cdr (assoc 5 ed)))
|
|
1592
|
+
(cons "layer" (cdr (assoc 8 ed)))
|
|
1593
|
+
(cons "blockName" (vla-get-name obj))
|
|
1594
|
+
(cons "effectiveBlockName" (@br:try obj 'effectivename))
|
|
1595
|
+
(cons "insertionPoint" (vlax-safearray->list (vla-get-insertionpoint obj)))
|
|
1596
|
+
(cons "rotation" (vla-get-rotation obj))
|
|
1597
|
+
(cons "scale" (list (vla-get-xscale obj) (vla-get-yscale obj) (vla-get-zscale obj)))
|
|
1598
|
+
(cons "isDynamic" (@br:try obj 'isdynamicblock))
|
|
1599
|
+
(cons "attributes" (@br:get-attrs ent))
|
|
1600
|
+
(cons "dynamicProperties" (@br:get-dynprops obj)))))))
|
|
1601
|
+
(if (vl-catch-all-error-p r) nil r))
|
|
1643
1602
|
|
|
1644
|
-
(setq ss (ssget "_X"
|
|
1603
|
+
(setq ss (ssget "_X" ${filterCode}))
|
|
1645
1604
|
(if (null ss)
|
|
1646
1605
|
(list (cons "total" 0) (cons "blockRefs" nil))
|
|
1647
1606
|
(progn
|
|
1648
1607
|
(setq total (sslength ss) i 0 refs nil)
|
|
1649
1608
|
(while (< i total)
|
|
1650
|
-
(setq
|
|
1651
|
-
|
|
1609
|
+
(setq r (@br:props (ssname ss i)))
|
|
1610
|
+
(if r (setq refs (cons r refs)))
|
|
1611
|
+
(setq i (1+ i)))
|
|
1612
|
+
(list (cons "total" total) (cons "blockRefs" (list (reverse refs)))))))`;
|
|
1652
1613
|
}
|
|
1653
1614
|
async function getBlockRefs(params = {}) {
|
|
1654
1615
|
const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
|
|
1655
1616
|
const cached = getCached(cacheKey);
|
|
1656
|
-
if (cached)
|
|
1657
|
-
|
|
1658
|
-
if (!cad.connected)
|
|
1659
|
-
await cad.connect();
|
|
1617
|
+
if (cached) return cached;
|
|
1618
|
+
if (!cad.connected) await cad.connect();
|
|
1660
1619
|
if (!cad.connected) {
|
|
1661
1620
|
return { total: 0, blockRefs: [] };
|
|
1662
1621
|
}
|
|
1663
1622
|
try {
|
|
1664
1623
|
const code = buildBlockRefsCode(params.blockName);
|
|
1665
1624
|
const resultStr = await cad.sendCommandWithResult(code);
|
|
1666
|
-
if (!resultStr || resultStr === "" || resultStr === "nil") {
|
|
1667
|
-
return { total: 0, blockRefs: [] };
|
|
1668
|
-
}
|
|
1669
1625
|
const parsed = parseLispRecursive(resultStr);
|
|
1670
1626
|
if (!parsed || !Array.isArray(parsed)) {
|
|
1671
|
-
|
|
1627
|
+
throw new Error(`block-refs: \u89E3\u6790 Lisp \u7ED3\u679C\u5931\u8D25: raw="${String(resultStr).substring(0, 500)}"`);
|
|
1628
|
+
}
|
|
1629
|
+
const result = {};
|
|
1630
|
+
for (const pair of parsed) {
|
|
1631
|
+
if (Array.isArray(pair) && pair.length >= 2) {
|
|
1632
|
+
result[String(pair[0])] = pair[1];
|
|
1633
|
+
}
|
|
1672
1634
|
}
|
|
1673
|
-
const result = lispPairsToObject(parsed);
|
|
1674
1635
|
const blockRefs = Array.isArray(result.blockRefs) ? result.blockRefs : [];
|
|
1675
1636
|
const finalResult = {
|
|
1676
1637
|
total: typeof result.total === "number" ? result.total : blockRefs.length,
|
|
@@ -1680,7 +1641,7 @@ async function getBlockRefs(params = {}) {
|
|
|
1680
1641
|
br.forEach((pair) => {
|
|
1681
1642
|
if (Array.isArray(pair) && pair.length >= 2) {
|
|
1682
1643
|
const key = pair[0];
|
|
1683
|
-
let val = pair[1];
|
|
1644
|
+
let val = pair.length === 2 ? pair[1] : pair.slice(1);
|
|
1684
1645
|
if (key === "insertionPoint" && Array.isArray(val)) {
|
|
1685
1646
|
val = val.map((v) => typeof v === "number" ? v : 0);
|
|
1686
1647
|
} else if (key === "scale" && Array.isArray(val)) {
|
|
@@ -1699,51 +1660,67 @@ async function getBlockRefs(params = {}) {
|
|
|
1699
1660
|
return finalResult;
|
|
1700
1661
|
} catch (e) {
|
|
1701
1662
|
log(`getBlockRefs error: ${e.message}`);
|
|
1702
|
-
|
|
1663
|
+
throw e;
|
|
1703
1664
|
}
|
|
1704
1665
|
}
|
|
1666
|
+
var VLA_HELPER_LISP = `(defun @:get-props (obj prop-names / result p p-sym val)
|
|
1667
|
+
(setq result nil)
|
|
1668
|
+
(foreach p prop-names
|
|
1669
|
+
(setq p-sym (read p))
|
|
1670
|
+
(if (vlax-property-available-p obj p-sym)
|
|
1671
|
+
(progn
|
|
1672
|
+
(setq val (vl-catch-all-apply 'vlax-get (list obj p-sym)))
|
|
1673
|
+
(if (not (vl-catch-all-error-p val))
|
|
1674
|
+
(progn
|
|
1675
|
+
(cond
|
|
1676
|
+
((= (type val) 'VLA-OBJECT) (setq val (strcat "@" (vla-get-objectname val))))
|
|
1677
|
+
((or (= (type val) 'STR) (= (type val) 'SAFEARRAY) (listp val)) (setq val (vl-prin1-to-string val))))
|
|
1678
|
+
(setq result (cons (cons p val) result)))))))
|
|
1679
|
+
(reverse result))`;
|
|
1705
1680
|
function buildTablesCode(tblName) {
|
|
1706
1681
|
const raw = tblName.toLowerCase();
|
|
1707
1682
|
const key = TBL_KEY_ALIAS[raw] || raw;
|
|
1708
1683
|
const query = TBL_QUERIES[key];
|
|
1684
|
+
const isVlaTable = key !== "layer";
|
|
1709
1685
|
if (query) {
|
|
1686
|
+
if (isVlaTable) {
|
|
1687
|
+
return `(progn (vl-load-com) ${VLA_HELPER_LISP} ${query.lisp})`;
|
|
1688
|
+
}
|
|
1710
1689
|
return `(progn (vl-load-com) ${query.lisp})`;
|
|
1711
1690
|
}
|
|
1712
|
-
const parts = Object.values(TBL_QUERIES).map((q) => q.lisp);
|
|
1713
|
-
return `(progn (vl-load-com) (list ${parts.join(" ")}))`;
|
|
1691
|
+
const parts = Object.values(TBL_QUERIES).map((q) => `(vl-catch-all-apply '(lambda () ${q.lisp}))`);
|
|
1692
|
+
return `(progn (vl-load-com) ${VLA_HELPER_LISP} (list ${parts.join(" ")}))`;
|
|
1714
1693
|
}
|
|
1715
|
-
function parseTableRecord(rec) {
|
|
1716
|
-
if (!rec || !Array.isArray(rec))
|
|
1717
|
-
return null;
|
|
1694
|
+
function parseTableRecord(rec, tableName) {
|
|
1695
|
+
if (!rec || !Array.isArray(rec)) return null;
|
|
1718
1696
|
const obj = {};
|
|
1697
|
+
const isLayer = tableName === "layer";
|
|
1719
1698
|
for (const pair of rec) {
|
|
1720
1699
|
if (Array.isArray(pair) && pair.length >= 2) {
|
|
1721
1700
|
const key = String(pair[0]);
|
|
1722
1701
|
const val = pair[1];
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
obj.color = typeof val === "number" ? val : 7;
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
obj.on = val === 0;
|
|
1735
|
-
|
|
1736
|
-
obj.
|
|
1737
|
-
|
|
1738
|
-
obj.
|
|
1739
|
-
|
|
1740
|
-
obj.
|
|
1741
|
-
else
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
else if (key === "50")
|
|
1746
|
-
obj.flags = typeof val === "number" ? val : 0;
|
|
1702
|
+
const isDxfCode = typeof pair[0] === "number";
|
|
1703
|
+
if (isDxfCode) {
|
|
1704
|
+
if (key === "2") obj.name = String(val);
|
|
1705
|
+
else if (key === "62") obj.color = typeof val === "number" ? val : 7;
|
|
1706
|
+
else if (key === "6") obj.linetype = String(val);
|
|
1707
|
+
else if (key === "70") {
|
|
1708
|
+
obj.flags = typeof val === "number" ? val : 0;
|
|
1709
|
+
if (isLayer) {
|
|
1710
|
+
obj.frozen = (val & 1) !== 0;
|
|
1711
|
+
obj.locked = (val & 4) !== 0;
|
|
1712
|
+
}
|
|
1713
|
+
} else if (key === "60") obj.on = val === 0;
|
|
1714
|
+
else if (key === "1") obj.font = String(val);
|
|
1715
|
+
else if (key === "40") obj.height = typeof val === "number" ? val : 0;
|
|
1716
|
+
else if (key === "41") obj.width = typeof val === "number" ? val : 1;
|
|
1717
|
+
else if (key === "42") obj.oblique = typeof val === "number" ? val : 0;
|
|
1718
|
+
else if (key === "3") obj.bigfont = String(val);
|
|
1719
|
+
else if (key === "50") obj.flags = typeof val === "number" ? val : 0;
|
|
1720
|
+
} else {
|
|
1721
|
+
if (key === "Name") obj.name = val;
|
|
1722
|
+
obj[key] = val;
|
|
1723
|
+
}
|
|
1747
1724
|
}
|
|
1748
1725
|
}
|
|
1749
1726
|
return obj.name ? obj : null;
|
|
@@ -1752,12 +1729,9 @@ async function getTables(params = {}) {
|
|
|
1752
1729
|
const tblName = params.tbl || params.type || "all";
|
|
1753
1730
|
const cacheKey = `dwg:tbl:${tblName}`;
|
|
1754
1731
|
const cached = getCached(cacheKey);
|
|
1755
|
-
if (cached)
|
|
1756
|
-
|
|
1757
|
-
if (!cad.connected)
|
|
1758
|
-
await cad.connect();
|
|
1759
|
-
if (!cad.connected)
|
|
1760
|
-
return { table: tblName, data: [] };
|
|
1732
|
+
if (cached) return cached;
|
|
1733
|
+
if (!cad.connected) await cad.connect();
|
|
1734
|
+
if (!cad.connected) return { table: tblName, data: [] };
|
|
1761
1735
|
try {
|
|
1762
1736
|
const code = buildTablesCode(tblName);
|
|
1763
1737
|
const resultStr = await cad.sendCommandWithResult(code);
|
|
@@ -1776,10 +1750,9 @@ async function getTables(params = {}) {
|
|
|
1776
1750
|
for (const item of parsed) {
|
|
1777
1751
|
if (Array.isArray(item) && item.length >= 2) {
|
|
1778
1752
|
const key = String(item[0]).toUpperCase();
|
|
1779
|
-
if (key === "TOTAL")
|
|
1780
|
-
total = typeof item[1] === "number" ? item[1] : 0;
|
|
1753
|
+
if (key === "TOTAL") total = typeof item[1] === "number" ? item[1] : 0;
|
|
1781
1754
|
else if (key === "DATA") {
|
|
1782
|
-
if (Array.isArray(item[1]) && item[1].length > 0
|
|
1755
|
+
if (Array.isArray(item[1]) && item[1].length > 0) {
|
|
1783
1756
|
tblData = item[1];
|
|
1784
1757
|
}
|
|
1785
1758
|
}
|
|
@@ -1791,46 +1764,41 @@ async function getTables(params = {}) {
|
|
|
1791
1764
|
result = {
|
|
1792
1765
|
table: tableName,
|
|
1793
1766
|
total,
|
|
1794
|
-
data: tblData.map(parseTableRecord).filter(Boolean)
|
|
1767
|
+
data: tblData.map((r) => parseTableRecord(r, tableName)).filter(Boolean)
|
|
1795
1768
|
};
|
|
1796
1769
|
} else {
|
|
1797
1770
|
const allData = {};
|
|
1798
1771
|
parsed.forEach((item) => {
|
|
1799
|
-
if (!Array.isArray(item) || item.length < 2)
|
|
1800
|
-
return;
|
|
1772
|
+
if (!Array.isArray(item) || item.length < 2) return;
|
|
1801
1773
|
let tableKey = null;
|
|
1802
1774
|
const entry = { total: 0, data: [] };
|
|
1803
1775
|
if (Array.isArray(item[0]) && item[0].length >= 2 && String(item[0][0]).toLowerCase() === "table") {
|
|
1804
1776
|
tableKey = String(item[0][1]).toLowerCase();
|
|
1805
1777
|
for (let i = 1; i < item.length; i++) {
|
|
1806
1778
|
const sub = item[i];
|
|
1807
|
-
if (!Array.isArray(sub) || sub.length < 2)
|
|
1808
|
-
continue;
|
|
1779
|
+
if (!Array.isArray(sub) || sub.length < 2) continue;
|
|
1809
1780
|
const subKey = String(sub[0]).toUpperCase();
|
|
1810
|
-
if (subKey === "TOTAL")
|
|
1811
|
-
entry.total = typeof sub[1] === "number" ? sub[1] : 0;
|
|
1781
|
+
if (subKey === "TOTAL") entry.total = typeof sub[1] === "number" ? sub[1] : 0;
|
|
1812
1782
|
else if (subKey === "DATA") {
|
|
1813
1783
|
const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
|
|
1814
|
-
entry.data = raw.map(parseTableRecord).filter(Boolean);
|
|
1784
|
+
entry.data = raw.map((r) => parseTableRecord(r, tableKey)).filter(Boolean);
|
|
1815
1785
|
}
|
|
1816
1786
|
}
|
|
1817
1787
|
} else {
|
|
1818
1788
|
tableKey = String(item[0]).toLowerCase();
|
|
1819
1789
|
for (let i = 1; i < item.length; i++) {
|
|
1820
1790
|
const sub = item[i];
|
|
1821
|
-
if (!Array.isArray(sub) || sub.length < 2)
|
|
1822
|
-
continue;
|
|
1791
|
+
if (!Array.isArray(sub) || sub.length < 2) continue;
|
|
1823
1792
|
const subKey = String(sub[0]).toUpperCase();
|
|
1824
1793
|
if (subKey === "TOTAL") {
|
|
1825
1794
|
entry.total = typeof sub[1] === "number" ? sub[1] : 0;
|
|
1826
1795
|
} else if (subKey === "DATA") {
|
|
1827
1796
|
const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
|
|
1828
|
-
entry.data = raw.map(parseTableRecord).filter(Boolean);
|
|
1797
|
+
entry.data = raw.map((r) => parseTableRecord(r, tableKey)).filter(Boolean);
|
|
1829
1798
|
}
|
|
1830
1799
|
}
|
|
1831
1800
|
}
|
|
1832
|
-
if (tableKey)
|
|
1833
|
-
allData[tableKey] = entry;
|
|
1801
|
+
if (tableKey) allData[tableKey] = entry;
|
|
1834
1802
|
});
|
|
1835
1803
|
result = allData;
|
|
1836
1804
|
}
|
|
@@ -1844,12 +1812,9 @@ async function getTables(params = {}) {
|
|
|
1844
1812
|
async function getPackages(filterName = null) {
|
|
1845
1813
|
const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
|
|
1846
1814
|
const cached = getCached(cacheKey);
|
|
1847
|
-
if (cached)
|
|
1848
|
-
|
|
1849
|
-
if (!cad.connected)
|
|
1850
|
-
await cad.connect();
|
|
1851
|
-
if (!cad.connected)
|
|
1852
|
-
return [];
|
|
1815
|
+
if (cached) return cached;
|
|
1816
|
+
if (!cad.connected) await cad.connect();
|
|
1817
|
+
if (!cad.connected) return [];
|
|
1853
1818
|
try {
|
|
1854
1819
|
const code = `(mapcar 'cdr @::*local-pkgs*)`;
|
|
1855
1820
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -1862,8 +1827,7 @@ async function getPackages(filterName = null) {
|
|
|
1862
1827
|
} catch {
|
|
1863
1828
|
raw = parseLispList(result) || [];
|
|
1864
1829
|
}
|
|
1865
|
-
if (!Array.isArray(raw))
|
|
1866
|
-
raw = [];
|
|
1830
|
+
if (!Array.isArray(raw)) raw = [];
|
|
1867
1831
|
const packages = raw.map((item) => {
|
|
1868
1832
|
if (Array.isArray(item)) {
|
|
1869
1833
|
const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
|
|
@@ -1872,20 +1836,13 @@ async function getPackages(filterName = null) {
|
|
|
1872
1836
|
const [[key, val]] = Object.entries(entry);
|
|
1873
1837
|
const k = String(key);
|
|
1874
1838
|
const v = String(val);
|
|
1875
|
-
if (k === ":NAME")
|
|
1876
|
-
|
|
1877
|
-
else if (k === ":
|
|
1878
|
-
|
|
1879
|
-
else if (k === ":
|
|
1880
|
-
|
|
1881
|
-
else if (k === ":
|
|
1882
|
-
pkg.fullName = v;
|
|
1883
|
-
else if (k === ":AUTHOR")
|
|
1884
|
-
pkg.author = v;
|
|
1885
|
-
else if (k === ":CATEGORY")
|
|
1886
|
-
pkg.category = v;
|
|
1887
|
-
else if (k === ":URL")
|
|
1888
|
-
pkg.url = v;
|
|
1839
|
+
if (k === ":NAME") pkg.name = v;
|
|
1840
|
+
else if (k === ":VERSION") pkg.version = v;
|
|
1841
|
+
else if (k === ":DESCRIPTION") pkg.description = v;
|
|
1842
|
+
else if (k === ":FULL-NAME") pkg.fullName = v;
|
|
1843
|
+
else if (k === ":AUTHOR") pkg.author = v;
|
|
1844
|
+
else if (k === ":CATEGORY") pkg.category = v;
|
|
1845
|
+
else if (k === ":URL") pkg.url = v;
|
|
1889
1846
|
}
|
|
1890
1847
|
}
|
|
1891
1848
|
return pkg;
|
|
@@ -1896,22 +1853,15 @@ async function getPackages(filterName = null) {
|
|
|
1896
1853
|
if (item && typeof item === "object") {
|
|
1897
1854
|
const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
|
|
1898
1855
|
const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
|
|
1899
|
-
if (nameVal)
|
|
1900
|
-
pkg.name = String(nameVal);
|
|
1856
|
+
if (nameVal) pkg.name = String(nameVal);
|
|
1901
1857
|
const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
|
|
1902
|
-
if (verVal)
|
|
1903
|
-
pkg.version = String(verVal);
|
|
1858
|
+
if (verVal) pkg.version = String(verVal);
|
|
1904
1859
|
const descVal = item.description || item.Description || item.DESCRIPTION || item[":DESCRIPTION"];
|
|
1905
|
-
if (descVal)
|
|
1906
|
-
|
|
1907
|
-
if (item.
|
|
1908
|
-
|
|
1909
|
-
if (item.
|
|
1910
|
-
pkg.author = String(item.author || item.Author);
|
|
1911
|
-
if (item.category || item.Category)
|
|
1912
|
-
pkg.category = String(item.category || item.Category);
|
|
1913
|
-
if (item.url || item.Url || item.URL)
|
|
1914
|
-
pkg.url = String(item.url || item.Url || item.URL);
|
|
1860
|
+
if (descVal) pkg.description = String(descVal);
|
|
1861
|
+
if (item.fullName || item.full_name) pkg.fullName = String(item.fullName || item.full_name);
|
|
1862
|
+
if (item.author || item.Author) pkg.author = String(item.author || item.Author);
|
|
1863
|
+
if (item.category || item.Category) pkg.category = String(item.category || item.Category);
|
|
1864
|
+
if (item.url || item.Url || item.URL) pkg.url = String(item.url || item.Url || item.URL);
|
|
1915
1865
|
return pkg;
|
|
1916
1866
|
}
|
|
1917
1867
|
return null;
|
|
@@ -1936,12 +1886,9 @@ function getPlatforms() {
|
|
|
1936
1886
|
async function getDwgList() {
|
|
1937
1887
|
const cacheKey = "cad:dwgs";
|
|
1938
1888
|
const cached = getCached(cacheKey);
|
|
1939
|
-
if (cached)
|
|
1940
|
-
|
|
1941
|
-
if (!cad.connected)
|
|
1942
|
-
await cad.connect();
|
|
1943
|
-
if (!cad.connected)
|
|
1944
|
-
return [];
|
|
1889
|
+
if (cached) return cached;
|
|
1890
|
+
if (!cad.connected) await cad.connect();
|
|
1891
|
+
if (!cad.connected) return [];
|
|
1945
1892
|
try {
|
|
1946
1893
|
const code = `(progn
|
|
1947
1894
|
(vl-load-com)
|
|
@@ -1959,13 +1906,12 @@ async function getDwgList() {
|
|
|
1959
1906
|
try {
|
|
1960
1907
|
parsed = JSON.parse(result);
|
|
1961
1908
|
} catch (e) {
|
|
1962
|
-
const listResult =
|
|
1963
|
-
if (listResult) {
|
|
1909
|
+
const listResult = parseLispRecursive(result);
|
|
1910
|
+
if (Array.isArray(listResult)) {
|
|
1964
1911
|
parsed = listResult;
|
|
1965
1912
|
}
|
|
1966
1913
|
}
|
|
1967
|
-
if (!Array.isArray(parsed))
|
|
1968
|
-
parsed = [];
|
|
1914
|
+
if (!Array.isArray(parsed)) parsed = [];
|
|
1969
1915
|
const dwgList = parsed.map((item) => {
|
|
1970
1916
|
if (Array.isArray(item) && item.length >= 2) {
|
|
1971
1917
|
return { name: String(item[0]), path: String(item[1]) };
|
|
@@ -1991,8 +1937,7 @@ function loadStandardsFile(filename) {
|
|
|
1991
1937
|
var standardsCache = /* @__PURE__ */ new Map();
|
|
1992
1938
|
function getCachedStandards(key) {
|
|
1993
1939
|
const entry = standardsCache.get(key);
|
|
1994
|
-
if (entry && Date.now() - entry.timestamp < 3e4)
|
|
1995
|
-
return entry.data;
|
|
1940
|
+
if (entry && Date.now() - entry.timestamp < 3e4) return entry.data;
|
|
1996
1941
|
standardsCache.delete(key);
|
|
1997
1942
|
return null;
|
|
1998
1943
|
}
|
|
@@ -2001,49 +1946,40 @@ function setCachedStandards(key, data) {
|
|
|
2001
1946
|
}
|
|
2002
1947
|
function getDraftingStandards() {
|
|
2003
1948
|
const cached = getCachedStandards("drafting");
|
|
2004
|
-
if (cached)
|
|
2005
|
-
return cached;
|
|
1949
|
+
if (cached) return cached;
|
|
2006
1950
|
const data = loadStandardsFile("drafting.json");
|
|
2007
|
-
if (data)
|
|
2008
|
-
setCachedStandards("drafting", data);
|
|
1951
|
+
if (data) setCachedStandards("drafting", data);
|
|
2009
1952
|
return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
|
|
2010
1953
|
}
|
|
2011
1954
|
function getCodingStandards() {
|
|
2012
1955
|
const cached = getCachedStandards("coding");
|
|
2013
|
-
if (cached)
|
|
2014
|
-
return cached;
|
|
1956
|
+
if (cached) return cached;
|
|
2015
1957
|
const data = loadStandardsFile("coding.json");
|
|
2016
|
-
if (data)
|
|
2017
|
-
setCachedStandards("coding", data);
|
|
1958
|
+
if (data) setCachedStandards("coding", data);
|
|
2018
1959
|
return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
|
|
2019
1960
|
}
|
|
2020
1961
|
|
|
2021
1962
|
// src/handlers/resource-handlers.js
|
|
2022
1963
|
function parseQuery(uri) {
|
|
2023
1964
|
const qIdx = uri.indexOf("?");
|
|
2024
|
-
if (qIdx === -1)
|
|
2025
|
-
return { base: uri, params: {} };
|
|
1965
|
+
if (qIdx === -1) return { base: uri, params: {} };
|
|
2026
1966
|
const base = uri.substring(0, qIdx);
|
|
2027
1967
|
const params = {};
|
|
2028
1968
|
uri.substring(qIdx + 1).split("&").forEach((p) => {
|
|
2029
1969
|
const eqIdx = p.indexOf("=");
|
|
2030
1970
|
const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
|
|
2031
1971
|
const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
|
|
2032
|
-
if (k)
|
|
2033
|
-
params[k] = decodeURIComponent(v);
|
|
1972
|
+
if (k) params[k] = decodeURIComponent(v);
|
|
2034
1973
|
});
|
|
2035
1974
|
return { base, params };
|
|
2036
1975
|
}
|
|
2037
1976
|
function parseTemplateUri(uri) {
|
|
2038
1977
|
const entityMatch = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
|
|
2039
|
-
if (entityMatch)
|
|
2040
|
-
return { type: "entity", handle: entityMatch[1] };
|
|
1978
|
+
if (entityMatch) return { type: "entity", handle: entityMatch[1] };
|
|
2041
1979
|
const tblMatch = uri.match(/^atlisp:\/\/dwg\/tbl\/([^?]+)$/);
|
|
2042
|
-
if (tblMatch)
|
|
2043
|
-
return { type: "tbl", tblName: tblMatch[1] };
|
|
1980
|
+
if (tblMatch) return { type: "tbl", tblName: tblMatch[1] };
|
|
2044
1981
|
const blockRefMatch = uri.match(/^atlisp:\/\/dwg\/block-refs\/([^?]+)$/);
|
|
2045
|
-
if (blockRefMatch)
|
|
2046
|
-
return { type: "block-refs", blockName: blockRefMatch[1] };
|
|
1982
|
+
if (blockRefMatch) return { type: "block-refs", blockName: blockRefMatch[1] };
|
|
2047
1983
|
return null;
|
|
2048
1984
|
}
|
|
2049
1985
|
async function listResources(subscribedUris = []) {
|
|
@@ -2203,10 +2139,8 @@ function isPrefixUri(uri) {
|
|
|
2203
2139
|
return uri.endsWith("/");
|
|
2204
2140
|
}
|
|
2205
2141
|
function matchesSubscription(subscribedUri, targetUri) {
|
|
2206
|
-
if (subscribedUri === targetUri)
|
|
2207
|
-
|
|
2208
|
-
if (isPrefixUri(subscribedUri) && targetUri.startsWith(subscribedUri))
|
|
2209
|
-
return true;
|
|
2142
|
+
if (subscribedUri === targetUri) return true;
|
|
2143
|
+
if (isPrefixUri(subscribedUri) && targetUri.startsWith(subscribedUri)) return true;
|
|
2210
2144
|
return false;
|
|
2211
2145
|
}
|
|
2212
2146
|
function isSubscribed(uri, sessionId) {
|
|
@@ -2216,8 +2150,7 @@ function isSubscribed(uri, sessionId) {
|
|
|
2216
2150
|
}
|
|
2217
2151
|
const allUris = sessionManager.getAllSubscribedUris();
|
|
2218
2152
|
for (const su of allUris) {
|
|
2219
|
-
if (matchesSubscription(su, uri))
|
|
2220
|
-
return true;
|
|
2153
|
+
if (matchesSubscription(su, uri)) return true;
|
|
2221
2154
|
}
|
|
2222
2155
|
return false;
|
|
2223
2156
|
}
|
|
@@ -2326,11 +2259,9 @@ var SseSession = class {
|
|
|
2326
2259
|
return lines.join("\n") + "\n\n";
|
|
2327
2260
|
}
|
|
2328
2261
|
_setupDrain() {
|
|
2329
|
-
if (typeof this.#res.on !== "function")
|
|
2330
|
-
return;
|
|
2262
|
+
if (typeof this.#res.on !== "function") return;
|
|
2331
2263
|
this.#drainHandler = () => {
|
|
2332
|
-
if (!this.#active)
|
|
2333
|
-
return;
|
|
2264
|
+
if (!this.#active) return;
|
|
2334
2265
|
if (this.#backpressureBuffer.length > 0) {
|
|
2335
2266
|
this._drainBuffer();
|
|
2336
2267
|
}
|
|
@@ -2352,8 +2283,7 @@ var SseSession = class {
|
|
|
2352
2283
|
}
|
|
2353
2284
|
}
|
|
2354
2285
|
_write(content) {
|
|
2355
|
-
if (!this.#active)
|
|
2356
|
-
return false;
|
|
2286
|
+
if (!this.#active) return false;
|
|
2357
2287
|
try {
|
|
2358
2288
|
if (this.#backpressureBuffer.length > 0) {
|
|
2359
2289
|
this.#backpressureBuffer.push(content);
|
|
@@ -2482,8 +2412,7 @@ function persistSessionData(clientId, sessionData) {
|
|
|
2482
2412
|
function loadPersistedSessionData(clientId) {
|
|
2483
2413
|
try {
|
|
2484
2414
|
const filePath = getSessionStorePath(clientId);
|
|
2485
|
-
if (!fs4.existsSync(filePath))
|
|
2486
|
-
return null;
|
|
2415
|
+
if (!fs4.existsSync(filePath)) return null;
|
|
2487
2416
|
const raw = fs4.readFileSync(filePath, "utf-8");
|
|
2488
2417
|
const store = JSON.parse(raw);
|
|
2489
2418
|
if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
|
|
@@ -2547,8 +2476,7 @@ var SseSessionManager = class {
|
|
|
2547
2476
|
session.close();
|
|
2548
2477
|
this.#sessions.delete(clientId);
|
|
2549
2478
|
const idx = this.#accessOrder.indexOf(clientId);
|
|
2550
|
-
if (idx !== -1)
|
|
2551
|
-
this.#accessOrder.splice(idx, 1);
|
|
2479
|
+
if (idx !== -1) this.#accessOrder.splice(idx, 1);
|
|
2552
2480
|
return true;
|
|
2553
2481
|
}
|
|
2554
2482
|
return false;
|
|
@@ -2635,8 +2563,7 @@ var SseSessionManager = class {
|
|
|
2635
2563
|
session.close();
|
|
2636
2564
|
this.#sessions.delete(clientId);
|
|
2637
2565
|
const idx = this.#accessOrder.indexOf(clientId);
|
|
2638
|
-
if (idx !== -1)
|
|
2639
|
-
this.#accessOrder.splice(idx, 1);
|
|
2566
|
+
if (idx !== -1) this.#accessOrder.splice(idx, 1);
|
|
2640
2567
|
}
|
|
2641
2568
|
}
|
|
2642
2569
|
}
|
|
@@ -2684,8 +2611,7 @@ var SessionTransport = class {
|
|
|
2684
2611
|
this._started = true;
|
|
2685
2612
|
}
|
|
2686
2613
|
async send(message) {
|
|
2687
|
-
if (this._closed)
|
|
2688
|
-
return;
|
|
2614
|
+
if (this._closed) return;
|
|
2689
2615
|
if (this._pendingRequest) {
|
|
2690
2616
|
const { resolve, reject, timeout } = this._pendingRequest;
|
|
2691
2617
|
clearTimeout(timeout);
|
|
@@ -2694,8 +2620,7 @@ var SessionTransport = class {
|
|
|
2694
2620
|
}
|
|
2695
2621
|
}
|
|
2696
2622
|
async close() {
|
|
2697
|
-
if (this._closed)
|
|
2698
|
-
return;
|
|
2623
|
+
if (this._closed) return;
|
|
2699
2624
|
this._closed = true;
|
|
2700
2625
|
if (this._pendingRequest) {
|
|
2701
2626
|
const { reject, timeout } = this._pendingRequest;
|
|
@@ -2769,12 +2694,10 @@ var DEFS_DIR = path7.join(__dirname3, "definitions");
|
|
|
2769
2694
|
var PROMPTS_DIR = path7.join(__dirname3, "..", "..", "prompts");
|
|
2770
2695
|
var builtinDefs = null;
|
|
2771
2696
|
function loadBuiltinDefs() {
|
|
2772
|
-
if (builtinDefs)
|
|
2773
|
-
return builtinDefs;
|
|
2697
|
+
if (builtinDefs) return builtinDefs;
|
|
2774
2698
|
builtinDefs = {};
|
|
2775
2699
|
try {
|
|
2776
|
-
if (!fs5.existsSync(DEFS_DIR))
|
|
2777
|
-
return builtinDefs;
|
|
2700
|
+
if (!fs5.existsSync(DEFS_DIR)) return builtinDefs;
|
|
2778
2701
|
const files = fs5.readdirSync(DEFS_DIR).filter((f) => f.endsWith(".json"));
|
|
2779
2702
|
for (const file of files) {
|
|
2780
2703
|
try {
|
|
@@ -2836,15 +2759,12 @@ function formatLispPoints(pointsStr) {
|
|
|
2836
2759
|
return `(list ${ptList.join(" ")})`;
|
|
2837
2760
|
}
|
|
2838
2761
|
function getDimensionStyleLisp(style) {
|
|
2839
|
-
if (style === "horizontal" || style === "vertical")
|
|
2840
|
-
return "DIMLINEAR";
|
|
2762
|
+
if (style === "horizontal" || style === "vertical") return "DIMLINEAR";
|
|
2841
2763
|
return "DIMALIGNED";
|
|
2842
2764
|
}
|
|
2843
2765
|
function getDimensionStyleLabel(style) {
|
|
2844
|
-
if (style === "horizontal")
|
|
2845
|
-
|
|
2846
|
-
if (style === "vertical")
|
|
2847
|
-
return "\u5782\u76F4";
|
|
2766
|
+
if (style === "horizontal") return "\u6C34\u5E73";
|
|
2767
|
+
if (style === "vertical") return "\u5782\u76F4";
|
|
2848
2768
|
return "aligned";
|
|
2849
2769
|
}
|
|
2850
2770
|
async function handleComplexPrompt(def, args) {
|
|
@@ -2878,14 +2798,10 @@ async function handleComplexPrompt(def, args) {
|
|
|
2878
2798
|
} catch {
|
|
2879
2799
|
}
|
|
2880
2800
|
const suggestions = [];
|
|
2881
|
-
if (entities.total > 1e3)
|
|
2882
|
-
|
|
2883
|
-
if (
|
|
2884
|
-
|
|
2885
|
-
if (entities.byType.LINE && entities.byType.LINE > 500)
|
|
2886
|
-
suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
|
|
2887
|
-
if (!entities.byType.DIMENSION)
|
|
2888
|
-
suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
|
|
2801
|
+
if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
|
|
2802
|
+
if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
|
|
2803
|
+
if (entities.byType.LINE && entities.byType.LINE > 500) suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
|
|
2804
|
+
if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
|
|
2889
2805
|
return {
|
|
2890
2806
|
messages: [{
|
|
2891
2807
|
role: "user",
|
|
@@ -3078,8 +2994,7 @@ ${code}
|
|
|
3078
2994
|
}
|
|
3079
2995
|
const defs = loadBuiltinDefs();
|
|
3080
2996
|
const def = defs[name];
|
|
3081
|
-
if (!def)
|
|
3082
|
-
throw new Error(`Unknown prompt: ${name}`);
|
|
2997
|
+
if (!def) throw new Error(`Unknown prompt: ${name}`);
|
|
3083
2998
|
if (def.handler) {
|
|
3084
2999
|
return handleComplexPrompt(def, args);
|
|
3085
3000
|
}
|
|
@@ -3104,8 +3019,7 @@ import path8 from "path";
|
|
|
3104
3019
|
init_config();
|
|
3105
3020
|
var MAX_HISTORY_VALUES = 1e3;
|
|
3106
3021
|
function percentile(sorted, p) {
|
|
3107
|
-
if (sorted.length === 0)
|
|
3108
|
-
return 0;
|
|
3022
|
+
if (sorted.length === 0) return 0;
|
|
3109
3023
|
const idx = Math.ceil(p * sorted.length) - 1;
|
|
3110
3024
|
return sorted[Math.max(0, Math.min(idx, sorted.length - 1))];
|
|
3111
3025
|
}
|
|
@@ -3396,8 +3310,7 @@ async function evalLisp(code, withResult = false, encoding = null) {
|
|
|
3396
3310
|
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3397
3311
|
}
|
|
3398
3312
|
const trimmed = (code || "").trim();
|
|
3399
|
-
if (!trimmed)
|
|
3400
|
-
return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
3313
|
+
if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
3401
3314
|
try {
|
|
3402
3315
|
if (withResult) {
|
|
3403
3316
|
const result = await cad.sendCommandWithResult(trimmed, encoding);
|
|
@@ -3417,17 +3330,14 @@ async function getCadInfo2() {
|
|
|
3417
3330
|
if (!cad.connected) {
|
|
3418
3331
|
await cad.connect();
|
|
3419
3332
|
}
|
|
3420
|
-
if (!cad.connected)
|
|
3421
|
-
return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
|
|
3333
|
+
if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
|
|
3422
3334
|
const info = await cad.getInfo();
|
|
3423
3335
|
return { content: [{ type: "text", text: info }] };
|
|
3424
3336
|
}
|
|
3425
3337
|
async function atCommand(command) {
|
|
3426
|
-
if (!cad.connected)
|
|
3427
|
-
return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
|
|
3338
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
|
|
3428
3339
|
const trimmed = (command || "").trim();
|
|
3429
|
-
if (!trimmed)
|
|
3430
|
-
return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
3340
|
+
if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
3431
3341
|
await cad.sendCommand(trimmed + "\n");
|
|
3432
3342
|
return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
|
|
3433
3343
|
}
|
|
@@ -3435,8 +3345,7 @@ async function newDocument() {
|
|
|
3435
3345
|
if (!cad.connected) {
|
|
3436
3346
|
await cad.connect();
|
|
3437
3347
|
}
|
|
3438
|
-
if (!cad.connected)
|
|
3439
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3348
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3440
3349
|
const result = await cad.newDoc();
|
|
3441
3350
|
if (result) {
|
|
3442
3351
|
return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
|
|
@@ -3447,8 +3356,7 @@ async function bringToFront() {
|
|
|
3447
3356
|
if (!cad.connected) {
|
|
3448
3357
|
await cad.connect();
|
|
3449
3358
|
}
|
|
3450
|
-
if (!cad.connected)
|
|
3451
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3359
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3452
3360
|
const result = await cad.bringToFront();
|
|
3453
3361
|
if (result) {
|
|
3454
3362
|
return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
|
|
@@ -3459,8 +3367,7 @@ async function installAtlisp() {
|
|
|
3459
3367
|
if (!cad.connected) {
|
|
3460
3368
|
await cad.connect();
|
|
3461
3369
|
}
|
|
3462
|
-
if (!cad.connected)
|
|
3463
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3370
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3464
3371
|
const installCode = `(progn(vl-load-com)(setq s strcat h "http" o(vlax-create-object (s"win"h".win"h"request.5.1"))v vlax-invoke e eval r read)(v o'open "get" (s h"://atlisp.""cn/@"):vlax-true)(v o'send)(v o'WaitforResponse 1000)(e(r(vlax-get-property o'ResponseText))))`;
|
|
3465
3372
|
await cad.sendCommand(installCode + "\n");
|
|
3466
3373
|
return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
|
|
@@ -3469,12 +3376,10 @@ async function listFunctionsInCad() {
|
|
|
3469
3376
|
if (!cad.connected) {
|
|
3470
3377
|
await cad.connect();
|
|
3471
3378
|
}
|
|
3472
|
-
if (!cad.connected)
|
|
3473
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3379
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3474
3380
|
try {
|
|
3475
3381
|
const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
|
|
3476
|
-
if (result)
|
|
3477
|
-
return { content: [{ type: "text", text: result }] };
|
|
3382
|
+
if (result) return { content: [{ type: "text", text: result }] };
|
|
3478
3383
|
return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
|
|
3479
3384
|
} catch (e) {
|
|
3480
3385
|
return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
|
|
@@ -3531,8 +3436,7 @@ async function initAtlisp() {
|
|
|
3531
3436
|
if (!cad.connected) {
|
|
3532
3437
|
await cad.connect();
|
|
3533
3438
|
}
|
|
3534
|
-
if (!cad.connected)
|
|
3535
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3439
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3536
3440
|
const code = `(if (null @::load-module)
|
|
3537
3441
|
(progn
|
|
3538
3442
|
(vl-load-com)
|
|
@@ -3574,15 +3478,12 @@ async function fetchPackages() {
|
|
|
3574
3478
|
return cachedPackages || MOCK_PACKAGES;
|
|
3575
3479
|
}
|
|
3576
3480
|
function flattenPackages(data) {
|
|
3577
|
-
if (Array.isArray(data))
|
|
3578
|
-
|
|
3579
|
-
if (data && Array.isArray(data.packages))
|
|
3580
|
-
return data.packages;
|
|
3481
|
+
if (Array.isArray(data)) return data;
|
|
3482
|
+
if (data && Array.isArray(data.packages)) return data.packages;
|
|
3581
3483
|
return [];
|
|
3582
3484
|
}
|
|
3583
3485
|
async function listPackages() {
|
|
3584
|
-
if (!cad.connected)
|
|
3585
|
-
await cad.connect();
|
|
3486
|
+
if (!cad.connected) await cad.connect();
|
|
3586
3487
|
if (!cad.connected) {
|
|
3587
3488
|
const data2 = await fetchPackages();
|
|
3588
3489
|
const items2 = flattenPackages(data2);
|
|
@@ -3590,8 +3491,7 @@ async function listPackages() {
|
|
|
3590
3491
|
return { content: [{ type: "text", text: text2 }] };
|
|
3591
3492
|
}
|
|
3592
3493
|
const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
|
|
3593
|
-
if (result && result !== "nil")
|
|
3594
|
-
return { content: [{ type: "text", text: result }] };
|
|
3494
|
+
if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
|
|
3595
3495
|
const data = await fetchPackages();
|
|
3596
3496
|
const items = flattenPackages(data);
|
|
3597
3497
|
const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
|
|
@@ -3611,12 +3511,10 @@ async function searchPackages(query) {
|
|
|
3611
3511
|
for (const p of items) {
|
|
3612
3512
|
const name = (p.name || "").toLowerCase();
|
|
3613
3513
|
const desc = (p.description || "").toLowerCase();
|
|
3614
|
-
if (name.includes(q) || desc.includes(q))
|
|
3615
|
-
results.push(p);
|
|
3514
|
+
if (name.includes(q) || desc.includes(q)) results.push(p);
|
|
3616
3515
|
}
|
|
3617
3516
|
} else {
|
|
3618
|
-
for (const p of items)
|
|
3619
|
-
results.push(p);
|
|
3517
|
+
for (const p of items) results.push(p);
|
|
3620
3518
|
}
|
|
3621
3519
|
if (results.length === 0) {
|
|
3622
3520
|
return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
|
|
@@ -3705,8 +3603,7 @@ async function getFunctionUsage(funcName, packageName) {
|
|
|
3705
3603
|
if (data) {
|
|
3706
3604
|
const funcs = Object.values(data.all_functions || {});
|
|
3707
3605
|
const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
|
|
3708
|
-
if (func)
|
|
3709
|
-
results.push(func);
|
|
3606
|
+
if (func) results.push(func);
|
|
3710
3607
|
}
|
|
3711
3608
|
if (results.length === 0 && FUNCTIONS_DIR) {
|
|
3712
3609
|
try {
|
|
@@ -3715,8 +3612,7 @@ async function getFunctionUsage(funcName, packageName) {
|
|
|
3715
3612
|
const raw = fs6.readFileSync(path9.join(FUNCTIONS_DIR, file), "utf-8");
|
|
3716
3613
|
const data2 = JSON.parse(raw);
|
|
3717
3614
|
const func = data2.functions?.find((f2) => f2.name === funcName);
|
|
3718
|
-
if (func)
|
|
3719
|
-
results.push(func);
|
|
3615
|
+
if (func) results.push(func);
|
|
3720
3616
|
}
|
|
3721
3617
|
} catch (e) {
|
|
3722
3618
|
log(`function-handlers: FUNCTIONS_DIR read error: ${e.message}`);
|
|
@@ -3786,8 +3682,7 @@ async function getEntity(handle) {
|
|
|
3786
3682
|
if (!cad.connected) {
|
|
3787
3683
|
await cad.connect();
|
|
3788
3684
|
}
|
|
3789
|
-
if (!cad.connected)
|
|
3790
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3685
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3791
3686
|
const code = `(progn
|
|
3792
3687
|
(vl-load-com)
|
|
3793
3688
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -3819,8 +3714,7 @@ async function setEntityProperty(handle, property, value) {
|
|
|
3819
3714
|
if (!cad.connected) {
|
|
3820
3715
|
await cad.connect();
|
|
3821
3716
|
}
|
|
3822
|
-
if (!cad.connected)
|
|
3823
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3717
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3824
3718
|
let propCode = "";
|
|
3825
3719
|
switch (property) {
|
|
3826
3720
|
case "layer":
|
|
@@ -3863,8 +3757,7 @@ async function deleteEntity(handle) {
|
|
|
3863
3757
|
if (!cad.connected) {
|
|
3864
3758
|
await cad.connect();
|
|
3865
3759
|
}
|
|
3866
|
-
if (!cad.connected)
|
|
3867
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3760
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3868
3761
|
const code = `(progn
|
|
3869
3762
|
(vl-load-com)
|
|
3870
3763
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -3889,15 +3782,12 @@ async function selectEntities(filter) {
|
|
|
3889
3782
|
if (!cad.connected) {
|
|
3890
3783
|
await cad.connect();
|
|
3891
3784
|
}
|
|
3892
|
-
if (!cad.connected)
|
|
3893
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3785
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3894
3786
|
let filterCode = "nil";
|
|
3895
3787
|
if (filter && (filter.type || filter.layer)) {
|
|
3896
3788
|
const items = [];
|
|
3897
|
-
if (filter.type)
|
|
3898
|
-
|
|
3899
|
-
if (filter.layer)
|
|
3900
|
-
items.push(`'(8 . "${escapeLispString(filter.layer)}")`);
|
|
3789
|
+
if (filter.type) items.push(`'(0 . "${escapeLispString(filter.type)}")`);
|
|
3790
|
+
if (filter.layer) items.push(`'(8 . "${escapeLispString(filter.layer)}")`);
|
|
3901
3791
|
filterCode = `(list ${items.join(" ")})`;
|
|
3902
3792
|
}
|
|
3903
3793
|
const code = `(progn
|
|
@@ -3930,8 +3820,7 @@ async function createLayer(name, color = 7, linetype = "Continuous") {
|
|
|
3930
3820
|
if (!cad.connected) {
|
|
3931
3821
|
await cad.connect();
|
|
3932
3822
|
}
|
|
3933
|
-
if (!cad.connected)
|
|
3934
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3823
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3935
3824
|
const code = `(progn
|
|
3936
3825
|
(vl-load-com)
|
|
3937
3826
|
(if (not (tblsearch "LAYER" "${escapeLispString(name)}"))
|
|
@@ -3967,8 +3856,7 @@ async function deleteLayer(name) {
|
|
|
3967
3856
|
if (!cad.connected) {
|
|
3968
3857
|
await cad.connect();
|
|
3969
3858
|
}
|
|
3970
|
-
if (!cad.connected)
|
|
3971
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3859
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3972
3860
|
const code = `(progn
|
|
3973
3861
|
(vl-load-com)
|
|
3974
3862
|
(cond
|
|
@@ -4002,8 +3890,7 @@ async function setLayerProperty(name, property, value) {
|
|
|
4002
3890
|
if (!cad.connected) {
|
|
4003
3891
|
await cad.connect();
|
|
4004
3892
|
}
|
|
4005
|
-
if (!cad.connected)
|
|
4006
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3893
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4007
3894
|
let propCode = "";
|
|
4008
3895
|
switch (property) {
|
|
4009
3896
|
case "color":
|
|
@@ -4051,8 +3938,7 @@ async function setCurrentLayer(name) {
|
|
|
4051
3938
|
if (!cad.connected) {
|
|
4052
3939
|
await cad.connect();
|
|
4053
3940
|
}
|
|
4054
|
-
if (!cad.connected)
|
|
4055
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3941
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4056
3942
|
const code = `(progn
|
|
4057
3943
|
(vl-load-com)
|
|
4058
3944
|
(if (tblsearch "LAYER" "${escapeLispString(name)}")
|
|
@@ -4080,8 +3966,7 @@ async function createBlock(name, entities) {
|
|
|
4080
3966
|
if (!cad.connected) {
|
|
4081
3967
|
await cad.connect();
|
|
4082
3968
|
}
|
|
4083
|
-
if (!cad.connected)
|
|
4084
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
3969
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4085
3970
|
const code = `(progn
|
|
4086
3971
|
(vl-load-com)
|
|
4087
3972
|
(if (not (tblsearch "BLOCK" "${escapeLispString(name)}"))
|
|
@@ -4118,8 +4003,7 @@ async function insertBlock(blockName, point, scale = 1, rotation = 0) {
|
|
|
4118
4003
|
if (!cad.connected) {
|
|
4119
4004
|
await cad.connect();
|
|
4120
4005
|
}
|
|
4121
|
-
if (!cad.connected)
|
|
4122
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4006
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4123
4007
|
const coords = Array.isArray(point) ? point : point.split(",").map((s) => parseFloat(s.trim()));
|
|
4124
4008
|
if (coords.length < 2) {
|
|
4125
4009
|
return { content: [{ type: "text", text: "\u63D2\u5165\u70B9\u683C\u5F0F\u9519\u8BEF\uFF0C\u9700\u8981 x,y \u6216 [x,y,z]" }], isError: true };
|
|
@@ -4149,8 +4033,7 @@ async function getBlocks() {
|
|
|
4149
4033
|
if (!cad.connected) {
|
|
4150
4034
|
await cad.connect();
|
|
4151
4035
|
}
|
|
4152
|
-
if (!cad.connected)
|
|
4153
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4036
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4154
4037
|
const code = `(progn
|
|
4155
4038
|
(vl-load-com)
|
|
4156
4039
|
(setq blocks nil)
|
|
@@ -4173,8 +4056,7 @@ async function explodeBlock(handle) {
|
|
|
4173
4056
|
if (!cad.connected) {
|
|
4174
4057
|
await cad.connect();
|
|
4175
4058
|
}
|
|
4176
|
-
if (!cad.connected)
|
|
4177
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4059
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4178
4060
|
const code = `(progn
|
|
4179
4061
|
(vl-load-com)
|
|
4180
4062
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -4210,8 +4092,7 @@ async function openDwg(filePath) {
|
|
|
4210
4092
|
if (!cad.connected) {
|
|
4211
4093
|
await cad.connect();
|
|
4212
4094
|
}
|
|
4213
|
-
if (!cad.connected)
|
|
4214
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4095
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4215
4096
|
try {
|
|
4216
4097
|
validateFilePath(filePath);
|
|
4217
4098
|
} catch (e) {
|
|
@@ -4252,8 +4133,7 @@ async function saveDwg(filePath = null) {
|
|
|
4252
4133
|
if (!cad.connected) {
|
|
4253
4134
|
await cad.connect();
|
|
4254
4135
|
}
|
|
4255
|
-
if (!cad.connected)
|
|
4256
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4136
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4257
4137
|
if (filePath) {
|
|
4258
4138
|
try {
|
|
4259
4139
|
validateFilePath(filePath);
|
|
@@ -4284,8 +4164,7 @@ async function exportPdf(outputPath, layout = "Model") {
|
|
|
4284
4164
|
if (!cad.connected) {
|
|
4285
4165
|
await cad.connect();
|
|
4286
4166
|
}
|
|
4287
|
-
if (!cad.connected)
|
|
4288
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4167
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4289
4168
|
try {
|
|
4290
4169
|
validateFilePath(outputPath);
|
|
4291
4170
|
} catch (e) {
|
|
@@ -4317,8 +4196,7 @@ async function closeDwg(save = false) {
|
|
|
4317
4196
|
if (!cad.connected) {
|
|
4318
4197
|
await cad.connect();
|
|
4319
4198
|
}
|
|
4320
|
-
if (!cad.connected)
|
|
4321
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4199
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4322
4200
|
const code = `(progn
|
|
4323
4201
|
(vl-load-com)
|
|
4324
4202
|
(if ${save ? "T" : "nil"}
|
|
@@ -4345,8 +4223,7 @@ async function createDimension(type, points, style = {}) {
|
|
|
4345
4223
|
if (!cad.connected) {
|
|
4346
4224
|
await cad.connect();
|
|
4347
4225
|
}
|
|
4348
|
-
if (!cad.connected)
|
|
4349
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4226
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4350
4227
|
let dimCode = "";
|
|
4351
4228
|
const validTypes = ["ALIGNED", "LINEAR", "ORDINATE", "RADIAL", "DIAMETER", "ANGULAR"];
|
|
4352
4229
|
const dimType = (type || "ALIGNED").toUpperCase();
|
|
@@ -4388,8 +4265,7 @@ async function getDimensionValue(handle) {
|
|
|
4388
4265
|
if (!cad.connected) {
|
|
4389
4266
|
await cad.connect();
|
|
4390
4267
|
}
|
|
4391
|
-
if (!cad.connected)
|
|
4392
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4268
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4393
4269
|
const code = `(progn
|
|
4394
4270
|
(vl-load-com)
|
|
4395
4271
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -4420,8 +4296,7 @@ async function createHatch(patternName, boundary, scale = 1, angle = 0) {
|
|
|
4420
4296
|
if (!cad.connected) {
|
|
4421
4297
|
await cad.connect();
|
|
4422
4298
|
}
|
|
4423
|
-
if (!cad.connected)
|
|
4424
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4299
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4425
4300
|
const code = `(progn
|
|
4426
4301
|
(vl-load-com)
|
|
4427
4302
|
(command "._BHATCH" "p" "${escapeLispString(patternName)}" "s" "s" "sc" ${scale} "an" ${angle} "")
|
|
@@ -4441,17 +4316,12 @@ async function setHatchProperties(handle, props) {
|
|
|
4441
4316
|
if (!cad.connected) {
|
|
4442
4317
|
await cad.connect();
|
|
4443
4318
|
}
|
|
4444
|
-
if (!cad.connected)
|
|
4445
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4319
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4446
4320
|
let propCode = "";
|
|
4447
|
-
if (props.pattern)
|
|
4448
|
-
|
|
4449
|
-
if (props.
|
|
4450
|
-
|
|
4451
|
-
if (props.angle)
|
|
4452
|
-
propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "an" ${parseFloat(props.angle) || 0})`;
|
|
4453
|
-
if (props.color)
|
|
4454
|
-
propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "c" ${parseInt(props.color) || 256})`;
|
|
4321
|
+
if (props.pattern) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "p" "${escapeLispString(props.pattern)}")`;
|
|
4322
|
+
if (props.scale) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "s" ${parseFloat(props.scale) || 1})`;
|
|
4323
|
+
if (props.angle) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "an" ${parseFloat(props.angle) || 0})`;
|
|
4324
|
+
if (props.color) propCode += `(command "._HATCHEDIT" "${escapeLispString(handle)}" "c" ${parseInt(props.color) || 256})`;
|
|
4455
4325
|
const code = `(progn
|
|
4456
4326
|
(vl-load-com)
|
|
4457
4327
|
${propCode}
|
|
@@ -4468,8 +4338,7 @@ async function getBlockAttributes(blockHandle) {
|
|
|
4468
4338
|
if (!cad.connected) {
|
|
4469
4339
|
await cad.connect();
|
|
4470
4340
|
}
|
|
4471
|
-
if (!cad.connected)
|
|
4472
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4341
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4473
4342
|
const code = `(progn
|
|
4474
4343
|
(vl-load-com)
|
|
4475
4344
|
(if (setq ent (handent "${escapeLispString(blockHandle)}"))
|
|
@@ -4498,8 +4367,7 @@ async function setBlockAttribute(blockHandle, tag, value) {
|
|
|
4498
4367
|
if (!cad.connected) {
|
|
4499
4368
|
await cad.connect();
|
|
4500
4369
|
}
|
|
4501
|
-
if (!cad.connected)
|
|
4502
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4370
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4503
4371
|
const code = `(progn
|
|
4504
4372
|
(vl-load-com)
|
|
4505
4373
|
(if (setq ent (handent "${escapeLispString(blockHandle)}"))
|
|
@@ -4535,8 +4403,7 @@ async function zoomToExtents() {
|
|
|
4535
4403
|
if (!cad.connected) {
|
|
4536
4404
|
await cad.connect();
|
|
4537
4405
|
}
|
|
4538
|
-
if (!cad.connected)
|
|
4539
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4406
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4540
4407
|
const code = `(progn
|
|
4541
4408
|
(vl-load-com)
|
|
4542
4409
|
(command "._ZOOM" "E")
|
|
@@ -4553,8 +4420,7 @@ async function zoomToWindow(p1, p2) {
|
|
|
4553
4420
|
if (!cad.connected) {
|
|
4554
4421
|
await cad.connect();
|
|
4555
4422
|
}
|
|
4556
|
-
if (!cad.connected)
|
|
4557
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4423
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4558
4424
|
const code = `(command "._ZOOM" "W" (list ${toSafePoint(p1)}) (list ${toSafePoint(p2)}))`;
|
|
4559
4425
|
try {
|
|
4560
4426
|
await cad.sendCommand(code + "\n");
|
|
@@ -4567,8 +4433,7 @@ async function createNamedView(viewName, center = null) {
|
|
|
4567
4433
|
if (!cad.connected) {
|
|
4568
4434
|
await cad.connect();
|
|
4569
4435
|
}
|
|
4570
|
-
if (!cad.connected)
|
|
4571
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4436
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4572
4437
|
const code = center ? `(command ".-VIEW" "S" "${escapeLispString(viewName)}" "C" (list ${toSafePoint(center)}))` : `(command ".-VIEW" "S" "${escapeLispString(viewName)}")`;
|
|
4573
4438
|
try {
|
|
4574
4439
|
await cad.sendCommand(code + "\n");
|
|
@@ -4581,8 +4446,7 @@ async function restoreNamedView(viewName) {
|
|
|
4581
4446
|
if (!cad.connected) {
|
|
4582
4447
|
await cad.connect();
|
|
4583
4448
|
}
|
|
4584
|
-
if (!cad.connected)
|
|
4585
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4449
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4586
4450
|
const code = `(command ".-VIEW" "R" "${escapeLispString(viewName)}")`;
|
|
4587
4451
|
try {
|
|
4588
4452
|
await cad.sendCommand(code + "\n");
|
|
@@ -4595,8 +4459,7 @@ async function listNamedViews() {
|
|
|
4595
4459
|
if (!cad.connected) {
|
|
4596
4460
|
await cad.connect();
|
|
4597
4461
|
}
|
|
4598
|
-
if (!cad.connected)
|
|
4599
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4462
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4600
4463
|
const code = `(progn
|
|
4601
4464
|
(vl-load-com)
|
|
4602
4465
|
(setq views nil)
|
|
@@ -4616,8 +4479,7 @@ async function exportDxf(outputPath, version2 = "R2018") {
|
|
|
4616
4479
|
if (!cad.connected) {
|
|
4617
4480
|
await cad.connect();
|
|
4618
4481
|
}
|
|
4619
|
-
if (!cad.connected)
|
|
4620
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4482
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4621
4483
|
const versionMap = {
|
|
4622
4484
|
"R2018": "AC1027",
|
|
4623
4485
|
"R2015": "AC1024",
|
|
@@ -4647,8 +4509,7 @@ async function exportDwf(outputPath) {
|
|
|
4647
4509
|
if (!cad.connected) {
|
|
4648
4510
|
await cad.connect();
|
|
4649
4511
|
}
|
|
4650
|
-
if (!cad.connected)
|
|
4651
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4512
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4652
4513
|
const code = `(progn
|
|
4653
4514
|
(vl-load-com)
|
|
4654
4515
|
(vla-export (vla-get-activedocument (vlax-get-acad-object)) "${escapeLispString(outputPath)}" "dwf")
|
|
@@ -4668,8 +4529,7 @@ async function batchSetLayer(handles, layerName) {
|
|
|
4668
4529
|
if (!cad.connected) {
|
|
4669
4530
|
await cad.connect();
|
|
4670
4531
|
}
|
|
4671
|
-
if (!cad.connected)
|
|
4672
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4532
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4673
4533
|
if (!Array.isArray(handles) || handles.length === 0) {
|
|
4674
4534
|
return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
|
|
4675
4535
|
}
|
|
@@ -4699,8 +4559,7 @@ async function createUcs(name, origin = "0,0,0", xAxis = "1,0,0", yAxis = "0,1,0
|
|
|
4699
4559
|
if (!cad.connected) {
|
|
4700
4560
|
await cad.connect();
|
|
4701
4561
|
}
|
|
4702
|
-
if (!cad.connected)
|
|
4703
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4562
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4704
4563
|
const code = `(progn
|
|
4705
4564
|
(vl-load-com)
|
|
4706
4565
|
(if (not (tblsearch "UCS" "${escapeLispString(name)}"))
|
|
@@ -4731,8 +4590,7 @@ async function setUcs(name) {
|
|
|
4731
4590
|
if (!cad.connected) {
|
|
4732
4591
|
await cad.connect();
|
|
4733
4592
|
}
|
|
4734
|
-
if (!cad.connected)
|
|
4735
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4593
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4736
4594
|
const code = `(progn
|
|
4737
4595
|
(vl-load-com)
|
|
4738
4596
|
(if (tblsearch "UCS" "${escapeLispString(name)}")
|
|
@@ -4757,8 +4615,7 @@ async function listUcs() {
|
|
|
4757
4615
|
if (!cad.connected) {
|
|
4758
4616
|
await cad.connect();
|
|
4759
4617
|
}
|
|
4760
|
-
if (!cad.connected)
|
|
4761
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4618
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4762
4619
|
const code = `(progn
|
|
4763
4620
|
(vl-load-com)
|
|
4764
4621
|
(setq ucsList nil)
|
|
@@ -4781,8 +4638,7 @@ async function deleteUcs(name) {
|
|
|
4781
4638
|
if (!cad.connected) {
|
|
4782
4639
|
await cad.connect();
|
|
4783
4640
|
}
|
|
4784
|
-
if (!cad.connected)
|
|
4785
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4641
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4786
4642
|
const code = `(progn
|
|
4787
4643
|
(vl-load-com)
|
|
4788
4644
|
(if (tblsearch "UCS" "${escapeLispString(name)}")
|
|
@@ -4807,8 +4663,7 @@ async function getCurrentUcs() {
|
|
|
4807
4663
|
if (!cad.connected) {
|
|
4808
4664
|
await cad.connect();
|
|
4809
4665
|
}
|
|
4810
|
-
if (!cad.connected)
|
|
4811
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4666
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4812
4667
|
const code = `(progn
|
|
4813
4668
|
(vl-load-com)
|
|
4814
4669
|
(vla-get-activeutilities (vla-get-document (vla-get-application (vlax-get-acad-object))))
|
|
@@ -4825,8 +4680,7 @@ async function createLayout(name) {
|
|
|
4825
4680
|
if (!cad.connected) {
|
|
4826
4681
|
await cad.connect();
|
|
4827
4682
|
}
|
|
4828
|
-
if (!cad.connected)
|
|
4829
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4683
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4830
4684
|
const code = `(progn
|
|
4831
4685
|
(vl-load-com)
|
|
4832
4686
|
(if (not (tblsearch "LAYOUT" "${escapeLispString(name)}"))
|
|
@@ -4854,8 +4708,7 @@ async function setLayout(name) {
|
|
|
4854
4708
|
if (!cad.connected) {
|
|
4855
4709
|
await cad.connect();
|
|
4856
4710
|
}
|
|
4857
|
-
if (!cad.connected)
|
|
4858
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4711
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4859
4712
|
const code = `(progn
|
|
4860
4713
|
(vl-load-com)
|
|
4861
4714
|
(vlax-for layout (vla-get-layouts (vla-get-activedocument (vla-get-application (vlax-get-acad-object))))
|
|
@@ -4885,8 +4738,7 @@ async function listLayouts() {
|
|
|
4885
4738
|
if (!cad.connected) {
|
|
4886
4739
|
await cad.connect();
|
|
4887
4740
|
}
|
|
4888
|
-
if (!cad.connected)
|
|
4889
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4741
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4890
4742
|
const code = `(progn
|
|
4891
4743
|
(vl-load-com)
|
|
4892
4744
|
(setq layouts nil)
|
|
@@ -4909,8 +4761,7 @@ async function deleteLayout(name) {
|
|
|
4909
4761
|
if (!cad.connected) {
|
|
4910
4762
|
await cad.connect();
|
|
4911
4763
|
}
|
|
4912
|
-
if (!cad.connected)
|
|
4913
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4764
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4914
4765
|
if (name === "Model" || name === "\u6A21\u578B") {
|
|
4915
4766
|
return { content: [{ type: "text", text: "\u65E0\u6CD5\u5220\u9664\u6A21\u578B\u7A7A\u95F4" }], isError: true };
|
|
4916
4767
|
}
|
|
@@ -4938,8 +4789,7 @@ async function getCurrentLayout() {
|
|
|
4938
4789
|
if (!cad.connected) {
|
|
4939
4790
|
await cad.connect();
|
|
4940
4791
|
}
|
|
4941
|
-
if (!cad.connected)
|
|
4942
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4792
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4943
4793
|
const code = `(vl-prin1-to-string (getvar "CTAB"))`;
|
|
4944
4794
|
try {
|
|
4945
4795
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -4952,8 +4802,7 @@ async function renameLayout(oldName, newName) {
|
|
|
4952
4802
|
if (!cad.connected) {
|
|
4953
4803
|
await cad.connect();
|
|
4954
4804
|
}
|
|
4955
|
-
if (!cad.connected)
|
|
4956
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4805
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4957
4806
|
const code = `(progn
|
|
4958
4807
|
(vl-load-com)
|
|
4959
4808
|
(if (tblsearch "LAYOUT" "${escapeLispString(oldName)}")
|
|
@@ -4985,8 +4834,7 @@ async function plotToPdf(outputPath, layout = "Model", style = {}) {
|
|
|
4985
4834
|
if (!cad.connected) {
|
|
4986
4835
|
await cad.connect();
|
|
4987
4836
|
}
|
|
4988
|
-
if (!cad.connected)
|
|
4989
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4837
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4990
4838
|
const paperSize = style.paperSize || "A4";
|
|
4991
4839
|
const code = `(progn
|
|
4992
4840
|
(vl-load-com)
|
|
@@ -5016,8 +4864,7 @@ async function plotToPrinter(printerName, layout = "Model") {
|
|
|
5016
4864
|
if (!cad.connected) {
|
|
5017
4865
|
await cad.connect();
|
|
5018
4866
|
}
|
|
5019
|
-
if (!cad.connected)
|
|
5020
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4867
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5021
4868
|
const code = `(progn
|
|
5022
4869
|
(vl-load-com)
|
|
5023
4870
|
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
|
|
@@ -5043,8 +4890,7 @@ async function createGroup(name, handles) {
|
|
|
5043
4890
|
if (!cad.connected) {
|
|
5044
4891
|
await cad.connect();
|
|
5045
4892
|
}
|
|
5046
|
-
if (!cad.connected)
|
|
5047
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4893
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5048
4894
|
if (!Array.isArray(handles) || handles.length === 0) {
|
|
5049
4895
|
return { content: [{ type: "text", text: "\u53E5\u67C4\u5217\u8868\u4E3A\u7A7A" }], isError: true };
|
|
5050
4896
|
}
|
|
@@ -5070,8 +4916,7 @@ async function deleteGroup(name) {
|
|
|
5070
4916
|
if (!cad.connected) {
|
|
5071
4917
|
await cad.connect();
|
|
5072
4918
|
}
|
|
5073
|
-
if (!cad.connected)
|
|
5074
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4919
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5075
4920
|
const code = `(progn
|
|
5076
4921
|
(vl-load-com)
|
|
5077
4922
|
(if (tblsearch "GROUP" "${escapeLispString(name)}")
|
|
@@ -5096,8 +4941,7 @@ async function listGroups() {
|
|
|
5096
4941
|
if (!cad.connected) {
|
|
5097
4942
|
await cad.connect();
|
|
5098
4943
|
}
|
|
5099
|
-
if (!cad.connected)
|
|
5100
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4944
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5101
4945
|
const code = `(progn
|
|
5102
4946
|
(vl-load-com)
|
|
5103
4947
|
(setq groups nil)
|
|
@@ -5117,8 +4961,7 @@ async function getGroupEntities(groupName) {
|
|
|
5117
4961
|
if (!cad.connected) {
|
|
5118
4962
|
await cad.connect();
|
|
5119
4963
|
}
|
|
5120
|
-
if (!cad.connected)
|
|
5121
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
4964
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5122
4965
|
const code = `(progn
|
|
5123
4966
|
(vl-load-com)
|
|
5124
4967
|
(if (tblsearch "GROUP" "${escapeLispString(groupName)}")
|
|
@@ -5156,8 +4999,7 @@ async function measureDistance(p1, p2) {
|
|
|
5156
4999
|
if (!cad.connected) {
|
|
5157
5000
|
await cad.connect();
|
|
5158
5001
|
}
|
|
5159
|
-
if (!cad.connected)
|
|
5160
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5002
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5161
5003
|
const code = `(progn
|
|
5162
5004
|
(vl-load-com)
|
|
5163
5005
|
(setq pt1 (list ${toSafePoint3(p1)}) pt2 (list ${toSafePoint3(p2)}))
|
|
@@ -5181,8 +5023,7 @@ async function measureArea(points) {
|
|
|
5181
5023
|
if (!cad.connected) {
|
|
5182
5024
|
await cad.connect();
|
|
5183
5025
|
}
|
|
5184
|
-
if (!cad.connected)
|
|
5185
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5026
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5186
5027
|
const pts = Array.isArray(points) ? points : points.split(/[\s,]+/).filter(Boolean);
|
|
5187
5028
|
if (pts.length < 3) {
|
|
5188
5029
|
return { content: [{ type: "text", text: "\u81F3\u5C11\u9700\u8981 3 \u4E2A\u70B9" }], isError: true };
|
|
@@ -5219,8 +5060,7 @@ async function getEntityInfo(handle) {
|
|
|
5219
5060
|
if (!cad.connected) {
|
|
5220
5061
|
await cad.connect();
|
|
5221
5062
|
}
|
|
5222
|
-
if (!cad.connected)
|
|
5223
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5063
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
5224
5064
|
const code = `(progn
|
|
5225
5065
|
(vl-load-com)
|
|
5226
5066
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -5260,8 +5100,7 @@ function parseHandleList(handles) {
|
|
|
5260
5100
|
handles = handles.split(",").map((h) => h.trim());
|
|
5261
5101
|
}
|
|
5262
5102
|
}
|
|
5263
|
-
if (!Array.isArray(handles))
|
|
5264
|
-
handles = [handles];
|
|
5103
|
+
if (!Array.isArray(handles)) handles = [handles];
|
|
5265
5104
|
return handles;
|
|
5266
5105
|
}
|
|
5267
5106
|
async function batchRename(handles, newNameTemplate, startNum = 1) {
|
|
@@ -5635,8 +5474,7 @@ async function copyXdata(sourceHandle, targetHandle, appName = null) {
|
|
|
5635
5474
|
const xdataResult = await getXdata(sourceHandle, appName);
|
|
5636
5475
|
if (xdataResult.content?.[0]) {
|
|
5637
5476
|
const parsed = JSON.parse(xdataResult.content[0].text);
|
|
5638
|
-
if (parsed.xdata)
|
|
5639
|
-
return await setXdata(targetHandle, appName, parsed.xdata);
|
|
5477
|
+
if (parsed.xdata) return await setXdata(targetHandle, appName, parsed.xdata);
|
|
5640
5478
|
}
|
|
5641
5479
|
return mcpError("\u6E90\u5B9E\u4F53\u672A\u627E\u5230\u6269\u5C55\u6570\u636E");
|
|
5642
5480
|
} else {
|
|
@@ -5871,10 +5709,8 @@ async function createSheetSetArchive(sheetSetName, archivePath) {
|
|
|
5871
5709
|
// src/handlers/3d-handlers.js
|
|
5872
5710
|
init_cad();
|
|
5873
5711
|
function parsePoint(point) {
|
|
5874
|
-
if (Array.isArray(point))
|
|
5875
|
-
|
|
5876
|
-
if (typeof point === "string")
|
|
5877
|
-
return point;
|
|
5712
|
+
if (Array.isArray(point)) return point.join(" ");
|
|
5713
|
+
if (typeof point === "string") return point;
|
|
5878
5714
|
return "0,0,0";
|
|
5879
5715
|
}
|
|
5880
5716
|
async function createBox(center, length, width, height) {
|
|
@@ -8346,8 +8182,7 @@ function validateToolArgs(name, args) {
|
|
|
8346
8182
|
const baseType = type.replace("?", "");
|
|
8347
8183
|
const val = args[key];
|
|
8348
8184
|
if (val === void 0 || val === null) {
|
|
8349
|
-
if (isOptional)
|
|
8350
|
-
continue;
|
|
8185
|
+
if (isOptional) continue;
|
|
8351
8186
|
throw new Error(`Missing required argument: ${key}`);
|
|
8352
8187
|
}
|
|
8353
8188
|
const actualType = typeof args[key];
|
|
@@ -8392,8 +8227,7 @@ ${CAD_PLATFORMS.join("\n")}
|
|
|
8392
8227
|
},
|
|
8393
8228
|
import_funlib: async (a) => {
|
|
8394
8229
|
const data = await loadAtlibFunctionLib();
|
|
8395
|
-
if (!data)
|
|
8396
|
-
return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
|
|
8230
|
+
if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
|
|
8397
8231
|
if (a.format === "list") {
|
|
8398
8232
|
const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
|
|
8399
8233
|
return { content: [{ type: "text", text: items.join("\n") }] };
|
|
@@ -8603,8 +8437,7 @@ function notifyResourceChanges(toolName) {
|
|
|
8603
8437
|
}
|
|
8604
8438
|
async function handleToolCall(name, args) {
|
|
8605
8439
|
const handler = TOOL_HANDLERS[name];
|
|
8606
|
-
if (!handler)
|
|
8607
|
-
return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
|
|
8440
|
+
if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
|
|
8608
8441
|
try {
|
|
8609
8442
|
validateToolArgs(name, args || {});
|
|
8610
8443
|
const result = await handler(args || {});
|
|
@@ -8665,12 +8498,10 @@ var RateLimiter = class {
|
|
|
8665
8498
|
this.keyLimits = /* @__PURE__ */ new Map();
|
|
8666
8499
|
}
|
|
8667
8500
|
getKeyLimit(apiKey2) {
|
|
8668
|
-
if (!apiKey2)
|
|
8669
|
-
return this.defaultLimit;
|
|
8501
|
+
if (!apiKey2) return this.defaultLimit;
|
|
8670
8502
|
if (config_default.apiKeys && config_default.apiKeys.length > 0) {
|
|
8671
8503
|
const found = config_default.apiKeys.find((k) => k.key === apiKey2);
|
|
8672
|
-
if (found)
|
|
8673
|
-
return found.limit;
|
|
8504
|
+
if (found) return found.limit;
|
|
8674
8505
|
}
|
|
8675
8506
|
if (config_default.apiKey && apiKey2 === config_default.apiKey) {
|
|
8676
8507
|
return config_default.apiKeyRateLimit || 1e3;
|
|
@@ -8678,12 +8509,10 @@ var RateLimiter = class {
|
|
|
8678
8509
|
return this.defaultLimit;
|
|
8679
8510
|
}
|
|
8680
8511
|
getKeyInfo(apiKey2) {
|
|
8681
|
-
if (!apiKey2)
|
|
8682
|
-
return { name: "anonymous", limit: this.defaultLimit };
|
|
8512
|
+
if (!apiKey2) return { name: "anonymous", limit: this.defaultLimit };
|
|
8683
8513
|
if (config_default.apiKeys && config_default.apiKeys.length > 0) {
|
|
8684
8514
|
const found = config_default.apiKeys.find((k) => k.key === apiKey2);
|
|
8685
|
-
if (found)
|
|
8686
|
-
return { name: found.name || apiKey2, limit: found.limit };
|
|
8515
|
+
if (found) return { name: found.name || apiKey2, limit: found.limit };
|
|
8687
8516
|
}
|
|
8688
8517
|
if (config_default.apiKey && apiKey2 === config_default.apiKey) {
|
|
8689
8518
|
return { name: "admin", limit: config_default.apiKeyRateLimit || 1e3 };
|
|
@@ -8779,8 +8608,7 @@ var JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "applicati
|
|
|
8779
8608
|
function createJsonBodyParser() {
|
|
8780
8609
|
return async (req, res, next) => {
|
|
8781
8610
|
const ct = (req.headers["content-type"] || "").toLowerCase();
|
|
8782
|
-
if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
|
|
8783
|
-
return next();
|
|
8611
|
+
if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
|
|
8784
8612
|
try {
|
|
8785
8613
|
const chunks = [];
|
|
8786
8614
|
for await (const chunk of req) {
|
|
@@ -8813,11 +8641,9 @@ function createAuthMiddleware() {
|
|
|
8813
8641
|
const PUBLIC_PATHS = ["/health"];
|
|
8814
8642
|
return (req, res, next) => {
|
|
8815
8643
|
if (apiKey) {
|
|
8816
|
-
if (PUBLIC_PATHS.includes(req.path))
|
|
8817
|
-
return next();
|
|
8644
|
+
if (PUBLIC_PATHS.includes(req.path)) return next();
|
|
8818
8645
|
const auth = req.get("Authorization");
|
|
8819
|
-
if (auth === `Bearer ${apiKey}`)
|
|
8820
|
-
return next();
|
|
8646
|
+
if (auth === `Bearer ${apiKey}`) return next();
|
|
8821
8647
|
return res.status(401).json({ error: "Unauthorized" });
|
|
8822
8648
|
}
|
|
8823
8649
|
next();
|
|
@@ -8825,16 +8651,14 @@ function createAuthMiddleware() {
|
|
|
8825
8651
|
}
|
|
8826
8652
|
function createCorsMiddleware() {
|
|
8827
8653
|
return (req, res, next) => {
|
|
8828
|
-
if (!enableCors)
|
|
8829
|
-
return next();
|
|
8654
|
+
if (!enableCors) return next();
|
|
8830
8655
|
res.setHeader("Access-Control-Allow-Origin", corsOrigin);
|
|
8831
8656
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, CONNECT");
|
|
8832
8657
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, mcp-session-id, last-event-id");
|
|
8833
8658
|
res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
|
|
8834
8659
|
res.setHeader("Access-Control-Max-Age", "86400");
|
|
8835
8660
|
res.setHeader("Vary", "Accept");
|
|
8836
|
-
if (req.method === "OPTIONS")
|
|
8837
|
-
return res.status(204).end();
|
|
8661
|
+
if (req.method === "OPTIONS") return res.status(204).end();
|
|
8838
8662
|
next();
|
|
8839
8663
|
};
|
|
8840
8664
|
}
|
|
@@ -9251,8 +9075,7 @@ For more info: https://atlisp.cn
|
|
|
9251
9075
|
}
|
|
9252
9076
|
}
|
|
9253
9077
|
}
|
|
9254
|
-
if (config_default.apiKey)
|
|
9255
|
-
log("API Key authentication enabled");
|
|
9078
|
+
if (config_default.apiKey) log("API Key authentication enabled");
|
|
9256
9079
|
async function initCadConnection() {
|
|
9257
9080
|
log("Attempting to connect to CAD on startup...");
|
|
9258
9081
|
try {
|
|
@@ -9317,10 +9140,8 @@ async function startServer() {
|
|
|
9317
9140
|
await cad.disconnect();
|
|
9318
9141
|
closeLog();
|
|
9319
9142
|
httpServer.close(() => {
|
|
9320
|
-
if (httpsServer)
|
|
9321
|
-
|
|
9322
|
-
else
|
|
9323
|
-
process.exit(0);
|
|
9143
|
+
if (httpsServer) httpsServer.close(() => process.exit(0));
|
|
9144
|
+
else process.exit(0);
|
|
9324
9145
|
});
|
|
9325
9146
|
setTimeout(() => process.exit(1), 5e3);
|
|
9326
9147
|
}
|
|
@@ -9328,6 +9149,22 @@ async function startServer() {
|
|
|
9328
9149
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
9329
9150
|
}
|
|
9330
9151
|
}
|
|
9152
|
+
onDocumentChanged((info) => {
|
|
9153
|
+
const uris = [
|
|
9154
|
+
"atlisp://dwg/name",
|
|
9155
|
+
"atlisp://dwg/path",
|
|
9156
|
+
"atlisp://cad/dwgs",
|
|
9157
|
+
"atlisp://dwg/tbl",
|
|
9158
|
+
"atlisp://dwg/entities",
|
|
9159
|
+
"atlisp://dwg/block-refs",
|
|
9160
|
+
"atlisp://dwg/text-content",
|
|
9161
|
+
"atlisp://dwg/groups"
|
|
9162
|
+
];
|
|
9163
|
+
for (const uri of uris) {
|
|
9164
|
+
clearCache(uri);
|
|
9165
|
+
notify(uri, { docName: info.docName, docPath: info.docPath });
|
|
9166
|
+
}
|
|
9167
|
+
});
|
|
9331
9168
|
if (!process.env.VITEST) {
|
|
9332
9169
|
await startServer();
|
|
9333
9170
|
}
|