@atlisp/mcp 1.4.4 → 1.5.0
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 +167 -258
- package/package.json +1 -1
package/dist/atlisp-mcp.js
CHANGED
|
@@ -36,8 +36,7 @@ var SessionTransport = class {
|
|
|
36
36
|
this._started = true;
|
|
37
37
|
}
|
|
38
38
|
async send(message) {
|
|
39
|
-
if (this._closed)
|
|
40
|
-
return;
|
|
39
|
+
if (this._closed) return;
|
|
41
40
|
if (this._pendingRequest) {
|
|
42
41
|
const { resolve, reject, timeout } = this._pendingRequest;
|
|
43
42
|
clearTimeout(timeout);
|
|
@@ -46,8 +45,7 @@ var SessionTransport = class {
|
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
async close() {
|
|
49
|
-
if (this._closed)
|
|
50
|
-
return;
|
|
48
|
+
if (this._closed) return;
|
|
51
49
|
this._closed = true;
|
|
52
50
|
if (this._pendingRequest) {
|
|
53
51
|
const { reject, timeout } = this._pendingRequest;
|
|
@@ -121,7 +119,7 @@ var FILE_EXTENSIONS = {
|
|
|
121
119
|
"BricsCAD": [".des"]
|
|
122
120
|
};
|
|
123
121
|
var SERVER_NAME = "atlisp-mcp-server";
|
|
124
|
-
var SERVER_VERSION = "1.
|
|
122
|
+
var SERVER_VERSION = "1.5.0";
|
|
125
123
|
var MOCK_PACKAGES = [
|
|
126
124
|
{ name: "base", description: "\u57FA\u7840\u51FD\u6570\u5E93", version: "1.0.0" },
|
|
127
125
|
{ name: "at-pm", description: "\u5DE5\u7A0B\u9879\u76EE\u7BA1\u7406", version: "2.1.0" },
|
|
@@ -239,8 +237,7 @@ function setupStdoutHandler(w) {
|
|
|
239
237
|
const lines = buffer.split("\n");
|
|
240
238
|
buffer = lines.pop() || "";
|
|
241
239
|
for (const line of lines) {
|
|
242
|
-
if (!line.trim())
|
|
243
|
-
continue;
|
|
240
|
+
if (!line.trim()) continue;
|
|
244
241
|
try {
|
|
245
242
|
const result = JSON.parse(line);
|
|
246
243
|
const rid = result.requestId;
|
|
@@ -266,8 +263,7 @@ function setupStdoutHandler(w) {
|
|
|
266
263
|
}
|
|
267
264
|
function getWorker(force = false) {
|
|
268
265
|
if (!worker || !worker.connected || force) {
|
|
269
|
-
if (worker)
|
|
270
|
-
worker.kill();
|
|
266
|
+
if (worker) worker.kill();
|
|
271
267
|
worker = spawn("node", [workerPath], {
|
|
272
268
|
stdio: ["pipe", "pipe", "pipe"]
|
|
273
269
|
});
|
|
@@ -275,8 +271,7 @@ function getWorker(force = false) {
|
|
|
275
271
|
const w = worker;
|
|
276
272
|
w.on("exit", (code) => {
|
|
277
273
|
console.error("worker exited with code:", code);
|
|
278
|
-
if (w !== worker)
|
|
279
|
-
return;
|
|
274
|
+
if (w !== worker) return;
|
|
280
275
|
w.connected = false;
|
|
281
276
|
for (const [id, { reject, timeout }] of pendingRequests) {
|
|
282
277
|
clearTimeout(timeout);
|
|
@@ -297,8 +292,7 @@ function getWorker(force = false) {
|
|
|
297
292
|
return worker;
|
|
298
293
|
}
|
|
299
294
|
function startHeartbeat() {
|
|
300
|
-
if (heartbeatTimer)
|
|
301
|
-
clearInterval(heartbeatTimer);
|
|
295
|
+
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
302
296
|
heartbeatTimer = setInterval(async () => {
|
|
303
297
|
try {
|
|
304
298
|
const result = await sendMessage({ type: "ping" });
|
|
@@ -343,8 +337,7 @@ var CadConnection = class {
|
|
|
343
337
|
return process.platform === "win32";
|
|
344
338
|
}
|
|
345
339
|
async connect(platform = null) {
|
|
346
|
-
if (!this.isAvailable())
|
|
347
|
-
return false;
|
|
340
|
+
if (!this.isAvailable()) return false;
|
|
348
341
|
try {
|
|
349
342
|
const msg = platform ? { type: "connect", platform } : { type: "connect" };
|
|
350
343
|
const result = await sendMessage(msg);
|
|
@@ -361,16 +354,13 @@ var CadConnection = class {
|
|
|
361
354
|
return false;
|
|
362
355
|
}
|
|
363
356
|
async sendCommand(code) {
|
|
364
|
-
if (!this.connected)
|
|
365
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
357
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
366
358
|
const result = await sendMessage({ type: "send", code, platform: _platform });
|
|
367
|
-
if (result.success)
|
|
368
|
-
return true;
|
|
359
|
+
if (result.success) return true;
|
|
369
360
|
throw new Error(result.error || "\u53D1\u9001\u5931\u8D25");
|
|
370
361
|
}
|
|
371
362
|
async sendCommandWithResult(code, encoding = null) {
|
|
372
|
-
if (!this.connected)
|
|
373
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
363
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
374
364
|
const result = await sendMessage({ type: "sendResult", code, platform: _platform, encoding: encoding || "" });
|
|
375
365
|
if (result.success) {
|
|
376
366
|
return result.result || "";
|
|
@@ -384,8 +374,7 @@ var CadConnection = class {
|
|
|
384
374
|
return this.product;
|
|
385
375
|
}
|
|
386
376
|
async isBusy() {
|
|
387
|
-
if (!this.connected)
|
|
388
|
-
return false;
|
|
377
|
+
if (!this.connected) return false;
|
|
389
378
|
try {
|
|
390
379
|
const result = await sendMessage({ type: "isBusy", platform: _platform });
|
|
391
380
|
return result && result.isBusy;
|
|
@@ -394,8 +383,7 @@ var CadConnection = class {
|
|
|
394
383
|
}
|
|
395
384
|
}
|
|
396
385
|
async hasDoc() {
|
|
397
|
-
if (!this.connected)
|
|
398
|
-
return { hasDoc: false, docCount: 0 };
|
|
386
|
+
if (!this.connected) return { hasDoc: false, docCount: 0 };
|
|
399
387
|
try {
|
|
400
388
|
const result = await sendMessage({ type: "hasdoc", platform: _platform });
|
|
401
389
|
return result || { hasDoc: false, docCount: 0 };
|
|
@@ -404,8 +392,7 @@ var CadConnection = class {
|
|
|
404
392
|
}
|
|
405
393
|
}
|
|
406
394
|
async newDoc() {
|
|
407
|
-
if (!this.connected)
|
|
408
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
395
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
409
396
|
try {
|
|
410
397
|
const result = await sendMessage({ type: "newdoc", platform: _platform });
|
|
411
398
|
return result && result.success;
|
|
@@ -414,8 +401,7 @@ var CadConnection = class {
|
|
|
414
401
|
}
|
|
415
402
|
}
|
|
416
403
|
async bringToFront() {
|
|
417
|
-
if (!this.connected)
|
|
418
|
-
throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
404
|
+
if (!this.connected) throw new Error("\u672A\u8FDE\u63A5 CAD");
|
|
419
405
|
try {
|
|
420
406
|
const result = await sendMessage({ type: "bringToFront", platform: _platform });
|
|
421
407
|
return result && result.success;
|
|
@@ -424,8 +410,7 @@ var CadConnection = class {
|
|
|
424
410
|
}
|
|
425
411
|
}
|
|
426
412
|
async getInfo() {
|
|
427
|
-
if (!this.connected)
|
|
428
|
-
return "CAD \u672A\u8FDE\u63A5";
|
|
413
|
+
if (!this.connected) return "CAD \u672A\u8FDE\u63A5";
|
|
429
414
|
return `Platform: ${this.product}, Version: ${this.version}, Status: Connected`;
|
|
430
415
|
}
|
|
431
416
|
async disconnect() {
|
|
@@ -462,11 +447,9 @@ var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
|
462
447
|
var MAX_LOG_FILES = 5;
|
|
463
448
|
var stream = null;
|
|
464
449
|
function rotateLog() {
|
|
465
|
-
if (!fs.existsSync(DEBUG_FILE))
|
|
466
|
-
return;
|
|
450
|
+
if (!fs.existsSync(DEBUG_FILE)) return;
|
|
467
451
|
const stat = fs.statSync(DEBUG_FILE);
|
|
468
|
-
if (stat.size < MAX_LOG_SIZE)
|
|
469
|
-
return;
|
|
452
|
+
if (stat.size < MAX_LOG_SIZE) return;
|
|
470
453
|
if (stream) {
|
|
471
454
|
stream.end();
|
|
472
455
|
stream = null;
|
|
@@ -528,8 +511,7 @@ async function evalLisp(code, withResult = false, encoding = null) {
|
|
|
528
511
|
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
529
512
|
}
|
|
530
513
|
const trimmed = (code || "").trim();
|
|
531
|
-
if (!trimmed)
|
|
532
|
-
return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
514
|
+
if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
533
515
|
try {
|
|
534
516
|
if (withResult) {
|
|
535
517
|
const result = await cad.sendCommandWithResult(trimmed, encoding);
|
|
@@ -549,17 +531,14 @@ async function getCadInfo() {
|
|
|
549
531
|
if (!cad.connected) {
|
|
550
532
|
await cad.connect();
|
|
551
533
|
}
|
|
552
|
-
if (!cad.connected)
|
|
553
|
-
return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
|
|
534
|
+
if (!cad.connected) return { content: [{ type: "text", text: "CAD \u672A\u8FDE\u63A5" }] };
|
|
554
535
|
const info = await cad.getInfo();
|
|
555
536
|
return { content: [{ type: "text", text: info }] };
|
|
556
537
|
}
|
|
557
538
|
async function atCommand(command) {
|
|
558
|
-
if (!cad.connected)
|
|
559
|
-
return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
|
|
539
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u8BF7\u5148\u8FDE\u63A5 CAD" }], isError: true };
|
|
560
540
|
const trimmed = (command || "").trim();
|
|
561
|
-
if (!trimmed)
|
|
562
|
-
return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
541
|
+
if (!trimmed) return { content: [{ type: "text", text: "\u547D\u4EE4\u4E3A\u7A7A\uFF0C\u672A\u53D1\u9001" }] };
|
|
563
542
|
await cad.sendCommand(trimmed + "\n");
|
|
564
543
|
return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001\u547D\u4EE4" }] };
|
|
565
544
|
}
|
|
@@ -567,8 +546,7 @@ async function newDocument() {
|
|
|
567
546
|
if (!cad.connected) {
|
|
568
547
|
await cad.connect();
|
|
569
548
|
}
|
|
570
|
-
if (!cad.connected)
|
|
571
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
549
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
572
550
|
const result = await cad.newDoc();
|
|
573
551
|
if (result) {
|
|
574
552
|
return { content: [{ type: "text", text: "\u5DF2\u5728 CAD \u4E2D\u65B0\u5EFA\u7A7A\u767D\u6587\u6863" }] };
|
|
@@ -579,8 +557,7 @@ async function bringToFront() {
|
|
|
579
557
|
if (!cad.connected) {
|
|
580
558
|
await cad.connect();
|
|
581
559
|
}
|
|
582
|
-
if (!cad.connected)
|
|
583
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
560
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
584
561
|
const result = await cad.bringToFront();
|
|
585
562
|
if (result) {
|
|
586
563
|
return { content: [{ type: "text", text: "\u5DF2\u5C06 CAD \u7A97\u53E3\u5207\u6362\u5230\u524D\u53F0" }] };
|
|
@@ -591,8 +568,7 @@ async function installAtlisp() {
|
|
|
591
568
|
if (!cad.connected) {
|
|
592
569
|
await cad.connect();
|
|
593
570
|
}
|
|
594
|
-
if (!cad.connected)
|
|
595
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
571
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
596
572
|
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))))`;
|
|
597
573
|
await cad.sendCommand(installCode + "\n");
|
|
598
574
|
return { content: [{ type: "text", text: "\u5DF2\u53D1\u9001 @lisp \u5B89\u88C5\u4EE3\u7801\u5230 CAD" }] };
|
|
@@ -601,12 +577,10 @@ async function listFunctionsInCad() {
|
|
|
601
577
|
if (!cad.connected) {
|
|
602
578
|
await cad.connect();
|
|
603
579
|
}
|
|
604
|
-
if (!cad.connected)
|
|
605
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
580
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
606
581
|
try {
|
|
607
582
|
const result = await cad.sendCommandWithResult("(atoms-family 0)", null);
|
|
608
|
-
if (result)
|
|
609
|
-
return { content: [{ type: "text", text: result }] };
|
|
583
|
+
if (result) return { content: [{ type: "text", text: result }] };
|
|
610
584
|
return { content: [{ type: "text", text: "CAD \u51FD\u6570\u5217\u8868\u4E3A\u7A7A" }] };
|
|
611
585
|
} catch (e) {
|
|
612
586
|
return { content: [{ type: "text", text: `\u9519\u8BEF: ${e.message}` }], isError: true };
|
|
@@ -661,8 +635,7 @@ async function initAtlisp() {
|
|
|
661
635
|
if (!cad.connected) {
|
|
662
636
|
await cad.connect();
|
|
663
637
|
}
|
|
664
|
-
if (!cad.connected)
|
|
665
|
-
return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
638
|
+
if (!cad.connected) return { content: [{ type: "text", text: "\u672A\u8FDE\u63A5 CAD" }], isError: true };
|
|
666
639
|
const code = `(if (null @::load-module)
|
|
667
640
|
(progn
|
|
668
641
|
(vl-load-com)
|
|
@@ -702,15 +675,12 @@ async function fetchPackages() {
|
|
|
702
675
|
return cachedPackages || MOCK_PACKAGES;
|
|
703
676
|
}
|
|
704
677
|
function flattenPackages(data) {
|
|
705
|
-
if (Array.isArray(data))
|
|
706
|
-
|
|
707
|
-
if (data && Array.isArray(data.packages))
|
|
708
|
-
return data.packages;
|
|
678
|
+
if (Array.isArray(data)) return data;
|
|
679
|
+
if (data && Array.isArray(data.packages)) return data.packages;
|
|
709
680
|
return [];
|
|
710
681
|
}
|
|
711
682
|
async function listPackages() {
|
|
712
|
-
if (!cad.connected)
|
|
713
|
-
await cad.connect();
|
|
683
|
+
if (!cad.connected) await cad.connect();
|
|
714
684
|
if (!cad.connected) {
|
|
715
685
|
const data2 = await fetchPackages();
|
|
716
686
|
const items2 = flattenPackages(data2);
|
|
@@ -718,8 +688,7 @@ async function listPackages() {
|
|
|
718
688
|
return { content: [{ type: "text", text: text2 }] };
|
|
719
689
|
}
|
|
720
690
|
const result = await cad.sendCommandWithResult("(@::package-list-in-local)");
|
|
721
|
-
if (result && result !== "nil")
|
|
722
|
-
return { content: [{ type: "text", text: result }] };
|
|
691
|
+
if (result && result !== "nil") return { content: [{ type: "text", text: result }] };
|
|
723
692
|
const data = await fetchPackages();
|
|
724
693
|
const items = flattenPackages(data);
|
|
725
694
|
const text = items.length ? `\u4ECE\u6CE8\u518C\u8868\u83B7\u53D6\u7684 @lisp \u5305:
|
|
@@ -739,12 +708,10 @@ async function searchPackages(query) {
|
|
|
739
708
|
for (const p of items) {
|
|
740
709
|
const name = (p.name || "").toLowerCase();
|
|
741
710
|
const desc = (p.description || "").toLowerCase();
|
|
742
|
-
if (name.includes(q) || desc.includes(q))
|
|
743
|
-
results.push(p);
|
|
711
|
+
if (name.includes(q) || desc.includes(q)) results.push(p);
|
|
744
712
|
}
|
|
745
713
|
} else {
|
|
746
|
-
for (const p of items)
|
|
747
|
-
results.push(p);
|
|
714
|
+
for (const p of items) results.push(p);
|
|
748
715
|
}
|
|
749
716
|
if (results.length === 0) {
|
|
750
717
|
return { content: [{ type: "text", text: `\u672A\u627E\u5230\u5305\u542B "${query}" \u7684\u5305` }] };
|
|
@@ -796,8 +763,7 @@ function writeCacheToDisk(data) {
|
|
|
796
763
|
}
|
|
797
764
|
async function fetchFunctions() {
|
|
798
765
|
const diskCache = readCacheFromDisk();
|
|
799
|
-
if (diskCache)
|
|
800
|
-
return diskCache;
|
|
766
|
+
if (diskCache) return diskCache;
|
|
801
767
|
try {
|
|
802
768
|
const response = await fetch(FUNCTIONS_URL, { headers: { "User-Agent": "atlisp-mcp" } });
|
|
803
769
|
if (response.ok) {
|
|
@@ -817,8 +783,7 @@ async function getFunctionUsage(funcName, packageName) {
|
|
|
817
783
|
if (data) {
|
|
818
784
|
const funcs = Object.values(data.all_functions || {});
|
|
819
785
|
const func = funcs.find((f2) => f2.name === funcName || f2.name === `${packageName}:${funcName}`);
|
|
820
|
-
if (func)
|
|
821
|
-
results.push(func);
|
|
786
|
+
if (func) results.push(func);
|
|
822
787
|
}
|
|
823
788
|
if (results.length === 0 && FUNCTIONS_DIR) {
|
|
824
789
|
try {
|
|
@@ -827,8 +792,7 @@ async function getFunctionUsage(funcName, packageName) {
|
|
|
827
792
|
const raw = fs2.readFileSync(path3.join(FUNCTIONS_DIR, file), "utf-8");
|
|
828
793
|
const data2 = JSON.parse(raw);
|
|
829
794
|
const func = data2.functions?.find((f2) => f2.name === funcName);
|
|
830
|
-
if (func)
|
|
831
|
-
results.push(func);
|
|
795
|
+
if (func) results.push(func);
|
|
832
796
|
}
|
|
833
797
|
} catch {
|
|
834
798
|
}
|
|
@@ -922,14 +886,11 @@ function clearCache(uri) {
|
|
|
922
886
|
}
|
|
923
887
|
}
|
|
924
888
|
function parseLispList(str) {
|
|
925
|
-
if (!str || typeof str !== "string")
|
|
926
|
-
return null;
|
|
889
|
+
if (!str || typeof str !== "string") return null;
|
|
927
890
|
const trimmed = str.trim();
|
|
928
|
-
if (!trimmed.startsWith("(") || !trimmed.endsWith(")"))
|
|
929
|
-
return null;
|
|
891
|
+
if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) return null;
|
|
930
892
|
const content = trimmed.slice(1, -1).trim();
|
|
931
|
-
if (!content)
|
|
932
|
-
return [];
|
|
893
|
+
if (!content) return [];
|
|
933
894
|
const result = [];
|
|
934
895
|
let depth = 0;
|
|
935
896
|
let current = "";
|
|
@@ -971,44 +932,32 @@ function parseLispList(str) {
|
|
|
971
932
|
}
|
|
972
933
|
current += ch;
|
|
973
934
|
}
|
|
974
|
-
if (current.trim())
|
|
975
|
-
result.push(current.trim());
|
|
935
|
+
if (current.trim()) result.push(current.trim());
|
|
976
936
|
return result.map((item) => {
|
|
977
937
|
const t = item.trim();
|
|
978
|
-
if (t === "nil")
|
|
979
|
-
|
|
980
|
-
if (t === "
|
|
981
|
-
return true;
|
|
982
|
-
if (t === "T")
|
|
983
|
-
return true;
|
|
938
|
+
if (t === "nil") return null;
|
|
939
|
+
if (t === "t") return true;
|
|
940
|
+
if (t === "T") return true;
|
|
984
941
|
const num = Number(t);
|
|
985
|
-
if (!isNaN(num) && t !== "")
|
|
986
|
-
|
|
987
|
-
if (t.startsWith('"') && t.endsWith('"'))
|
|
988
|
-
return t.slice(1, -1);
|
|
942
|
+
if (!isNaN(num) && t !== "") return num;
|
|
943
|
+
if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
|
|
989
944
|
return t;
|
|
990
945
|
});
|
|
991
946
|
}
|
|
992
947
|
function parseLispRecursive(str) {
|
|
993
|
-
if (!str || typeof str !== "string")
|
|
994
|
-
return null;
|
|
948
|
+
if (!str || typeof str !== "string") return null;
|
|
995
949
|
str = str.trim();
|
|
996
|
-
if (!str)
|
|
997
|
-
return null;
|
|
950
|
+
if (!str) return null;
|
|
998
951
|
let pos = 0;
|
|
999
952
|
function skipWs() {
|
|
1000
|
-
while (pos < str.length && /\s/.test(str[pos]))
|
|
1001
|
-
pos++;
|
|
953
|
+
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
|
1002
954
|
}
|
|
1003
955
|
function parseValue() {
|
|
1004
956
|
skipWs();
|
|
1005
|
-
if (pos >= str.length)
|
|
1006
|
-
return null;
|
|
957
|
+
if (pos >= str.length) return null;
|
|
1007
958
|
const ch = str[pos];
|
|
1008
|
-
if (ch === "(")
|
|
1009
|
-
|
|
1010
|
-
if (ch === '"')
|
|
1011
|
-
return parseString();
|
|
959
|
+
if (ch === "(") return parseList();
|
|
960
|
+
if (ch === '"') return parseString();
|
|
1012
961
|
if (ch === "'") {
|
|
1013
962
|
pos++;
|
|
1014
963
|
return parseValue();
|
|
@@ -1021,16 +970,11 @@ function parseLispRecursive(str) {
|
|
|
1021
970
|
while (pos < str.length && str[pos] !== '"') {
|
|
1022
971
|
if (str[pos] === "\\" && pos + 1 < str.length) {
|
|
1023
972
|
pos++;
|
|
1024
|
-
if (str[pos] === '"')
|
|
1025
|
-
|
|
1026
|
-
else if (str[pos] === "
|
|
1027
|
-
|
|
1028
|
-
else
|
|
1029
|
-
r += " ";
|
|
1030
|
-
else if (str[pos] === "\\")
|
|
1031
|
-
r += "\\";
|
|
1032
|
-
else
|
|
1033
|
-
r += str[pos];
|
|
973
|
+
if (str[pos] === '"') r += '"';
|
|
974
|
+
else if (str[pos] === "n") r += "\n";
|
|
975
|
+
else if (str[pos] === "t") r += " ";
|
|
976
|
+
else if (str[pos] === "\\") r += "\\";
|
|
977
|
+
else r += str[pos];
|
|
1034
978
|
} else {
|
|
1035
979
|
r += str[pos];
|
|
1036
980
|
}
|
|
@@ -1041,16 +985,12 @@ function parseLispRecursive(str) {
|
|
|
1041
985
|
}
|
|
1042
986
|
function parseAtom() {
|
|
1043
987
|
const start = pos;
|
|
1044
|
-
while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(")
|
|
1045
|
-
pos++;
|
|
988
|
+
while (pos < str.length && !/\s/.test(str[pos]) && str[pos] !== ")" && str[pos] !== "(") pos++;
|
|
1046
989
|
const atom = str.slice(start, pos);
|
|
1047
|
-
if (atom === "nil" || atom === "NIL")
|
|
1048
|
-
|
|
1049
|
-
if (atom === "t" || atom === "T")
|
|
1050
|
-
return true;
|
|
990
|
+
if (atom === "nil" || atom === "NIL") return null;
|
|
991
|
+
if (atom === "t" || atom === "T") return true;
|
|
1051
992
|
const num = Number(atom);
|
|
1052
|
-
if (!isNaN(num) && atom !== "")
|
|
1053
|
-
return num;
|
|
993
|
+
if (!isNaN(num) && atom !== "") return num;
|
|
1054
994
|
return atom;
|
|
1055
995
|
}
|
|
1056
996
|
function parseList() {
|
|
@@ -1058,15 +998,13 @@ function parseLispRecursive(str) {
|
|
|
1058
998
|
const items = [];
|
|
1059
999
|
while (pos < str.length) {
|
|
1060
1000
|
skipWs();
|
|
1061
|
-
if (pos >= str.length)
|
|
1062
|
-
break;
|
|
1001
|
+
if (pos >= str.length) break;
|
|
1063
1002
|
if (str[pos] === ")") {
|
|
1064
1003
|
pos++;
|
|
1065
1004
|
return items;
|
|
1066
1005
|
}
|
|
1067
1006
|
const left = parseValue();
|
|
1068
|
-
if (left === void 0)
|
|
1069
|
-
break;
|
|
1007
|
+
if (left === void 0) break;
|
|
1070
1008
|
skipWs();
|
|
1071
1009
|
if (str[pos] === "." && (pos + 1 >= str.length || /\s/.test(str[pos + 1]) || str[pos + 1] === ")")) {
|
|
1072
1010
|
pos++;
|
|
@@ -1087,8 +1025,7 @@ function parseLispRecursive(str) {
|
|
|
1087
1025
|
return parseValue();
|
|
1088
1026
|
}
|
|
1089
1027
|
function lispPairsToObject(pairs) {
|
|
1090
|
-
if (!Array.isArray(pairs))
|
|
1091
|
-
return pairs;
|
|
1028
|
+
if (!Array.isArray(pairs)) return pairs;
|
|
1092
1029
|
const obj = {};
|
|
1093
1030
|
for (let i = 0; i < pairs.length - 1; i += 2) {
|
|
1094
1031
|
const key = pairs[i];
|
|
@@ -1100,17 +1037,35 @@ function lispPairsToObject(pairs) {
|
|
|
1100
1037
|
return obj;
|
|
1101
1038
|
}
|
|
1102
1039
|
function parseEntity(arr) {
|
|
1103
|
-
if (!Array.isArray(arr) || arr.length < 5)
|
|
1104
|
-
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1040
|
+
if (!Array.isArray(arr) || arr.length < 5) return null;
|
|
1041
|
+
const [type, handle, layer, color, linetype, ...rest] = arr;
|
|
1042
|
+
const entity = {
|
|
1043
|
+
type: String(type).toUpperCase().replace(/^"|"$/g, ""),
|
|
1044
|
+
handle: String(handle),
|
|
1045
|
+
layer: String(layer),
|
|
1046
|
+
color,
|
|
1047
|
+
linetype: String(linetype)
|
|
1048
|
+
};
|
|
1049
|
+
const entType = typeof entity.type === "string" ? entity.type.toUpperCase() : entity.type;
|
|
1050
|
+
if (/^(TEXT|MTEXT|ATTRIB|TCH_TEXT)$/.test(entType) && rest[0] != null) {
|
|
1051
|
+
entity.text = String(rest[0]);
|
|
1052
|
+
}
|
|
1053
|
+
if (/^(LINE|LWPOLYLINE|POLYLINE|ARC|CIRCLE|SPLINE|ELLIPSE|XLINE|RAY)$/.test(entType) && Array.isArray(rest[0])) {
|
|
1054
|
+
entity.points = rest[0].map((pt) => {
|
|
1055
|
+
if (Array.isArray(pt) && pt.length >= 2)
|
|
1056
|
+
return { x: Number(pt[0]), y: Number(pt[1]), z: Number(pt[2] || 0) };
|
|
1057
|
+
return null;
|
|
1058
|
+
}).filter(Boolean);
|
|
1059
|
+
}
|
|
1060
|
+
if (entType === "INSERT" && rest[0] != null) {
|
|
1061
|
+
entity.blockName = String(rest[0]);
|
|
1062
|
+
}
|
|
1063
|
+
return entity;
|
|
1107
1064
|
}
|
|
1108
1065
|
function buildEntityCode({ type, layer, bbox }) {
|
|
1109
1066
|
const items = [];
|
|
1110
|
-
if (type)
|
|
1111
|
-
|
|
1112
|
-
if (layer)
|
|
1113
|
-
items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
|
|
1067
|
+
if (type) items.push(`(cons 0 "${type.replace(/"/g, '\\"')}")`);
|
|
1068
|
+
if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
|
|
1114
1069
|
if (bbox) {
|
|
1115
1070
|
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
1116
1071
|
if (parts.length === 4) {
|
|
@@ -1127,21 +1082,32 @@ function buildEntityCode({ type, layer, bbox }) {
|
|
|
1127
1082
|
const ssgetExpr = items.length ? `(ssget "_X" ${filterExpr})` : '(ssget "_X")';
|
|
1128
1083
|
return `(progn
|
|
1129
1084
|
(vl-load-com)
|
|
1130
|
-
(defun @e:
|
|
1131
|
-
(setq
|
|
1132
|
-
(
|
|
1133
|
-
|
|
1134
|
-
|
|
1085
|
+
(defun @e:safe-fn (f ent / r)
|
|
1086
|
+
(setq r (vl-catch-all-apply f (list ent)))
|
|
1087
|
+
(if (vl-catch-all-error-p r) nil r))
|
|
1088
|
+
(defun @e:dp (ent / ed typ gcl is)
|
|
1089
|
+
(setq ed (entget ent) typ (cdr (assoc 0 ed)) gcl (assoc 62 ed) is (assoc 6 ed))
|
|
1090
|
+
(append
|
|
1091
|
+
(list typ (cdr (assoc 5 ed)) (cdr (assoc 8 ed))
|
|
1092
|
+
(if gcl (cdr gcl) 256)
|
|
1093
|
+
(if is (cdr is) "ByLayer"))
|
|
1094
|
+
(cond
|
|
1095
|
+
((wcmatch typ "TEXT,MTEXT,ATTRIB,TCH_TEXT")
|
|
1096
|
+
(list (@e:safe-fn '(lambda (e) (text:remove-fmt (text:get-mtext e))) ent)))
|
|
1097
|
+
((wcmatch typ "LINE,LWPOLYLINE,POLYLINE,ARC,CIRCLE,SPLINE,ELLIPSE,XLINE,RAY")
|
|
1098
|
+
(list (@e:safe-fn 'curve:get-points ent)))
|
|
1099
|
+
((= typ "INSERT")
|
|
1100
|
+
(list (@e:safe-fn 'block:get-effectivename ent)))
|
|
1101
|
+
(t nil))))
|
|
1135
1102
|
(setq @e:total (if (setq @e:ss ${ssgetExpr}) (sslength @e:ss) 0)
|
|
1136
1103
|
@e:ents nil @e:i 0)
|
|
1137
|
-
(while (and @e:ss (< @e:i @e:total)(< (length @e:ents)
|
|
1104
|
+
(while (and @e:ss (< @e:i @e:total)(< (length @e:ents) 3000))
|
|
1138
1105
|
(setq @e:ents (cons (@e:dp (ssname @e:ss @e:i)) @e:ents) @e:i (1+ @e:i)))
|
|
1139
1106
|
(vl-prin1-to-string (list @e:total (reverse @e:ents))))`;
|
|
1140
1107
|
}
|
|
1141
1108
|
function buildTextCode({ layer, bbox, offset, limit }) {
|
|
1142
1109
|
const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
|
|
1143
|
-
if (layer)
|
|
1144
|
-
items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
|
|
1110
|
+
if (layer) items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
|
|
1145
1111
|
if (bbox) {
|
|
1146
1112
|
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
1147
1113
|
if (parts.length === 4) {
|
|
@@ -1180,7 +1146,7 @@ function buildTextCode({ layer, bbox, offset, limit }) {
|
|
|
1180
1146
|
var RESOURCES = [
|
|
1181
1147
|
{ uri: "atlisp://cad/info", name: "CAD Info", description: "CAD \u8FDE\u63A5\u4FE1\u606F", mimeType: "application/json", subscribable: true },
|
|
1182
1148
|
{ uri: "atlisp://dwg/layers", name: "Layers", description: "\u56FE\u5C42\u5217\u8868", mimeType: "application/json", subscribable: true },
|
|
1183
|
-
{ uri: "atlisp://dwg/entities", name: "Entities", description: "\u56FE\u5143\u5217\u8868\uFF0C\u8FD4\u56DE\u603B\u6570\u548C\
|
|
1149
|
+
{ uri: "atlisp://dwg/entities", name: "Entities", description: "\u56FE\u5143\u5217\u8868\uFF0C\u8FD4\u56DE\u603B\u6570\u548C\u524D3000\u4E2A\u56FE\u5143\uFF0C\u6587\u672C\u9644\u52A0 text \u5B57\u6BB5\uFF0C\u66F2\u7EBF\u9644\u52A0 points \u6570\u7EC4\uFF0CINSERT \u9644\u52A0 blockName\uFF0C\u652F\u6301 ?type=LINE&layer=0&bbox=0,0,100,100 \u8FC7\u6EE4", mimeType: "application/json", subscribable: true },
|
|
1184
1150
|
{ uri: "atlisp://dwg/texts", name: "Texts", description: "\u6587\u672C\u5B9E\u4F53\u5185\u5BB9\u5217\u8868 (TEXT/MTEXT/ATTRIB/TCH_TEXT)\uFF0C\u652F\u6301 ?layer=0&bbox=0,0,100,100&limit=5000&offset=0", mimeType: "application/json", subscribable: true },
|
|
1185
1151
|
{ uri: "atlisp://dwg/name", name: "DWG Name", description: "\u5F53\u524D DWG \u6587\u4EF6\u540D", mimeType: "application/json", subscribable: true },
|
|
1186
1152
|
{ uri: "atlisp://dwg/path", name: "DWG Path", description: "\u6587\u4EF6\u5B8C\u6574\u8DEF\u5F84", mimeType: "application/json", subscribable: true },
|
|
@@ -1192,16 +1158,14 @@ var RESOURCES = [
|
|
|
1192
1158
|
];
|
|
1193
1159
|
function parseQuery(uri) {
|
|
1194
1160
|
const qIdx = uri.indexOf("?");
|
|
1195
|
-
if (qIdx === -1)
|
|
1196
|
-
return { base: uri, params: {} };
|
|
1161
|
+
if (qIdx === -1) return { base: uri, params: {} };
|
|
1197
1162
|
const base = uri.substring(0, qIdx);
|
|
1198
1163
|
const params = {};
|
|
1199
1164
|
uri.substring(qIdx + 1).split("&").forEach((p) => {
|
|
1200
1165
|
const eqIdx = p.indexOf("=");
|
|
1201
1166
|
const k = eqIdx === -1 ? p : p.substring(0, eqIdx);
|
|
1202
1167
|
const v = eqIdx === -1 ? "" : p.substring(eqIdx + 1);
|
|
1203
|
-
if (k)
|
|
1204
|
-
params[k] = decodeURIComponent(v);
|
|
1168
|
+
if (k) params[k] = decodeURIComponent(v);
|
|
1205
1169
|
});
|
|
1206
1170
|
return { base, params };
|
|
1207
1171
|
}
|
|
@@ -1245,8 +1209,7 @@ async function readResource(uri) {
|
|
|
1245
1209
|
}
|
|
1246
1210
|
async function getCadInfo2() {
|
|
1247
1211
|
const cached = getCached("cad:info");
|
|
1248
|
-
if (cached)
|
|
1249
|
-
return cached;
|
|
1212
|
+
if (cached) return cached;
|
|
1250
1213
|
if (!cad.connected) {
|
|
1251
1214
|
await cad.connect();
|
|
1252
1215
|
}
|
|
@@ -1273,12 +1236,9 @@ async function getCadInfo2() {
|
|
|
1273
1236
|
async function getLayers(filterName = null) {
|
|
1274
1237
|
const cacheKey = filterName ? `dwg:layers:${filterName}` : "dwg:layers:all";
|
|
1275
1238
|
const cached = getCached(cacheKey);
|
|
1276
|
-
if (cached)
|
|
1277
|
-
|
|
1278
|
-
if (!cad.connected)
|
|
1279
|
-
await cad.connect();
|
|
1280
|
-
if (!cad.connected)
|
|
1281
|
-
return [];
|
|
1239
|
+
if (cached) return cached;
|
|
1240
|
+
if (!cad.connected) await cad.connect();
|
|
1241
|
+
if (!cad.connected) return [];
|
|
1282
1242
|
try {
|
|
1283
1243
|
const code = filterName ? `(vl-prin1-to-string (cdr (assoc 2 (tblnext "LAYER" T))))` : `(progn (setq res nil)(while (setq e (tblnext "LAYER" (null res)))(setq res (cons (list (vl-prin1-to-string (cdr (assoc 2 e))) (cdr (assoc 62 e)) (cdr (assoc 70 e))) res))) (reverse res))`;
|
|
1284
1244
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -1325,10 +1285,8 @@ async function getLayers(filterName = null) {
|
|
|
1325
1285
|
async function getEntities(params = {}) {
|
|
1326
1286
|
const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
|
|
1327
1287
|
const cached = getCached(cacheKey);
|
|
1328
|
-
if (cached)
|
|
1329
|
-
|
|
1330
|
-
if (!cad.connected)
|
|
1331
|
-
await cad.connect();
|
|
1288
|
+
if (cached) return cached;
|
|
1289
|
+
if (!cad.connected) await cad.connect();
|
|
1332
1290
|
if (!cad.connected) {
|
|
1333
1291
|
const result = { total: 0, entities: [] };
|
|
1334
1292
|
setCache(cacheKey, result);
|
|
@@ -1368,10 +1326,8 @@ async function getEntities(params = {}) {
|
|
|
1368
1326
|
async function getTexts(params = {}) {
|
|
1369
1327
|
const cacheKey = `dwg:texts:${JSON.stringify(params)}`;
|
|
1370
1328
|
const cached = getCached(cacheKey);
|
|
1371
|
-
if (cached)
|
|
1372
|
-
|
|
1373
|
-
if (!cad.connected)
|
|
1374
|
-
await cad.connect();
|
|
1329
|
+
if (cached) return cached;
|
|
1330
|
+
if (!cad.connected) await cad.connect();
|
|
1375
1331
|
if (!cad.connected) {
|
|
1376
1332
|
const result = { total: 0, texts: [] };
|
|
1377
1333
|
setCache(cacheKey, result);
|
|
@@ -1409,10 +1365,8 @@ async function getTexts(params = {}) {
|
|
|
1409
1365
|
}
|
|
1410
1366
|
}
|
|
1411
1367
|
async function getDwgName() {
|
|
1412
|
-
if (!cad.connected)
|
|
1413
|
-
|
|
1414
|
-
if (!cad.connected)
|
|
1415
|
-
return { name: null };
|
|
1368
|
+
if (!cad.connected) await cad.connect();
|
|
1369
|
+
if (!cad.connected) return { name: null };
|
|
1416
1370
|
try {
|
|
1417
1371
|
const code = `(vl-princ-to-string (getvar "dwgname"))`;
|
|
1418
1372
|
const name = await cad.sendCommandWithResult(code);
|
|
@@ -1422,10 +1376,8 @@ async function getDwgName() {
|
|
|
1422
1376
|
}
|
|
1423
1377
|
}
|
|
1424
1378
|
async function getDwgPath() {
|
|
1425
|
-
if (!cad.connected)
|
|
1426
|
-
|
|
1427
|
-
if (!cad.connected)
|
|
1428
|
-
return { path: null, name: null };
|
|
1379
|
+
if (!cad.connected) await cad.connect();
|
|
1380
|
+
if (!cad.connected) return { path: null, name: null };
|
|
1429
1381
|
try {
|
|
1430
1382
|
const code = `(progn
|
|
1431
1383
|
(setq prefix (vl-princ-to-string (getvar "dwgprefix")))
|
|
@@ -1443,8 +1395,7 @@ async function getDwgPath() {
|
|
|
1443
1395
|
}
|
|
1444
1396
|
if (!parsed) {
|
|
1445
1397
|
const listResult = parseLispList(result);
|
|
1446
|
-
if (listResult && listResult.length >= 2)
|
|
1447
|
-
parsed = listResult;
|
|
1398
|
+
if (listResult && listResult.length >= 2) parsed = listResult;
|
|
1448
1399
|
}
|
|
1449
1400
|
if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
|
|
1450
1401
|
return { path: String(parsed[0]), name: String(parsed[1]) };
|
|
@@ -1457,12 +1408,9 @@ async function getDwgPath() {
|
|
|
1457
1408
|
async function getPackages(filterName = null) {
|
|
1458
1409
|
const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
|
|
1459
1410
|
const cached = getCached(cacheKey);
|
|
1460
|
-
if (cached)
|
|
1461
|
-
|
|
1462
|
-
if (!cad.connected)
|
|
1463
|
-
await cad.connect();
|
|
1464
|
-
if (!cad.connected)
|
|
1465
|
-
return [];
|
|
1411
|
+
if (cached) return cached;
|
|
1412
|
+
if (!cad.connected) await cad.connect();
|
|
1413
|
+
if (!cad.connected) return [];
|
|
1466
1414
|
try {
|
|
1467
1415
|
const code = `(mapcar 'cdr @::*local-pkgs*)`;
|
|
1468
1416
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -1476,8 +1424,7 @@ async function getPackages(filterName = null) {
|
|
|
1476
1424
|
} catch {
|
|
1477
1425
|
raw = parseLispList(result) || [];
|
|
1478
1426
|
}
|
|
1479
|
-
if (!Array.isArray(raw))
|
|
1480
|
-
raw = [];
|
|
1427
|
+
if (!Array.isArray(raw)) raw = [];
|
|
1481
1428
|
const packages = raw.map((item) => {
|
|
1482
1429
|
if (Array.isArray(item)) {
|
|
1483
1430
|
const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
|
|
@@ -1486,20 +1433,13 @@ async function getPackages(filterName = null) {
|
|
|
1486
1433
|
const [[key, val]] = Object.entries(entry);
|
|
1487
1434
|
const k = String(key);
|
|
1488
1435
|
const v = String(val);
|
|
1489
|
-
if (k === ":NAME")
|
|
1490
|
-
|
|
1491
|
-
else if (k === ":
|
|
1492
|
-
|
|
1493
|
-
else if (k === ":
|
|
1494
|
-
|
|
1495
|
-
else if (k === ":
|
|
1496
|
-
pkg.fullName = v;
|
|
1497
|
-
else if (k === ":AUTHOR")
|
|
1498
|
-
pkg.author = v;
|
|
1499
|
-
else if (k === ":CATEGORY")
|
|
1500
|
-
pkg.category = v;
|
|
1501
|
-
else if (k === ":URL")
|
|
1502
|
-
pkg.url = v;
|
|
1436
|
+
if (k === ":NAME") pkg.name = v;
|
|
1437
|
+
else if (k === ":VERSION") pkg.version = v;
|
|
1438
|
+
else if (k === ":DESCRIPTION") pkg.description = v;
|
|
1439
|
+
else if (k === ":FULL-NAME") pkg.fullName = v;
|
|
1440
|
+
else if (k === ":AUTHOR") pkg.author = v;
|
|
1441
|
+
else if (k === ":CATEGORY") pkg.category = v;
|
|
1442
|
+
else if (k === ":URL") pkg.url = v;
|
|
1503
1443
|
}
|
|
1504
1444
|
}
|
|
1505
1445
|
return pkg;
|
|
@@ -1510,22 +1450,15 @@ async function getPackages(filterName = null) {
|
|
|
1510
1450
|
if (item && typeof item === "object") {
|
|
1511
1451
|
const pkg = { name: "", version: "0.0.0", description: "", loaded: true };
|
|
1512
1452
|
const nameVal = item.name || item.Name || item.NAME || item[":NAME"];
|
|
1513
|
-
if (nameVal)
|
|
1514
|
-
pkg.name = String(nameVal);
|
|
1453
|
+
if (nameVal) pkg.name = String(nameVal);
|
|
1515
1454
|
const verVal = item.version || item.Version || item.VERSION || item[":VERSION"];
|
|
1516
|
-
if (verVal)
|
|
1517
|
-
pkg.version = String(verVal);
|
|
1455
|
+
if (verVal) pkg.version = String(verVal);
|
|
1518
1456
|
const descVal = item.description || item.Description || item.DESCRIPTION || item[":DESCRIPTION"];
|
|
1519
|
-
if (descVal)
|
|
1520
|
-
|
|
1521
|
-
if (item.
|
|
1522
|
-
|
|
1523
|
-
if (item.
|
|
1524
|
-
pkg.author = String(item.author || item.Author);
|
|
1525
|
-
if (item.category || item.Category)
|
|
1526
|
-
pkg.category = String(item.category || item.Category);
|
|
1527
|
-
if (item.url || item.Url || item.URL)
|
|
1528
|
-
pkg.url = String(item.url || item.Url || item.URL);
|
|
1457
|
+
if (descVal) pkg.description = String(descVal);
|
|
1458
|
+
if (item.fullName || item.full_name) pkg.fullName = String(item.fullName || item.full_name);
|
|
1459
|
+
if (item.author || item.Author) pkg.author = String(item.author || item.Author);
|
|
1460
|
+
if (item.category || item.Category) pkg.category = String(item.category || item.Category);
|
|
1461
|
+
if (item.url || item.Url || item.URL) pkg.url = String(item.url || item.Url || item.URL);
|
|
1529
1462
|
return pkg;
|
|
1530
1463
|
}
|
|
1531
1464
|
return null;
|
|
@@ -1551,12 +1484,9 @@ function getPlatforms() {
|
|
|
1551
1484
|
async function getDwgList() {
|
|
1552
1485
|
const cacheKey = "cad:dwgs";
|
|
1553
1486
|
const cached = getCached(cacheKey);
|
|
1554
|
-
if (cached)
|
|
1555
|
-
|
|
1556
|
-
if (!cad.connected)
|
|
1557
|
-
await cad.connect();
|
|
1558
|
-
if (!cad.connected)
|
|
1559
|
-
return [];
|
|
1487
|
+
if (cached) return cached;
|
|
1488
|
+
if (!cad.connected) await cad.connect();
|
|
1489
|
+
if (!cad.connected) return [];
|
|
1560
1490
|
try {
|
|
1561
1491
|
const code = `(progn
|
|
1562
1492
|
(vl-load-com)
|
|
@@ -1580,8 +1510,7 @@ async function getDwgList() {
|
|
|
1580
1510
|
parsed = listResult;
|
|
1581
1511
|
}
|
|
1582
1512
|
}
|
|
1583
|
-
if (!Array.isArray(parsed))
|
|
1584
|
-
parsed = [];
|
|
1513
|
+
if (!Array.isArray(parsed)) parsed = [];
|
|
1585
1514
|
const dwgList = parsed.map((item) => {
|
|
1586
1515
|
if (Array.isArray(item) && item.length >= 2) {
|
|
1587
1516
|
return { name: String(item[0]), path: String(item[1]) };
|
|
@@ -1608,8 +1537,7 @@ function loadStandardsFile(filename) {
|
|
|
1608
1537
|
var standardsCache = /* @__PURE__ */ new Map();
|
|
1609
1538
|
function getCachedStandards(key) {
|
|
1610
1539
|
const entry = standardsCache.get(key);
|
|
1611
|
-
if (entry && Date.now() - entry.timestamp < 3e4)
|
|
1612
|
-
return entry.data;
|
|
1540
|
+
if (entry && Date.now() - entry.timestamp < 3e4) return entry.data;
|
|
1613
1541
|
standardsCache.delete(key);
|
|
1614
1542
|
return null;
|
|
1615
1543
|
}
|
|
@@ -1618,20 +1546,16 @@ function setCachedStandards(key, data) {
|
|
|
1618
1546
|
}
|
|
1619
1547
|
function getDraftingStandards() {
|
|
1620
1548
|
const cached = getCachedStandards("drafting");
|
|
1621
|
-
if (cached)
|
|
1622
|
-
return cached;
|
|
1549
|
+
if (cached) return cached;
|
|
1623
1550
|
const data = loadStandardsFile("drafting.json");
|
|
1624
|
-
if (data)
|
|
1625
|
-
setCachedStandards("drafting", data);
|
|
1551
|
+
if (data) setCachedStandards("drafting", data);
|
|
1626
1552
|
return data || { error: "\u5236\u56FE\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
|
|
1627
1553
|
}
|
|
1628
1554
|
function getCodingStandards() {
|
|
1629
1555
|
const cached = getCachedStandards("coding");
|
|
1630
|
-
if (cached)
|
|
1631
|
-
return cached;
|
|
1556
|
+
if (cached) return cached;
|
|
1632
1557
|
const data = loadStandardsFile("coding.json");
|
|
1633
|
-
if (data)
|
|
1634
|
-
setCachedStandards("coding", data);
|
|
1558
|
+
if (data) setCachedStandards("coding", data);
|
|
1635
1559
|
return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
|
|
1636
1560
|
}
|
|
1637
1561
|
|
|
@@ -1885,14 +1809,10 @@ ${generateSuggestions(entities, layers)}`
|
|
|
1885
1809
|
}
|
|
1886
1810
|
function generateSuggestions(entities, layers) {
|
|
1887
1811
|
const suggestions = [];
|
|
1888
|
-
if (entities.total > 1e3)
|
|
1889
|
-
|
|
1890
|
-
if (
|
|
1891
|
-
|
|
1892
|
-
if (entities.byType.LINE && entities.byType.LINE > 500)
|
|
1893
|
-
suggestions.push("- \u7EBF\u6761\u8F83\u591A\uFF0C\u53EF\u8003\u8651\u4F7F\u7528 BLOCK \u51CF\u5C11\u5B9E\u4F53\u6570\u91CF");
|
|
1894
|
-
if (!entities.byType.DIMENSION)
|
|
1895
|
-
suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
|
|
1812
|
+
if (entities.total > 1e3) suggestions.push("- \u56FE\u7EB8\u5B9E\u4F53\u8F83\u591A\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u56FE\u5C42\u5206\u7C7B\u7BA1\u7406");
|
|
1813
|
+
if (layers.length > 20) suggestions.push("- \u56FE\u5C42\u8F83\u591A\uFF0C\u5EFA\u8BAE\u6E05\u7406\u672A\u4F7F\u7528\u7684\u56FE\u5C42");
|
|
1814
|
+
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");
|
|
1815
|
+
if (!entities.byType.DIMENSION) suggestions.push("- \u672A\u53D1\u73B0\u5C3A\u5BF8\u6807\u6CE8\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u6807\u6CE8");
|
|
1896
1816
|
return suggestions.length ? suggestions.join("\n") : "- \u56FE\u7EB8\u7ED3\u6784\u826F\u597D";
|
|
1897
1817
|
}
|
|
1898
1818
|
async function generateBatchLinesPrompt(args) {
|
|
@@ -2620,11 +2540,9 @@ var SseSession = class {
|
|
|
2620
2540
|
return lines.join("\n") + "\n\n";
|
|
2621
2541
|
}
|
|
2622
2542
|
_setupDrain() {
|
|
2623
|
-
if (typeof this.#res.on !== "function")
|
|
2624
|
-
return;
|
|
2543
|
+
if (typeof this.#res.on !== "function") return;
|
|
2625
2544
|
this.#drainHandler = () => {
|
|
2626
|
-
if (!this.#active)
|
|
2627
|
-
return;
|
|
2545
|
+
if (!this.#active) return;
|
|
2628
2546
|
if (this.#backpressureBuffer.length > 0) {
|
|
2629
2547
|
this._drainBuffer();
|
|
2630
2548
|
}
|
|
@@ -2646,8 +2564,7 @@ var SseSession = class {
|
|
|
2646
2564
|
}
|
|
2647
2565
|
}
|
|
2648
2566
|
_write(content) {
|
|
2649
|
-
if (!this.#active)
|
|
2650
|
-
return false;
|
|
2567
|
+
if (!this.#active) return false;
|
|
2651
2568
|
try {
|
|
2652
2569
|
if (this.#backpressureBuffer.length > 0) {
|
|
2653
2570
|
this.#backpressureBuffer.push(content);
|
|
@@ -2775,8 +2692,7 @@ function persistSessionData(clientId, sessionData) {
|
|
|
2775
2692
|
function loadPersistedSessionData(clientId) {
|
|
2776
2693
|
try {
|
|
2777
2694
|
const filePath = getSessionStorePath(clientId);
|
|
2778
|
-
if (!fs5.existsSync(filePath))
|
|
2779
|
-
return null;
|
|
2695
|
+
if (!fs5.existsSync(filePath)) return null;
|
|
2780
2696
|
const raw = fs5.readFileSync(filePath, "utf-8");
|
|
2781
2697
|
const store = JSON.parse(raw);
|
|
2782
2698
|
if (Date.now() - store.savedAt > SESSION_STORE_TTL) {
|
|
@@ -2965,8 +2881,7 @@ var SERVER_CAPABILITIES = {
|
|
|
2965
2881
|
prompts: {}
|
|
2966
2882
|
};
|
|
2967
2883
|
var { port, host, transport, apiKey, rateLimitWindow, rateLimitMax } = config_default;
|
|
2968
|
-
if (apiKey)
|
|
2969
|
-
log("API Key authentication enabled");
|
|
2884
|
+
if (apiKey) log("API Key authentication enabled");
|
|
2970
2885
|
var mcpLimiter = rateLimit({
|
|
2971
2886
|
windowMs: rateLimitWindow,
|
|
2972
2887
|
max: rateLimitMax,
|
|
@@ -3051,8 +2966,7 @@ ${CAD_PLATFORMS.join("\n")}
|
|
|
3051
2966
|
},
|
|
3052
2967
|
import_funlib: async (a) => {
|
|
3053
2968
|
const data = await loadAtlibFunctionLib();
|
|
3054
|
-
if (!data)
|
|
3055
|
-
return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
|
|
2969
|
+
if (!data) return { content: [{ type: "text", text: "\u52A0\u8F7D\u51FD\u6570\u5E93\u5931\u8D25" }], isError: true };
|
|
3056
2970
|
if (a.format === "list") {
|
|
3057
2971
|
const items = Object.values(data.all_functions || {}).map((f) => `${f.name}: ${f.description || ""}`);
|
|
3058
2972
|
return { content: [{ type: "text", text: items.join("\n") }] };
|
|
@@ -3241,8 +3155,7 @@ var tools = [
|
|
|
3241
3155
|
];
|
|
3242
3156
|
async function handleToolCall(name, args) {
|
|
3243
3157
|
const handler = TOOL_HANDLERS[name];
|
|
3244
|
-
if (!handler)
|
|
3245
|
-
return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
|
|
3158
|
+
if (!handler) return { content: [{ type: "text", text: `\u672A\u77E5\u5DE5\u5177: ${name}` }], isError: true };
|
|
3246
3159
|
try {
|
|
3247
3160
|
const result = await handler(args || {});
|
|
3248
3161
|
notifyResourceChanges(name);
|
|
@@ -3365,8 +3278,7 @@ async function startServer() {
|
|
|
3365
3278
|
const JSON_CONTENT_TYPES = ["application/json", "application/json-rpc", "application/vnd.api+json"];
|
|
3366
3279
|
app.use(async (req, res, next) => {
|
|
3367
3280
|
const ct = (req.headers["content-type"] || "").toLowerCase();
|
|
3368
|
-
if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t)))
|
|
3369
|
-
return next();
|
|
3281
|
+
if (!JSON_CONTENT_TYPES.some((t) => ct.startsWith(t))) return next();
|
|
3370
3282
|
try {
|
|
3371
3283
|
const buf = await rawBody(req, { limit: "10mb" });
|
|
3372
3284
|
const m = ct.match(/charset\s*=\s*([^\s;]+)/i);
|
|
@@ -3387,11 +3299,9 @@ async function startServer() {
|
|
|
3387
3299
|
const PUBLIC_PATHS = ["/health"];
|
|
3388
3300
|
if (apiKey) {
|
|
3389
3301
|
app.use((req, res, next) => {
|
|
3390
|
-
if (PUBLIC_PATHS.includes(req.path))
|
|
3391
|
-
return next();
|
|
3302
|
+
if (PUBLIC_PATHS.includes(req.path)) return next();
|
|
3392
3303
|
const auth = req.get("Authorization");
|
|
3393
|
-
if (auth === `Bearer ${apiKey}`)
|
|
3394
|
-
return next();
|
|
3304
|
+
if (auth === `Bearer ${apiKey}`) return next();
|
|
3395
3305
|
res.status(401).json({ error: "Unauthorized" });
|
|
3396
3306
|
});
|
|
3397
3307
|
}
|
|
@@ -3406,8 +3316,7 @@ async function startServer() {
|
|
|
3406
3316
|
res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, content-type, x-accel-buffering");
|
|
3407
3317
|
res.setHeader("Access-Control-Max-Age", "86400");
|
|
3408
3318
|
res.setHeader("Vary", "Accept");
|
|
3409
|
-
if (req.method === "OPTIONS")
|
|
3410
|
-
return res.status(204).end();
|
|
3319
|
+
if (req.method === "OPTIONS") return res.status(204).end();
|
|
3411
3320
|
next();
|
|
3412
3321
|
});
|
|
3413
3322
|
}
|