@atlisp/mcp 1.8.23 → 1.8.25
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/README.md +52 -4
- package/dist/atlisp-mcp.js +1422 -848
- package/dist/cad-rothelper.dll +0 -0
- package/dist/cad-worker.js +236 -174
- package/dist/config.js +59 -56
- package/dist/handlers/meta-handlers.js +70 -0
- package/dist/handlers/resource-cache.js +48 -16
- package/dist/handlers/resource-defs.js +3 -0
- package/dist/handlers/resource-handlers.js +123 -0
- package/dist/handlers/skill-handlers.js +152 -0
- package/dist/lisp-security.js +65 -0
- package/dist/prompts/definitions/workflow-batch-doc.json +27 -0
- package/package.json +3 -2
- package/dist/pipelines/analyze-and-report.json +0 -16
- package/dist/pipelines/batch-export-pdfs.json +0 -11
- package/dist/pipelines/batch-layer-move.json +0 -19
- package/dist/pipelines/export-current-drawing.json +0 -18
- package/dist/pipelines/purge-and-save.json +0 -16
|
Binary file
|
package/dist/cad-worker.js
CHANGED
|
@@ -4,15 +4,55 @@ import process from 'process';
|
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import crypto from 'crypto';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
7
8
|
import { validateLispCodeWorker, checkParens } from './lisp-security.js';
|
|
8
9
|
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
const _dllPath = path.join(__dirname, '..', 'dist', 'cad-rothelper.dll');
|
|
13
|
+
|
|
14
|
+
function _loadDll(methodName) {
|
|
15
|
+
try {
|
|
16
|
+
return edge.func({
|
|
17
|
+
assemblyFile: _dllPath,
|
|
18
|
+
typeName: 'CadRotHelper.ConnectionManager',
|
|
19
|
+
methodName,
|
|
20
|
+
});
|
|
21
|
+
} catch (e) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function _loadEnum() {
|
|
27
|
+
try {
|
|
28
|
+
return edge.func({
|
|
29
|
+
assemblyFile: _dllPath,
|
|
30
|
+
typeName: 'CadRotHelper.RotEnumerator',
|
|
31
|
+
methodName: 'EnumerateAll',
|
|
32
|
+
});
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const _rotConnect = _loadDll('RotConnect');
|
|
39
|
+
const _rotDisconnect = _loadDll('RotDisconnect');
|
|
40
|
+
const _rotSendCmd = _loadDll('RotSendCommand');
|
|
41
|
+
const _rotSendResult = _loadDll('RotSendWithResult');
|
|
42
|
+
const _rotIsBusy = _loadDll('RotIsBusy');
|
|
43
|
+
const _rotHasDoc = _loadDll('RotHasDoc');
|
|
44
|
+
const _rotDocInfo = _loadDll('RotGetActiveDocInfo');
|
|
45
|
+
const _rotBringToFront = _loadDll('RotBringToFront');
|
|
46
|
+
const _rotNewDoc = _loadDll('RotNewDoc');
|
|
47
|
+
const _rotEnum = _loadEnum();
|
|
48
|
+
|
|
49
|
+
let _monikerSession = null;
|
|
50
|
+
|
|
9
51
|
const BUSY_RETRIES = parseInt(process.env.BUSY_RETRIES || '10', 10);
|
|
10
52
|
const BUSY_DELAY = parseInt(process.env.BUSY_DELAY || '500', 10);
|
|
11
53
|
|
|
12
|
-
// Lisp expression cache (hash -> compiled Lisp code)
|
|
13
54
|
const LISP_CACHE = new Map();
|
|
14
55
|
const LISP_CACHE_MAX = parseInt(process.env.LISP_CACHE_MAX || '500', 10);
|
|
15
|
-
|
|
16
56
|
const CACHE_TTL = parseInt(process.env.LISP_CACHE_TTL || '300000', 10);
|
|
17
57
|
|
|
18
58
|
function getCachedLisp(code) {
|
|
@@ -123,7 +163,7 @@ const cadLaunch = edge.func(function() {/*
|
|
|
123
163
|
}
|
|
124
164
|
} catch (Exception ex) {
|
|
125
165
|
System.Diagnostics.Debug.WriteLine("cadLaunch create " + progIds[i] + " error: " + ex.Message);
|
|
126
|
-
|
|
166
|
+
}
|
|
127
167
|
}
|
|
128
168
|
|
|
129
169
|
return new { success = false, error = "No CAD found" };
|
|
@@ -135,14 +175,14 @@ const cadSend = edge.func(function() {/*
|
|
|
135
175
|
try {
|
|
136
176
|
dynamic d = input;
|
|
137
177
|
string code = d.code.ToString();
|
|
138
|
-
|
|
139
|
-
|
|
178
|
+
string platform = d.platform.ToString();
|
|
179
|
+
string progId = platform == "BricsCAD" ? "BricscadApp.AcadApplication" : platform + ".Application";
|
|
140
180
|
dynamic cad = System.Runtime.InteropServices.Marshal.GetActiveObject(progId);
|
|
141
181
|
if (cad != null) {
|
|
142
182
|
dynamic doc = cad.ActiveDocument;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
183
|
+
if (doc != null) {
|
|
184
|
+
doc.SendCommand(code);
|
|
185
|
+
return new { success = true };
|
|
146
186
|
}
|
|
147
187
|
}
|
|
148
188
|
} catch (Exception ex) {
|
|
@@ -165,18 +205,16 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
165
205
|
string codeHash = d.codeHash != null ? d.codeHash.ToString() : "";
|
|
166
206
|
bool cacheEnabled = d.cacheEnabled != null && d.cacheEnabled.ToString() == "True";
|
|
167
207
|
bool hasCacheKey = cacheEnabled && !string.IsNullOrEmpty(codeHash);
|
|
168
|
-
|
|
169
|
-
|
|
208
|
+
string progId = platform == "BricsCAD" ? "BricscadApp.AcadApplication" : platform + ".Application";
|
|
209
|
+
string tempDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "@lisp", "tmp");
|
|
170
210
|
System.IO.Directory.CreateDirectory(tempDir);
|
|
171
|
-
|
|
172
|
-
// 结果文件始终使用 GUID 命名(每次调用唯一)
|
|
211
|
+
|
|
173
212
|
tempFile = System.IO.Path.Combine(tempDir, "atlisp_result_" + System.Guid.NewGuid().ToString("N") + ".txt");
|
|
174
|
-
|
|
175
|
-
// 代码文件:启用缓存时使用 hash 命名,否则使用 GUID 命名
|
|
213
|
+
|
|
176
214
|
string fileKey = hasCacheKey ? codeHash : System.Guid.NewGuid().ToString("N");
|
|
177
215
|
userCodeFile = System.IO.Path.Combine(tempDir, "atlisp_user_" + fileKey + ".lsp");
|
|
178
216
|
lispFile = System.IO.Path.Combine(tempDir, "atlisp_code_" + fileKey + ".lsp");
|
|
179
|
-
|
|
217
|
+
|
|
180
218
|
bool useCachedUserCode = false;
|
|
181
219
|
if (hasCacheKey) {
|
|
182
220
|
if (System.IO.File.Exists(userCodeFile)) {
|
|
@@ -186,11 +224,11 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
186
224
|
}
|
|
187
225
|
}
|
|
188
226
|
}
|
|
189
|
-
|
|
227
|
+
|
|
190
228
|
if (!useCachedUserCode) {
|
|
191
229
|
System.IO.File.WriteAllText(userCodeFile, code, System.Text.Encoding.GetEncoding(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage));
|
|
192
230
|
}
|
|
193
|
-
|
|
231
|
+
|
|
194
232
|
string lispCode = "(progn"
|
|
195
233
|
+ "(setq f(open \"" + tempFile.Replace("\\", "\\\\") + "\" \"w\"))"
|
|
196
234
|
+ "(setq r(vl-catch-all-apply '(lambda ()(load \"" + userCodeFile.Replace("\\", "\\\\") + "\"))))"
|
|
@@ -199,15 +237,15 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
199
237
|
+ "(princ r f))"
|
|
200
238
|
+ "(close f)"
|
|
201
239
|
+ "(princ))";
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
240
|
+
|
|
241
|
+
System.IO.File.WriteAllText(lispFile, lispCode, System.Text.Encoding.GetEncoding(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage));
|
|
242
|
+
|
|
205
243
|
dynamic cad = System.Runtime.InteropServices.Marshal.GetActiveObject(progId);
|
|
206
244
|
if (cad != null) {
|
|
207
245
|
dynamic doc = cad.ActiveDocument;
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
246
|
+
if (doc != null) {
|
|
247
|
+
doc.SendCommand("(load \"" + lispFile.Replace("\\", "\\\\") + "\")\n");
|
|
248
|
+
|
|
211
249
|
int retries = 10;
|
|
212
250
|
string result = "";
|
|
213
251
|
while (retries > 0 && !System.IO.File.Exists(tempFile)) {
|
|
@@ -220,7 +258,7 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
220
258
|
try {
|
|
221
259
|
byte[] bytes = System.IO.File.ReadAllBytes(tempFile);
|
|
222
260
|
System.Text.Encoding enc;
|
|
223
|
-
|
|
261
|
+
|
|
224
262
|
if (!string.IsNullOrEmpty(encoding)) {
|
|
225
263
|
enc = System.Text.Encoding.GetEncoding(encoding);
|
|
226
264
|
} else {
|
|
@@ -239,13 +277,13 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
239
277
|
}
|
|
240
278
|
}
|
|
241
279
|
}
|
|
242
|
-
|
|
280
|
+
|
|
243
281
|
result = enc.GetString(bytes).Trim();
|
|
244
|
-
|
|
282
|
+
|
|
245
283
|
if (result.StartsWith("ERROR:")) {
|
|
246
284
|
return new { success = false, error = result.Substring(6).Trim() };
|
|
247
285
|
}
|
|
248
|
-
|
|
286
|
+
|
|
249
287
|
try { System.IO.File.Delete(tempFile); } catch {}
|
|
250
288
|
try { System.IO.File.Delete(lispFile); } catch {}
|
|
251
289
|
if (!hasCacheKey) { try { if (System.IO.File.Exists(userCodeFile)) System.IO.File.Delete(userCodeFile); } catch {} }
|
|
@@ -512,184 +550,208 @@ function computeCodeHash(code, cacheEnabled) {
|
|
|
512
550
|
return '';
|
|
513
551
|
}
|
|
514
552
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
return {
|
|
553
|
+
function dllCall(fn, args) {
|
|
554
|
+
return new Promise((resolve, reject) => {
|
|
555
|
+
if (!fn) return resolve({ success: false, error: 'DLL method not available' });
|
|
556
|
+
fn(args, (e, r) => {
|
|
557
|
+
if (e) reject(e);
|
|
558
|
+
else resolve(r);
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
async function monikerOrEdge(rotFn, edgeFn, args, platform) {
|
|
564
|
+
if (_monikerSession && rotFn) return await dllCall(rotFn, { key: _monikerSession, ...args });
|
|
565
|
+
return new Promise((resolve, reject) => {
|
|
566
|
+
edgeFn(platform || 'AutoCAD', (e, r) => {
|
|
567
|
+
if (e) reject(e);
|
|
568
|
+
else resolve(r);
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function validateCode(code) {
|
|
574
|
+
const parenCheck = checkParens(code);
|
|
575
|
+
if (!parenCheck.valid) {
|
|
576
|
+
return { valid: false, error: `括号错误: ${parenCheck.error} (位置 ${parenCheck.pos})` };
|
|
518
577
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const result = await new Promise((resolve, reject) => {
|
|
525
|
-
cadConnect({}, (e, r) => {
|
|
526
|
-
if (e) reject(e);
|
|
527
|
-
else resolve(r);
|
|
528
|
-
});
|
|
529
|
-
});
|
|
530
|
-
if (result && result.success) return result;
|
|
531
|
-
} catch (e) {
|
|
532
|
-
log('cadConnect failed: ' + e.message);
|
|
578
|
+
const securityLevel = process.env.SECURITY_LEVEL || 'strict';
|
|
579
|
+
if (securityLevel !== 'relaxed') {
|
|
580
|
+
const injectionCheck = validateLispCodeWorker(code);
|
|
581
|
+
if (!injectionCheck.valid) {
|
|
582
|
+
return { valid: false, error: `安全限制: ${injectionCheck.error}` };
|
|
533
583
|
}
|
|
534
|
-
return new Promise((resolve, reject) => {
|
|
535
|
-
cadLaunch({}, (e, r) => {
|
|
536
|
-
if (e) reject(e);
|
|
537
|
-
else resolve(r);
|
|
538
|
-
});
|
|
539
|
-
});
|
|
540
584
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
585
|
+
return { valid: true };
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
async function ensureDocument(platform) {
|
|
589
|
+
if (_monikerSession) return true;
|
|
590
|
+
const docCheck = await new Promise((resolve, reject) => {
|
|
591
|
+
cadHasDoc(platform || 'AutoCAD', (e, r) => {
|
|
592
|
+
if (e) reject(e);
|
|
593
|
+
else resolve(r);
|
|
547
594
|
});
|
|
595
|
+
});
|
|
596
|
+
return docCheck.hasDoc;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
async function executeWithRetry(fn, label) {
|
|
600
|
+
const maxRetries = 3;
|
|
601
|
+
let lastError = null;
|
|
602
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
603
|
+
const isBusy = await waitForIdle();
|
|
604
|
+
if (isBusy) {
|
|
605
|
+
try {
|
|
606
|
+
return await fn();
|
|
607
|
+
} catch (e) {
|
|
608
|
+
log(`${label} error: ${e.message}`);
|
|
609
|
+
lastError = e;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
await new Promise(r => setTimeout(r, 500));
|
|
548
613
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
});
|
|
614
|
+
return { success: false, error: lastError?.message || '发送失败' };
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
async function executeLisp(msg, withResult) {
|
|
618
|
+
if (!msg.code.endsWith('\n')) {
|
|
619
|
+
msg.code += '\n';
|
|
556
620
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
});
|
|
621
|
+
|
|
622
|
+
const validation = validateCode(msg.code);
|
|
623
|
+
if (!validation.valid) return validation;
|
|
624
|
+
|
|
625
|
+
if (!await ensureDocument(msg.platform)) {
|
|
626
|
+
return { success: false, error: 'No open document' };
|
|
564
627
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
const docCheck = await new Promise((resolve, reject) => {
|
|
570
|
-
cadHasDoc(msg.platform || 'AutoCAD', (e, r) => {
|
|
571
|
-
if (e) reject(e);
|
|
572
|
-
else resolve(r);
|
|
573
|
-
});
|
|
574
|
-
});
|
|
575
|
-
if (!docCheck.hasDoc) {
|
|
576
|
-
return { success: false, error: 'No open document' };
|
|
577
|
-
}
|
|
578
|
-
const parenCheck = checkParens(msg.code);
|
|
579
|
-
if (!parenCheck.valid) {
|
|
580
|
-
return { success: false, error: `括号错误: ${parenCheck.error} (位置 ${parenCheck.pos})` };
|
|
581
|
-
}
|
|
582
|
-
const securityLevel = process.env.SECURITY_LEVEL || 'strict';
|
|
583
|
-
if (securityLevel !== 'relaxed') {
|
|
584
|
-
const injectionCheck = validateLispCodeWorker(msg.code);
|
|
585
|
-
if (!injectionCheck.valid) {
|
|
586
|
-
return { success: false, error: `安全限制: ${injectionCheck.error}` };
|
|
587
|
-
}
|
|
628
|
+
|
|
629
|
+
if (_monikerSession) {
|
|
630
|
+
if (withResult || msg.code.length > 240) {
|
|
631
|
+
return await dllCall(_rotSendResult, { key: _monikerSession, code: msg.code, encoding: msg.encoding || '' });
|
|
588
632
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
633
|
+
return await dllCall(_rotSendCmd, { key: _monikerSession, code: msg.code });
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (withResult || msg.code.length > 255) {
|
|
637
|
+
const cacheEnabled = process.env.LONG_CODE_CACHE === '1';
|
|
638
|
+
const codeHash = computeCodeHash(msg.code, cacheEnabled);
|
|
639
|
+
log(`sendResult (${msg.code.length} chars, cache=${cacheEnabled}): ${msg.code.substring(0, 80)}...`);
|
|
640
|
+
return await executeWithRetry(async () => {
|
|
593
641
|
const r = await new Promise((resolve, reject) => {
|
|
594
|
-
cadSendWithResult({ code: msg.code, platform: msg.platform
|
|
642
|
+
cadSendWithResult({ code: msg.code, platform: msg.platform, encoding: msg.encoding || '', codeHash, cacheEnabled }, (e, r) => {
|
|
595
643
|
if (e) reject(e);
|
|
596
644
|
else resolve(r);
|
|
597
645
|
});
|
|
598
646
|
});
|
|
599
|
-
log(`
|
|
647
|
+
log(`sendResult result: ${JSON.stringify(r)}`);
|
|
600
648
|
return r;
|
|
601
|
-
}
|
|
602
|
-
const maxRetries = 3;
|
|
603
|
-
let lastError = null;
|
|
604
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
605
|
-
const isBusy = await waitForIdle(msg.platform || 'AutoCAD');
|
|
606
|
-
if (isBusy) {
|
|
607
|
-
log(`send: ${msg.code}`);
|
|
608
|
-
try {
|
|
609
|
-
const r = await new Promise((resolve, reject) => {
|
|
610
|
-
cadSend({ code: msg.code, platform: msg.platform }, (e, r) => {
|
|
611
|
-
if (e) reject(e);
|
|
612
|
-
else resolve(r);
|
|
613
|
-
});
|
|
614
|
-
});
|
|
615
|
-
log(`send result: ${JSON.stringify(r)}`);
|
|
616
|
-
return r;
|
|
617
|
-
} catch (e) {
|
|
618
|
-
log(`send error: ${e.message}`);
|
|
619
|
-
lastError = e;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
await new Promise(r => setTimeout(r, 500));
|
|
623
|
-
}
|
|
624
|
-
return { success: false, error: lastError?.message || '发送失败' };
|
|
649
|
+
}, 'sendResult');
|
|
625
650
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
651
|
+
|
|
652
|
+
log(`send: ${msg.code}`);
|
|
653
|
+
return await executeWithRetry(async () => {
|
|
654
|
+
const r = await new Promise((resolve, reject) => {
|
|
655
|
+
cadSend({ code: msg.code, platform: msg.platform }, (e, r) => {
|
|
629
656
|
if (e) reject(e);
|
|
630
657
|
else resolve(r);
|
|
631
658
|
});
|
|
632
659
|
});
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const isBusy = await waitForIdle(msg.platform);
|
|
650
|
-
if (isBusy) {
|
|
651
|
-
log(`sendResult: ${msg.code}`);
|
|
652
|
-
try {
|
|
653
|
-
const r = await new Promise((resolve, reject) => {
|
|
654
|
-
cadSendWithResult({ code: msg.code, platform: msg.platform, encoding: msg.encoding || '', codeHash, cacheEnabled }, (e, r) => {
|
|
655
|
-
if (e) reject(e);
|
|
656
|
-
else resolve(r);
|
|
657
|
-
});
|
|
658
|
-
});
|
|
659
|
-
log(`sendResult result: ${JSON.stringify(r)}`);
|
|
660
|
-
return r;
|
|
661
|
-
} catch (e) {
|
|
662
|
-
log(`sendResult error: ${e.message}`);
|
|
663
|
-
lastErrorResult = e;
|
|
664
|
-
}
|
|
660
|
+
log(`send result: ${JSON.stringify(r)}`);
|
|
661
|
+
return r;
|
|
662
|
+
}, 'send');
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
const MESSAGE_HANDLERS = {
|
|
666
|
+
ping() {
|
|
667
|
+
return { pong: true };
|
|
668
|
+
},
|
|
669
|
+
|
|
670
|
+
async connect(msg) {
|
|
671
|
+
if (msg.moniker && _rotConnect) {
|
|
672
|
+
const result = await dllCall(_rotConnect, { key: msg.monikerKey, moniker: msg.moniker });
|
|
673
|
+
if (result && result.success) {
|
|
674
|
+
_monikerSession = msg.monikerKey;
|
|
675
|
+
return result;
|
|
665
676
|
}
|
|
666
|
-
|
|
677
|
+
return result;
|
|
667
678
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
679
|
+
if (msg.platform) {
|
|
680
|
+
return await connectToPlatform(msg.platform);
|
|
681
|
+
}
|
|
682
|
+
try {
|
|
683
|
+
const result = await new Promise((resolve, reject) => {
|
|
684
|
+
cadConnect({}, (e, r) => {
|
|
685
|
+
if (e) reject(e);
|
|
686
|
+
else resolve(r);
|
|
687
|
+
});
|
|
675
688
|
});
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
689
|
+
if (result && result.success) return result;
|
|
690
|
+
} catch (e) {
|
|
691
|
+
log('cadConnect failed: ' + e.message);
|
|
692
|
+
}
|
|
679
693
|
return new Promise((resolve, reject) => {
|
|
680
|
-
|
|
694
|
+
cadLaunch({}, (e, r) => {
|
|
681
695
|
if (e) reject(e);
|
|
682
696
|
else resolve(r);
|
|
683
697
|
});
|
|
684
698
|
});
|
|
685
|
-
}
|
|
686
|
-
|
|
699
|
+
},
|
|
700
|
+
|
|
701
|
+
async disconnect() {
|
|
702
|
+
if (_monikerSession && _rotDisconnect) {
|
|
703
|
+
await dllCall(_rotDisconnect, { key: _monikerSession });
|
|
704
|
+
}
|
|
705
|
+
_monikerSession = null;
|
|
706
|
+
return { success: true };
|
|
707
|
+
},
|
|
708
|
+
|
|
709
|
+
async hasdoc(msg) {
|
|
710
|
+
return await monikerOrEdge(_rotHasDoc, cadHasDoc, {}, msg.platform);
|
|
711
|
+
},
|
|
712
|
+
|
|
713
|
+
async newdoc(msg) {
|
|
714
|
+
return await monikerOrEdge(_rotNewDoc, cadNewDoc, {}, msg.platform);
|
|
715
|
+
},
|
|
716
|
+
|
|
717
|
+
async bringToFront(msg) {
|
|
718
|
+
return await monikerOrEdge(_rotBringToFront, cadBringToFront, {}, msg.platform);
|
|
719
|
+
},
|
|
720
|
+
|
|
721
|
+
async send(msg) {
|
|
722
|
+
return await executeLisp(msg, false);
|
|
723
|
+
},
|
|
724
|
+
|
|
725
|
+
async sendResult(msg) {
|
|
726
|
+
return await executeLisp(msg, true);
|
|
727
|
+
},
|
|
728
|
+
|
|
729
|
+
async isBusy(msg) {
|
|
730
|
+
return await monikerOrEdge(_rotIsBusy, cadIsBusy, {}, msg.platform);
|
|
731
|
+
},
|
|
732
|
+
|
|
733
|
+
async getActiveDocInfo(msg) {
|
|
734
|
+
return await monikerOrEdge(_rotDocInfo, cadGetActiveDocInfo, {}, msg.platform);
|
|
735
|
+
},
|
|
736
|
+
|
|
737
|
+
async startMonitor(msg) {
|
|
738
|
+
if (_monikerSession) {
|
|
739
|
+
return { success: false, error: 'startMonitor not supported for moniker connections' };
|
|
740
|
+
}
|
|
687
741
|
return new Promise((resolve, reject) => {
|
|
688
742
|
cadStartMonitor(msg.platform || 'AutoCAD', (e, r) => {
|
|
689
743
|
if (e) reject(e);
|
|
690
744
|
else resolve(r);
|
|
691
745
|
});
|
|
692
746
|
});
|
|
693
|
-
}
|
|
694
|
-
|
|
747
|
+
},
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
export async function handleMessage(msg) {
|
|
751
|
+
const handler = MESSAGE_HANDLERS[msg.type];
|
|
752
|
+
if (!handler) return { error: 'unknown message type' };
|
|
753
|
+
return await handler(msg);
|
|
695
754
|
}
|
|
755
|
+
|
|
756
|
+
// Exported for testing
|
|
757
|
+
export { validateCode, computeCodeHash, getCachedLisp, setCachedLisp, MESSAGE_HANDLERS, executeLisp };
|