@atlisp/mcp 1.8.21 → 1.8.23
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 +512 -66
- package/dist/handlers/debug-handlers.js +126 -0
- package/package.json +1 -1
package/dist/atlisp-mcp.js
CHANGED
|
@@ -6374,6 +6374,89 @@ var init_lint_tools = __esm({
|
|
|
6374
6374
|
}
|
|
6375
6375
|
});
|
|
6376
6376
|
|
|
6377
|
+
// src/tools/debug-tools.js
|
|
6378
|
+
var tools41;
|
|
6379
|
+
var init_debug_tools = __esm({
|
|
6380
|
+
"src/tools/debug-tools.js"() {
|
|
6381
|
+
tools41 = [
|
|
6382
|
+
{
|
|
6383
|
+
name: "debug_start",
|
|
6384
|
+
description: "\u542F\u52A8\u4EA4\u4E92\u5F0F\u8C03\u8BD5\u4F1A\u8BDD\u3002\u5C06\u4EE3\u7801\u6309\u5757\u62C6\u5206\u4E3A\u65AD\u70B9\u7EA7\u6267\u884C\uFF0C\u52A0\u8F7D\u8C03\u8BD5\u8F85\u52A9\u51FD\u6570\u5230 CAD\uFF0C\u8DF3\u8FC7\u975E\u65AD\u70B9\u524D\u7F6E\u5757",
|
|
6385
|
+
inputSchema: {
|
|
6386
|
+
type: "object",
|
|
6387
|
+
properties: {
|
|
6388
|
+
code: { type: "string", description: "\u539F\u59CB AutoLISP \u4EE3\u7801" },
|
|
6389
|
+
chunks: {
|
|
6390
|
+
type: "array",
|
|
6391
|
+
description: "\u7531\u6269\u5C55\u7AEF\u62C6\u5206\u597D\u7684\u4EE3\u7801\u5757\u5217\u8868",
|
|
6392
|
+
items: {
|
|
6393
|
+
type: "object",
|
|
6394
|
+
properties: {
|
|
6395
|
+
id: { type: "integer", description: "\u5757\u5E8F\u53F7 (1-based)" },
|
|
6396
|
+
line: { type: "integer", description: "\u6E90\u6587\u4EF6\u884C\u53F7" },
|
|
6397
|
+
code: { type: "string", description: "\u5757\u7684 AutoLISP \u4EE3\u7801" },
|
|
6398
|
+
vars: { type: "array", items: { type: "string" }, description: "\u8BE5\u5757\u9700\u6355\u83B7\u7684\u53D8\u91CF\u540D" },
|
|
6399
|
+
isBreakpoint: { type: "boolean", description: "\u8BE5\u884C\u6709\u65AD\u70B9" },
|
|
6400
|
+
isDefunStart: { type: "boolean", description: "\u662F defun \u5B9A\u4E49\u5F00\u5934" }
|
|
6401
|
+
},
|
|
6402
|
+
required: ["id", "line", "code", "vars", "isBreakpoint"]
|
|
6403
|
+
}
|
|
6404
|
+
},
|
|
6405
|
+
encoding: { type: "string", description: "\u7F16\u7801\uFF08\u9ED8\u8BA4 auto\uFF09" }
|
|
6406
|
+
},
|
|
6407
|
+
required: ["code", "chunks"]
|
|
6408
|
+
}
|
|
6409
|
+
},
|
|
6410
|
+
{
|
|
6411
|
+
name: "debug_step",
|
|
6412
|
+
description: "\u6267\u884C\u4E00\u6B65\uFF08step\uFF09\u6216\u7EE7\u7EED\u5230\u4E0B\u4E00\u65AD\u70B9\uFF08continue\uFF09",
|
|
6413
|
+
inputSchema: {
|
|
6414
|
+
type: "object",
|
|
6415
|
+
properties: {
|
|
6416
|
+
sessionId: { type: "string", description: "\u8C03\u8BD5\u4F1A\u8BDD ID" },
|
|
6417
|
+
action: { type: "string", enum: ["step", "continue"], description: "step=\u6267\u884C\u4E00\u4E2A\u5757, continue=\u5230\u4E0B\u4E00\u65AD\u70B9/\u7ED3\u675F" }
|
|
6418
|
+
},
|
|
6419
|
+
required: ["sessionId", "action"]
|
|
6420
|
+
}
|
|
6421
|
+
},
|
|
6422
|
+
{
|
|
6423
|
+
name: "debug_evaluate",
|
|
6424
|
+
description: "\u8C03\u8BD5\u6682\u505C\u65F6\u6C42\u503C AutoLISP \u8868\u8FBE\u5F0F",
|
|
6425
|
+
inputSchema: {
|
|
6426
|
+
type: "object",
|
|
6427
|
+
properties: {
|
|
6428
|
+
sessionId: { type: "string", description: "\u8C03\u8BD5\u4F1A\u8BDD ID" },
|
|
6429
|
+
expression: { type: "string", description: "\u4EFB\u610F AutoLISP \u8868\u8FBE\u5F0F" }
|
|
6430
|
+
},
|
|
6431
|
+
required: ["sessionId", "expression"]
|
|
6432
|
+
}
|
|
6433
|
+
},
|
|
6434
|
+
{
|
|
6435
|
+
name: "debug_get_state",
|
|
6436
|
+
description: "\u67E5\u8BE2\u8C03\u8BD5\u4F1A\u8BDD\u5F53\u524D\u72B6\u6001",
|
|
6437
|
+
inputSchema: {
|
|
6438
|
+
type: "object",
|
|
6439
|
+
properties: {
|
|
6440
|
+
sessionId: { type: "string", description: "\u8C03\u8BD5\u4F1A\u8BDD ID" }
|
|
6441
|
+
},
|
|
6442
|
+
required: ["sessionId"]
|
|
6443
|
+
}
|
|
6444
|
+
},
|
|
6445
|
+
{
|
|
6446
|
+
name: "debug_stop",
|
|
6447
|
+
description: "\u505C\u6B62\u8C03\u8BD5\u4F1A\u8BDD\uFF0C\u6E05\u7406 CAD \u5168\u5C40\u53D8\u91CF\u548C\u8F85\u52A9\u51FD\u6570",
|
|
6448
|
+
inputSchema: {
|
|
6449
|
+
type: "object",
|
|
6450
|
+
properties: {
|
|
6451
|
+
sessionId: { type: "string", description: "\u8C03\u8BD5\u4F1A\u8BDD ID" }
|
|
6452
|
+
},
|
|
6453
|
+
required: ["sessionId"]
|
|
6454
|
+
}
|
|
6455
|
+
}
|
|
6456
|
+
];
|
|
6457
|
+
}
|
|
6458
|
+
});
|
|
6459
|
+
|
|
6377
6460
|
// src/tools/index.js
|
|
6378
6461
|
function addAnnotations(tool) {
|
|
6379
6462
|
const isDeprecated = DEPRECATED_TOOLS.has(tool.name);
|
|
@@ -6398,7 +6481,7 @@ function addAnnotations(tool) {
|
|
|
6398
6481
|
}
|
|
6399
6482
|
};
|
|
6400
6483
|
}
|
|
6401
|
-
var READ_ONLY_TOOLS, DEPRECATED_TOOLS, EXTRA_DESTRUCTIVE, IDEMPOTENT_WRITE_TOOLS, OPEN_WORLD_TOOLS,
|
|
6484
|
+
var READ_ONLY_TOOLS, DEPRECATED_TOOLS, EXTRA_DESTRUCTIVE, IDEMPOTENT_WRITE_TOOLS, OPEN_WORLD_TOOLS, tools42, toolsByName;
|
|
6402
6485
|
var init_tools = __esm({
|
|
6403
6486
|
"src/tools/index.js"() {
|
|
6404
6487
|
init_cad_tools();
|
|
@@ -6441,6 +6524,7 @@ var init_tools = __esm({
|
|
|
6441
6524
|
init_context_tools();
|
|
6442
6525
|
init_batch_transaction_tools();
|
|
6443
6526
|
init_lint_tools();
|
|
6527
|
+
init_debug_tools();
|
|
6444
6528
|
READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
6445
6529
|
"get_cad_info",
|
|
6446
6530
|
"get_platform_info",
|
|
@@ -6523,7 +6607,8 @@ var init_tools = __esm({
|
|
|
6523
6607
|
"analyze_lisp_code",
|
|
6524
6608
|
"format_lisp_code",
|
|
6525
6609
|
"list_lint_rules",
|
|
6526
|
-
"lint_project"
|
|
6610
|
+
"lint_project",
|
|
6611
|
+
"debug_get_state"
|
|
6527
6612
|
]);
|
|
6528
6613
|
DEPRECATED_TOOLS = /* @__PURE__ */ new Set([]);
|
|
6529
6614
|
EXTRA_DESTRUCTIVE = /* @__PURE__ */ new Set([
|
|
@@ -6579,7 +6664,7 @@ var init_tools = __esm({
|
|
|
6579
6664
|
"import_page_setup",
|
|
6580
6665
|
"load_linetype"
|
|
6581
6666
|
]);
|
|
6582
|
-
|
|
6667
|
+
tools42 = [
|
|
6583
6668
|
...tools,
|
|
6584
6669
|
...tools2,
|
|
6585
6670
|
...tools3,
|
|
@@ -6619,9 +6704,10 @@ var init_tools = __esm({
|
|
|
6619
6704
|
...tools38,
|
|
6620
6705
|
...tools39,
|
|
6621
6706
|
...tools37,
|
|
6622
|
-
...tools40
|
|
6707
|
+
...tools40,
|
|
6708
|
+
...tools41
|
|
6623
6709
|
].map(addAnnotations);
|
|
6624
|
-
toolsByName = new Map(
|
|
6710
|
+
toolsByName = new Map(tools42.map((t) => [t.name, t]));
|
|
6625
6711
|
}
|
|
6626
6712
|
});
|
|
6627
6713
|
|
|
@@ -6674,7 +6760,7 @@ function parseLispList(str) {
|
|
|
6674
6760
|
});
|
|
6675
6761
|
}
|
|
6676
6762
|
function createMcpServer(handlers = {}) {
|
|
6677
|
-
const { tools:
|
|
6763
|
+
const { tools: tools43 = [], handleToolCall: handleToolCall2 = () => ({ content: [] }) } = handlers;
|
|
6678
6764
|
const server = new Server(
|
|
6679
6765
|
{ name: SERVER_NAME, version: SERVER_VERSION },
|
|
6680
6766
|
{
|
|
@@ -6697,8 +6783,8 @@ function createMcpServer(handlers = {}) {
|
|
|
6697
6783
|
const params = request.params || {};
|
|
6698
6784
|
const cursor = decodeCursor(params.cursor);
|
|
6699
6785
|
const PAGE_SIZE = 100;
|
|
6700
|
-
const page =
|
|
6701
|
-
const nextCursor = cursor + PAGE_SIZE <
|
|
6786
|
+
const page = tools43.slice(cursor, cursor + PAGE_SIZE);
|
|
6787
|
+
const nextCursor = cursor + PAGE_SIZE < tools43.length ? encodeCursor(cursor + PAGE_SIZE) : void 0;
|
|
6702
6788
|
return { tools: page, nextCursor };
|
|
6703
6789
|
});
|
|
6704
6790
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -7047,11 +7133,11 @@ function createMcpServer(handlers = {}) {
|
|
|
7047
7133
|
if (p.toLowerCase().startsWith(prefix)) values.push(p);
|
|
7048
7134
|
}
|
|
7049
7135
|
} else if (ref?.type === "tool") {
|
|
7050
|
-
for (const t of
|
|
7136
|
+
for (const t of tools43) {
|
|
7051
7137
|
if (t.name.toLowerCase().startsWith(prefix)) values.push(t.name);
|
|
7052
7138
|
}
|
|
7053
7139
|
} else if (ref?.type === "ref/parameter") {
|
|
7054
|
-
const toolDef =
|
|
7140
|
+
const toolDef = tools43.find((t) => t.name === ref.name);
|
|
7055
7141
|
if (toolDef?.inputSchema?.properties) {
|
|
7056
7142
|
const paramName = argument.name;
|
|
7057
7143
|
const paramDef = toolDef.inputSchema.properties[paramName];
|
|
@@ -8565,6 +8651,359 @@ var init_constraint_handlers = __esm({
|
|
|
8565
8651
|
}
|
|
8566
8652
|
});
|
|
8567
8653
|
|
|
8654
|
+
// src/debug-engine.js
|
|
8655
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
8656
|
+
async function ensureCad() {
|
|
8657
|
+
if (!cad.connected) {
|
|
8658
|
+
log("Debug engine: CAD not connected, attempting auto-connect...");
|
|
8659
|
+
await cad.connect();
|
|
8660
|
+
}
|
|
8661
|
+
if (!cad.connected) {
|
|
8662
|
+
throw new Error("CAD \u672A\u8FDE\u63A5");
|
|
8663
|
+
}
|
|
8664
|
+
}
|
|
8665
|
+
async function createSession(code, chunks, encoding) {
|
|
8666
|
+
if (sessions.size >= MAX_SESSIONS2) {
|
|
8667
|
+
let oldest = null;
|
|
8668
|
+
for (const [id, s] of sessions) {
|
|
8669
|
+
if (!oldest || s.createdAt < oldest.createdAt) oldest = { id, s };
|
|
8670
|
+
}
|
|
8671
|
+
if (oldest) {
|
|
8672
|
+
sessions.delete(oldest.id);
|
|
8673
|
+
log(`Debug session ${oldest.id} evicted (max sessions)`);
|
|
8674
|
+
}
|
|
8675
|
+
}
|
|
8676
|
+
if (!chunks || chunks.length === 0) {
|
|
8677
|
+
throw new Error("Chunks array is empty");
|
|
8678
|
+
}
|
|
8679
|
+
if (chunks.length > MAX_CHUNKS) {
|
|
8680
|
+
throw new Error(`Too many chunks: ${chunks.length} (max ${MAX_CHUNKS})`);
|
|
8681
|
+
}
|
|
8682
|
+
for (const chunk of chunks) {
|
|
8683
|
+
if (typeof chunk.id !== "number" || typeof chunk.code !== "string") {
|
|
8684
|
+
throw new Error("Each chunk must have id (number) and code (string)");
|
|
8685
|
+
}
|
|
8686
|
+
}
|
|
8687
|
+
const sessionId = randomUUID4();
|
|
8688
|
+
const session = new DebugSession(sessionId, code, chunks, encoding);
|
|
8689
|
+
sessions.set(sessionId, session);
|
|
8690
|
+
return sessionId;
|
|
8691
|
+
}
|
|
8692
|
+
function getSession(id) {
|
|
8693
|
+
return sessions.get(id) || null;
|
|
8694
|
+
}
|
|
8695
|
+
async function closeSession(sessionId) {
|
|
8696
|
+
const session = sessions.get(sessionId);
|
|
8697
|
+
if (!session) return false;
|
|
8698
|
+
try {
|
|
8699
|
+
if (cad.connected) {
|
|
8700
|
+
await cad.sendCommand(CLEANUP_CODE + "\n");
|
|
8701
|
+
}
|
|
8702
|
+
} catch (e) {
|
|
8703
|
+
log(`Debug cleanup warning: ${e.message}`);
|
|
8704
|
+
}
|
|
8705
|
+
sessions.delete(sessionId);
|
|
8706
|
+
return true;
|
|
8707
|
+
}
|
|
8708
|
+
async function loadHelpers(session) {
|
|
8709
|
+
await ensureCad();
|
|
8710
|
+
try {
|
|
8711
|
+
await cad.sendCommand(HELPER_DEFUNS + "\n");
|
|
8712
|
+
} catch (e) {
|
|
8713
|
+
throw new Error(`Failed to load debug helpers: ${e.message}`);
|
|
8714
|
+
}
|
|
8715
|
+
}
|
|
8716
|
+
async function fastForward(session) {
|
|
8717
|
+
await ensureCad();
|
|
8718
|
+
session.state = "running";
|
|
8719
|
+
while (session.currentIndex < session.totalChunks) {
|
|
8720
|
+
const chunk = session.chunks[session.currentIndex];
|
|
8721
|
+
if (chunk.isBreakpoint) break;
|
|
8722
|
+
try {
|
|
8723
|
+
await cad.sendCommandWithResult(chunk.code, session.encoding);
|
|
8724
|
+
} catch (e) {
|
|
8725
|
+
session.state = "error";
|
|
8726
|
+
session.error = `Fast-forward error at chunk ${chunk.id}: ${e.message}`;
|
|
8727
|
+
throw new Error(session.error);
|
|
8728
|
+
}
|
|
8729
|
+
session.currentIndex++;
|
|
8730
|
+
}
|
|
8731
|
+
if (session.currentIndex >= session.totalChunks) {
|
|
8732
|
+
session.state = "done";
|
|
8733
|
+
return {
|
|
8734
|
+
done: true,
|
|
8735
|
+
finalResult: session.finalResult
|
|
8736
|
+
};
|
|
8737
|
+
}
|
|
8738
|
+
session.state = "paused";
|
|
8739
|
+
return {
|
|
8740
|
+
done: false,
|
|
8741
|
+
pausedAt: {
|
|
8742
|
+
id: session.chunks[session.currentIndex].id,
|
|
8743
|
+
line: session.chunks[session.currentIndex].line
|
|
8744
|
+
}
|
|
8745
|
+
};
|
|
8746
|
+
}
|
|
8747
|
+
async function executeStep(session) {
|
|
8748
|
+
await ensureCad();
|
|
8749
|
+
if (session.state !== "paused" && session.state !== "ready") {
|
|
8750
|
+
throw new Error(`Invalid state: ${session.state} (expected paused or ready)`);
|
|
8751
|
+
}
|
|
8752
|
+
if (session.currentIndex >= session.totalChunks) {
|
|
8753
|
+
session.state = "done";
|
|
8754
|
+
return { done: true, finalResult: session.finalResult };
|
|
8755
|
+
}
|
|
8756
|
+
const chunk = session.chunks[session.currentIndex];
|
|
8757
|
+
const vars = chunk.vars || [];
|
|
8758
|
+
session.state = "running";
|
|
8759
|
+
let rawResult;
|
|
8760
|
+
try {
|
|
8761
|
+
const varCapture = vars.length > 0 ? `(mapcar (function (lambda (v) (list (vl-prin1-to-string v) (if (boundp v) (vl-prin1-to-string (eval v)) nil)))) (list ${vars.map((v) => `'${v}`).join(" ")})` : "nil";
|
|
8762
|
+
const lispCode = `(progn
|
|
8763
|
+
(setq @::dbg/result (progn ${chunk.code}))
|
|
8764
|
+
(list
|
|
8765
|
+
(vl-prin1-to-string @::dbg/result)
|
|
8766
|
+
${varCapture}))`;
|
|
8767
|
+
rawResult = await cad.sendCommandWithResult(lispCode, session.encoding);
|
|
8768
|
+
} catch (e) {
|
|
8769
|
+
session.state = "error";
|
|
8770
|
+
session.error = `Step error at chunk ${chunk.id}: ${e.message}`;
|
|
8771
|
+
throw new Error(session.error);
|
|
8772
|
+
}
|
|
8773
|
+
session.currentIndex++;
|
|
8774
|
+
session.finalResult = rawResult;
|
|
8775
|
+
let parsedResult = rawResult;
|
|
8776
|
+
let variables = [];
|
|
8777
|
+
try {
|
|
8778
|
+
const parsed = parseLispRecursive(rawResult);
|
|
8779
|
+
if (Array.isArray(parsed) && parsed.length >= 2) {
|
|
8780
|
+
parsedResult = parsed[0] !== null ? String(parsed[0]) : "nil";
|
|
8781
|
+
if (Array.isArray(parsed[1])) {
|
|
8782
|
+
variables = parsed[1].map((item) => {
|
|
8783
|
+
if (Array.isArray(item) && item.length >= 2) {
|
|
8784
|
+
return { name: String(item[0] || ""), value: item[1] !== null ? String(item[1]) : "nil" };
|
|
8785
|
+
}
|
|
8786
|
+
return null;
|
|
8787
|
+
}).filter(Boolean);
|
|
8788
|
+
}
|
|
8789
|
+
}
|
|
8790
|
+
} catch {
|
|
8791
|
+
parsedResult = rawResult || "nil";
|
|
8792
|
+
}
|
|
8793
|
+
const checkpoint = {
|
|
8794
|
+
id: chunk.id,
|
|
8795
|
+
line: chunk.line,
|
|
8796
|
+
variables,
|
|
8797
|
+
result: parsedResult
|
|
8798
|
+
};
|
|
8799
|
+
session.lastCheckpoint = checkpoint;
|
|
8800
|
+
if (session.currentIndex >= session.totalChunks) {
|
|
8801
|
+
session.state = "done";
|
|
8802
|
+
return {
|
|
8803
|
+
done: true,
|
|
8804
|
+
checkpoint,
|
|
8805
|
+
finalResult: parsedResult
|
|
8806
|
+
};
|
|
8807
|
+
}
|
|
8808
|
+
session.state = "paused";
|
|
8809
|
+
return { done: false, checkpoint };
|
|
8810
|
+
}
|
|
8811
|
+
async function continueExecution(session) {
|
|
8812
|
+
await ensureCad();
|
|
8813
|
+
if (session.state !== "paused" && session.state !== "ready") {
|
|
8814
|
+
throw new Error(`Invalid state: ${session.state} (expected paused or ready)`);
|
|
8815
|
+
}
|
|
8816
|
+
while (session.currentIndex < session.totalChunks) {
|
|
8817
|
+
const chunk = session.chunks[session.currentIndex];
|
|
8818
|
+
if (chunk.isBreakpoint) {
|
|
8819
|
+
return await executeStep(session);
|
|
8820
|
+
}
|
|
8821
|
+
try {
|
|
8822
|
+
await cad.sendCommandWithResult(chunk.code, session.encoding);
|
|
8823
|
+
} catch (e) {
|
|
8824
|
+
session.state = "error";
|
|
8825
|
+
session.error = `Continue error at chunk ${chunk.id}: ${e.message}`;
|
|
8826
|
+
throw new Error(session.error);
|
|
8827
|
+
}
|
|
8828
|
+
session.currentIndex++;
|
|
8829
|
+
session.finalResult = null;
|
|
8830
|
+
}
|
|
8831
|
+
session.state = "done";
|
|
8832
|
+
return { done: true, finalResult: session.finalResult };
|
|
8833
|
+
}
|
|
8834
|
+
async function evaluateExpression(session, expression) {
|
|
8835
|
+
await ensureCad();
|
|
8836
|
+
if (session.state !== "paused") {
|
|
8837
|
+
throw new Error(`Invalid state: ${session.state} (expected paused)`);
|
|
8838
|
+
}
|
|
8839
|
+
try {
|
|
8840
|
+
const result = await cad.sendCommandWithResult(`(vl-prin1-to-string ${expression})`, session.encoding);
|
|
8841
|
+
return { value: result || "nil" };
|
|
8842
|
+
} catch (e) {
|
|
8843
|
+
return { error: `CAD error: ${e.message}` };
|
|
8844
|
+
}
|
|
8845
|
+
}
|
|
8846
|
+
var sessions, MAX_SESSIONS2, MAX_CHUNKS, HELPER_DEFUNS, CLEANUP_CODE, DebugSession;
|
|
8847
|
+
var init_debug_engine = __esm({
|
|
8848
|
+
"src/debug-engine.js"() {
|
|
8849
|
+
init_cad();
|
|
8850
|
+
init_logger();
|
|
8851
|
+
init_handler_utils();
|
|
8852
|
+
sessions = /* @__PURE__ */ new Map();
|
|
8853
|
+
MAX_SESSIONS2 = 10;
|
|
8854
|
+
MAX_CHUNKS = 500;
|
|
8855
|
+
HELPER_DEFUNS = `
|
|
8856
|
+
(defun @::dbg/exec-chunk (chunk-code var-names)
|
|
8857
|
+
(setq @::dbg/result (eval (read chunk-code)))
|
|
8858
|
+
(if var-names
|
|
8859
|
+
(setq @::dbg/snapshot
|
|
8860
|
+
(mapcar
|
|
8861
|
+
(function (lambda (v)
|
|
8862
|
+
(list (vl-prin1-to-string v)
|
|
8863
|
+
(if (boundp v) (vl-prin1-to-string (eval v)) nil))))
|
|
8864
|
+
var-names))
|
|
8865
|
+
(setq @::dbg/snapshot nil))
|
|
8866
|
+
(list @::dbg/result @::dbg/snapshot))
|
|
8867
|
+
`;
|
|
8868
|
+
CLEANUP_CODE = `
|
|
8869
|
+
(if (not (vl-catch-all-error-p (vl-catch-all-apply (function (lambda ()
|
|
8870
|
+
(mapcar (function (lambda (s) (set s nil)))
|
|
8871
|
+
(quote (@::dbg/result @::dbg/snapshot @::dbg/state @::dbg/chunks @::dbg/idx @::dbg/encoding))))))))
|
|
8872
|
+
(princ "ok"))
|
|
8873
|
+
`;
|
|
8874
|
+
DebugSession = class {
|
|
8875
|
+
constructor(sessionId, code, chunks, encoding) {
|
|
8876
|
+
this.sessionId = sessionId;
|
|
8877
|
+
this.code = code;
|
|
8878
|
+
this.chunks = chunks;
|
|
8879
|
+
this.totalChunks = chunks.length;
|
|
8880
|
+
this.currentIndex = 0;
|
|
8881
|
+
this.encoding = encoding || null;
|
|
8882
|
+
this.state = "ready";
|
|
8883
|
+
this.lastCheckpoint = null;
|
|
8884
|
+
this.finalResult = null;
|
|
8885
|
+
this.createdAt = Date.now();
|
|
8886
|
+
this.error = null;
|
|
8887
|
+
}
|
|
8888
|
+
};
|
|
8889
|
+
}
|
|
8890
|
+
});
|
|
8891
|
+
|
|
8892
|
+
// src/handlers/debug-handlers.js
|
|
8893
|
+
var debug_handlers_exports = {};
|
|
8894
|
+
__export(debug_handlers_exports, {
|
|
8895
|
+
debugEvaluate: () => debugEvaluate,
|
|
8896
|
+
debugGetState: () => debugGetState,
|
|
8897
|
+
debugStart: () => debugStart,
|
|
8898
|
+
debugStep: () => debugStep,
|
|
8899
|
+
debugStop: () => debugStop
|
|
8900
|
+
});
|
|
8901
|
+
async function debugGetState(args) {
|
|
8902
|
+
try {
|
|
8903
|
+
const { sessionId } = args || {};
|
|
8904
|
+
if (!sessionId) return mcpError("Missing required argument: sessionId");
|
|
8905
|
+
const session = getSession(sessionId);
|
|
8906
|
+
if (!session) return mcpError(`Debug session not found: ${sessionId}`);
|
|
8907
|
+
const checkpoint = session.lastCheckpoint;
|
|
8908
|
+
return mcpSuccess(JSON.stringify({
|
|
8909
|
+
state: session.state,
|
|
8910
|
+
currentIndex: session.currentIndex,
|
|
8911
|
+
totalChunks: session.totalChunks,
|
|
8912
|
+
currentCheckpoint: checkpoint || void 0,
|
|
8913
|
+
error: session.error
|
|
8914
|
+
}));
|
|
8915
|
+
} catch (e) {
|
|
8916
|
+
return mcpError(e.message);
|
|
8917
|
+
}
|
|
8918
|
+
}
|
|
8919
|
+
async function debugStop(args) {
|
|
8920
|
+
try {
|
|
8921
|
+
const { sessionId } = args || {};
|
|
8922
|
+
if (!sessionId) return mcpError("Missing required argument: sessionId");
|
|
8923
|
+
const session = getSession(sessionId);
|
|
8924
|
+
if (!session) {
|
|
8925
|
+
return mcpError(`Debug session not found: ${sessionId}`);
|
|
8926
|
+
}
|
|
8927
|
+
const ok = await closeSession(sessionId);
|
|
8928
|
+
return mcpSuccess(JSON.stringify({ success: ok }));
|
|
8929
|
+
} catch (e) {
|
|
8930
|
+
return mcpError(e.message);
|
|
8931
|
+
}
|
|
8932
|
+
}
|
|
8933
|
+
var debugStart, debugStep, debugEvaluate;
|
|
8934
|
+
var init_debug_handlers = __esm({
|
|
8935
|
+
"src/handlers/debug-handlers.js"() {
|
|
8936
|
+
init_handler_utils();
|
|
8937
|
+
init_debug_engine();
|
|
8938
|
+
debugStart = withCadConnection(async (args) => {
|
|
8939
|
+
try {
|
|
8940
|
+
const { code, chunks, encoding } = args || {};
|
|
8941
|
+
if (!code) return mcpError("Missing required argument: code");
|
|
8942
|
+
if (!chunks || !Array.isArray(chunks)) return mcpError("Missing required argument: chunks (must be an array)");
|
|
8943
|
+
const sessionId = await createSession(code, chunks, encoding);
|
|
8944
|
+
const session = getSession(sessionId);
|
|
8945
|
+
if (!session) return mcpError("Failed to create debug session");
|
|
8946
|
+
await loadHelpers(session);
|
|
8947
|
+
const ffResult = await fastForward(session);
|
|
8948
|
+
if (session.state === "error") {
|
|
8949
|
+
await closeSession(sessionId);
|
|
8950
|
+
return mcpError(session.error);
|
|
8951
|
+
}
|
|
8952
|
+
return mcpSuccess(JSON.stringify({
|
|
8953
|
+
sessionId,
|
|
8954
|
+
totalChunks: session.totalChunks,
|
|
8955
|
+
...ffResult
|
|
8956
|
+
}));
|
|
8957
|
+
} catch (e) {
|
|
8958
|
+
return mcpError(e.message);
|
|
8959
|
+
}
|
|
8960
|
+
});
|
|
8961
|
+
debugStep = withCadConnection(async (args) => {
|
|
8962
|
+
try {
|
|
8963
|
+
const { sessionId, action } = args || {};
|
|
8964
|
+
if (!sessionId) return mcpError("Missing required argument: sessionId");
|
|
8965
|
+
if (!action) return mcpError("Missing required argument: action");
|
|
8966
|
+
const session = getSession(sessionId);
|
|
8967
|
+
if (!session) return mcpError(`Debug session not found: ${sessionId}`);
|
|
8968
|
+
if (session.state !== "paused" && session.state !== "ready") {
|
|
8969
|
+
return mcpError(`Invalid state: ${session.state} (expected paused or ready)`);
|
|
8970
|
+
}
|
|
8971
|
+
let result;
|
|
8972
|
+
if (action === "step") {
|
|
8973
|
+
result = await executeStep(session);
|
|
8974
|
+
} else if (action === "continue") {
|
|
8975
|
+
result = await continueExecution(session);
|
|
8976
|
+
} else {
|
|
8977
|
+
return mcpError(`Invalid action: ${action} (expected step or continue)`);
|
|
8978
|
+
}
|
|
8979
|
+
if (session.state === "error") {
|
|
8980
|
+
return mcpError(session.error);
|
|
8981
|
+
}
|
|
8982
|
+
return mcpSuccess(JSON.stringify(result));
|
|
8983
|
+
} catch (e) {
|
|
8984
|
+
return mcpError(e.message);
|
|
8985
|
+
}
|
|
8986
|
+
});
|
|
8987
|
+
debugEvaluate = withCadConnection(async (args) => {
|
|
8988
|
+
try {
|
|
8989
|
+
const { sessionId, expression } = args || {};
|
|
8990
|
+
if (!sessionId) return mcpError("Missing required argument: sessionId");
|
|
8991
|
+
if (!expression) return mcpError("Missing required argument: expression");
|
|
8992
|
+
const session = getSession(sessionId);
|
|
8993
|
+
if (!session) return mcpError(`Debug session not found: ${sessionId}`);
|
|
8994
|
+
if (session.state !== "paused") {
|
|
8995
|
+
return mcpError(`Invalid state: ${session.state} (expected paused)`);
|
|
8996
|
+
}
|
|
8997
|
+
const result = await evaluateExpression(session, expression);
|
|
8998
|
+
if (result.error) return mcpError(result.error);
|
|
8999
|
+
return mcpSuccess(JSON.stringify({ value: result.value }));
|
|
9000
|
+
} catch (e) {
|
|
9001
|
+
return mcpError(e.message);
|
|
9002
|
+
}
|
|
9003
|
+
});
|
|
9004
|
+
}
|
|
9005
|
+
});
|
|
9006
|
+
|
|
8568
9007
|
// src/handlers/dim-hatch-handlers.js
|
|
8569
9008
|
var dim_hatch_handlers_exports = {};
|
|
8570
9009
|
__export(dim_hatch_handlers_exports, {
|
|
@@ -13845,6 +14284,7 @@ var init_ = __esm({
|
|
|
13845
14284
|
"./handlers/block-handlers.js": () => Promise.resolve().then(() => (init_block_handlers(), block_handlers_exports)),
|
|
13846
14285
|
"./handlers/cad-handlers.js": () => Promise.resolve().then(() => (init_cad_handlers(), cad_handlers_exports)),
|
|
13847
14286
|
"./handlers/constraint-handlers.js": () => Promise.resolve().then(() => (init_constraint_handlers(), constraint_handlers_exports)),
|
|
14287
|
+
"./handlers/debug-handlers.js": () => Promise.resolve().then(() => (init_debug_handlers(), debug_handlers_exports)),
|
|
13848
14288
|
"./handlers/dim-hatch-handlers.js": () => Promise.resolve().then(() => (init_dim_hatch_handlers(), dim_hatch_handlers_exports)),
|
|
13849
14289
|
"./handlers/draw-handlers.js": () => Promise.resolve().then(() => (init_draw_handlers(), draw_handlers_exports)),
|
|
13850
14290
|
"./handlers/edit-handlers.js": () => Promise.resolve().then(() => (init_edit_handlers(), edit_handlers_exports)),
|
|
@@ -14850,54 +15290,54 @@ var init_lisp_sandbox = __esm({
|
|
|
14850
15290
|
});
|
|
14851
15291
|
|
|
14852
15292
|
// src/repl-engine.js
|
|
14853
|
-
import { randomUUID as
|
|
15293
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
14854
15294
|
function ensureCleanup2() {
|
|
14855
15295
|
if (cleanupTimer2) return;
|
|
14856
15296
|
cleanupTimer2 = setInterval(() => {
|
|
14857
15297
|
const now = Date.now();
|
|
14858
|
-
for (const [id, session] of
|
|
15298
|
+
for (const [id, session] of sessions2) {
|
|
14859
15299
|
if (now - session.createdAt > SESSION_TTL) {
|
|
14860
|
-
|
|
15300
|
+
sessions2.delete(id);
|
|
14861
15301
|
log(`REPL session ${id} expired (TTL)`);
|
|
14862
15302
|
}
|
|
14863
15303
|
}
|
|
14864
15304
|
}, CLEANUP_INTERVAL3);
|
|
14865
15305
|
cleanupTimer2.unref();
|
|
14866
15306
|
}
|
|
14867
|
-
function
|
|
14868
|
-
if (
|
|
15307
|
+
function createSession2() {
|
|
15308
|
+
if (sessions2.size >= MAX_SESSIONS3) {
|
|
14869
15309
|
let oldest = null;
|
|
14870
|
-
for (const [id, s] of
|
|
15310
|
+
for (const [id, s] of sessions2) {
|
|
14871
15311
|
if (!oldest || s.lastActivity < oldest.lastActivity) oldest = { id, s };
|
|
14872
15312
|
}
|
|
14873
15313
|
if (oldest) {
|
|
14874
|
-
|
|
15314
|
+
sessions2.delete(oldest.id);
|
|
14875
15315
|
log(`REPL session ${oldest.id} evicted (max sessions reached)`);
|
|
14876
15316
|
}
|
|
14877
15317
|
}
|
|
14878
15318
|
ensureCleanup2();
|
|
14879
|
-
const sessionId =
|
|
15319
|
+
const sessionId = randomUUID5();
|
|
14880
15320
|
const session = new ReplSession(sessionId);
|
|
14881
|
-
|
|
15321
|
+
sessions2.set(sessionId, session);
|
|
14882
15322
|
return sessionId;
|
|
14883
15323
|
}
|
|
14884
15324
|
async function executeInSession(sessionId, code) {
|
|
14885
|
-
let session =
|
|
15325
|
+
let session = sessions2.get(sessionId);
|
|
14886
15326
|
if (!session) {
|
|
14887
|
-
sessionId =
|
|
14888
|
-
session =
|
|
15327
|
+
sessionId = createSession2();
|
|
15328
|
+
session = sessions2.get(sessionId);
|
|
14889
15329
|
}
|
|
14890
15330
|
const result = await session.execute(code);
|
|
14891
15331
|
return { sessionId, result, history: session.history };
|
|
14892
15332
|
}
|
|
14893
15333
|
function getHistory(sessionId) {
|
|
14894
|
-
const session =
|
|
15334
|
+
const session = sessions2.get(sessionId);
|
|
14895
15335
|
if (!session) return null;
|
|
14896
15336
|
return session.history;
|
|
14897
15337
|
}
|
|
14898
|
-
function
|
|
15338
|
+
function listSessions2() {
|
|
14899
15339
|
const result = [];
|
|
14900
|
-
for (const [id, session] of
|
|
15340
|
+
for (const [id, session] of sessions2) {
|
|
14901
15341
|
result.push({
|
|
14902
15342
|
sessionId: id,
|
|
14903
15343
|
historyCount: session.history.length,
|
|
@@ -14907,20 +15347,20 @@ function listSessions() {
|
|
|
14907
15347
|
}
|
|
14908
15348
|
return result;
|
|
14909
15349
|
}
|
|
14910
|
-
function
|
|
14911
|
-
const session =
|
|
15350
|
+
function closeSession2(id) {
|
|
15351
|
+
const session = sessions2.get(id);
|
|
14912
15352
|
if (!session) return false;
|
|
14913
|
-
|
|
15353
|
+
sessions2.delete(id);
|
|
14914
15354
|
return true;
|
|
14915
15355
|
}
|
|
14916
|
-
var
|
|
15356
|
+
var sessions2, MAX_SESSIONS3, SESSION_TTL, CLEANUP_INTERVAL3, cleanupTimer2, SETQ_RE, ReplSession;
|
|
14917
15357
|
var init_repl_engine = __esm({
|
|
14918
15358
|
"src/repl-engine.js"() {
|
|
14919
15359
|
init_cad();
|
|
14920
15360
|
init_logger();
|
|
14921
15361
|
init_lint_analyzer();
|
|
14922
|
-
|
|
14923
|
-
|
|
15362
|
+
sessions2 = /* @__PURE__ */ new Map();
|
|
15363
|
+
MAX_SESSIONS3 = 50;
|
|
14924
15364
|
SESSION_TTL = 30 * 60 * 1e3;
|
|
14925
15365
|
CLEANUP_INTERVAL3 = 5 * 60 * 1e3;
|
|
14926
15366
|
cleanupTimer2 = null;
|
|
@@ -15389,7 +15829,7 @@ function registerTool(toolDef, handler) {
|
|
|
15389
15829
|
}
|
|
15390
15830
|
customTools.push(toolDef);
|
|
15391
15831
|
customHandlers.set(toolDef.name, handler);
|
|
15392
|
-
|
|
15832
|
+
tools42.push(toolDef);
|
|
15393
15833
|
return true;
|
|
15394
15834
|
}
|
|
15395
15835
|
function callCustomTool(name, args) {
|
|
@@ -15907,10 +16347,10 @@ ${CAD_PLATFORMS.join("\n")}
|
|
|
15907
16347
|
return { content: [{ type: "text", text: JSON.stringify(history) }] };
|
|
15908
16348
|
},
|
|
15909
16349
|
lisp_repl_list: () => {
|
|
15910
|
-
return { content: [{ type: "text", text: JSON.stringify(
|
|
16350
|
+
return { content: [{ type: "text", text: JSON.stringify(listSessions2()) }] };
|
|
15911
16351
|
},
|
|
15912
16352
|
lisp_repl_close: (a) => {
|
|
15913
|
-
const ok =
|
|
16353
|
+
const ok = closeSession2(a.sessionId);
|
|
15914
16354
|
return { content: [{ type: "text", text: JSON.stringify({ success: ok }) }] };
|
|
15915
16355
|
},
|
|
15916
16356
|
// === Streaming ===
|
|
@@ -15982,6 +16422,12 @@ ${CAD_PLATFORMS.join("\n")}
|
|
|
15982
16422
|
return { content: [{ type: "text", text: `\u9879\u76EE\u5206\u6790\u5931\u8D25: ${e.message}` }], isError: true };
|
|
15983
16423
|
}
|
|
15984
16424
|
},
|
|
16425
|
+
// === Debug ===
|
|
16426
|
+
debug_start: lazy("debug_start", (a) => a),
|
|
16427
|
+
debug_step: lazy("debug_step", (a) => a),
|
|
16428
|
+
debug_evaluate: lazy("debug_evaluate", (a) => a),
|
|
16429
|
+
debug_get_state: lazy("debug_get_state", (a) => a),
|
|
16430
|
+
debug_stop: lazy("debug_stop", (a) => a),
|
|
15985
16431
|
// === Sandbox (Security) ===
|
|
15986
16432
|
sandbox_validate: (a) => {
|
|
15987
16433
|
const result = validateLispCode(a.code, a.sessionId || null);
|
|
@@ -16075,14 +16521,14 @@ ${CAD_PLATFORMS.join("\n")}
|
|
|
16075
16521
|
// === Meta Tools ===
|
|
16076
16522
|
search_tools: async (a) => {
|
|
16077
16523
|
const q = (a.query || "").toLowerCase();
|
|
16078
|
-
const results =
|
|
16524
|
+
const results = tools42.filter((t) => t.name.toLowerCase().includes(q) || (t.description || "").toLowerCase().includes(q));
|
|
16079
16525
|
const text = results.length ? `\u627E\u5230 ${results.length} \u4E2A\u5DE5\u5177:
|
|
16080
16526
|
${results.map((t) => `${t.name}: ${t.description}`).join("\n")}` : `\u672A\u627E\u5230\u5305\u542B "${a.query}" \u7684\u5DE5\u5177`;
|
|
16081
16527
|
return { content: [{ type: "text", text }] };
|
|
16082
16528
|
},
|
|
16083
16529
|
list_tools_by_category: async (a) => {
|
|
16084
16530
|
const categories = {};
|
|
16085
|
-
for (const t of
|
|
16531
|
+
for (const t of tools42) {
|
|
16086
16532
|
let cat = "\u5176\u4ED6";
|
|
16087
16533
|
const n = t.name;
|
|
16088
16534
|
if (/^(draw_|create_3d_|create_box|create_cone|create_cylinder|create_sphere|create_torus|create_wedge|extrude_|revolve_|boolean_|slice_solid|thicken_|offset_surface|create_loft_|create_region)/.test(n)) cat = "\u7ED8\u56FE\u4E0E3D";
|
|
@@ -16418,7 +16864,7 @@ var init_mcp_server_state = __esm({
|
|
|
16418
16864
|
progressContext = new AsyncLocalStorage();
|
|
16419
16865
|
sessionServers = /* @__PURE__ */ new Map();
|
|
16420
16866
|
sessionTransports = /* @__PURE__ */ new Map();
|
|
16421
|
-
mcpHandlers = { tools:
|
|
16867
|
+
mcpHandlers = { tools: tools42, handleToolCall };
|
|
16422
16868
|
_stdioServer = null;
|
|
16423
16869
|
_pendingResourceUpdated = /* @__PURE__ */ new Set();
|
|
16424
16870
|
_resourceUpdatedTimer = null;
|
|
@@ -16642,7 +17088,7 @@ function propertyPairsToObject(pairs) {
|
|
|
16642
17088
|
}
|
|
16643
17089
|
return obj;
|
|
16644
17090
|
}
|
|
16645
|
-
async function
|
|
17091
|
+
async function ensureCad2() {
|
|
16646
17092
|
if (!cad.connected) await cad.connect();
|
|
16647
17093
|
if (!cad.connected) throw createError(ERROR_CODES.CAD_NOT_CONNECTED);
|
|
16648
17094
|
}
|
|
@@ -16810,7 +17256,7 @@ function parseTableRecord(rec, tableName) {
|
|
|
16810
17256
|
return obj.name ? obj : null;
|
|
16811
17257
|
}
|
|
16812
17258
|
async function getEntityByHandle(handle) {
|
|
16813
|
-
await
|
|
17259
|
+
await ensureCad2();
|
|
16814
17260
|
const code = `(progn
|
|
16815
17261
|
(vl-load-com)
|
|
16816
17262
|
(if (setq ent (handent "${escapeLispString(handle)}"))
|
|
@@ -16920,7 +17366,7 @@ async function getEntities(params = {}) {
|
|
|
16920
17366
|
const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
|
|
16921
17367
|
const cached = getCached(cacheKey);
|
|
16922
17368
|
if (cached) return cached;
|
|
16923
|
-
await
|
|
17369
|
+
await ensureCad2();
|
|
16924
17370
|
const hasFilter = params.type || params.layer || params.bbox;
|
|
16925
17371
|
if (!hasFilter) {
|
|
16926
17372
|
return await getEntitiesSummary(cacheKey);
|
|
@@ -16956,7 +17402,7 @@ async function getTextContent(params = {}) {
|
|
|
16956
17402
|
const cacheKey = `dwg:text-content:${JSON.stringify(params)}`;
|
|
16957
17403
|
const cached = getCached(cacheKey);
|
|
16958
17404
|
if (cached) return cached;
|
|
16959
|
-
await
|
|
17405
|
+
await ensureCad2();
|
|
16960
17406
|
const offset = Math.max(0, parseInt(params.offset) || 0);
|
|
16961
17407
|
const limit = Math.min(Math.max(1, parseInt(params.limit) || 5e3), 5e3);
|
|
16962
17408
|
try {
|
|
@@ -17106,7 +17552,7 @@ async function combineText(params = {}) {
|
|
|
17106
17552
|
return { total: blocks.length, blocks, medianHeight: mh };
|
|
17107
17553
|
}
|
|
17108
17554
|
async function getDwgName() {
|
|
17109
|
-
await
|
|
17555
|
+
await ensureCad2();
|
|
17110
17556
|
try {
|
|
17111
17557
|
const code = `(vl-princ-to-string (getvar "dwgname"))`;
|
|
17112
17558
|
const name = await cad.sendCommandWithResult(code);
|
|
@@ -17116,7 +17562,7 @@ async function getDwgName() {
|
|
|
17116
17562
|
}
|
|
17117
17563
|
}
|
|
17118
17564
|
async function getDwgPath() {
|
|
17119
|
-
await
|
|
17565
|
+
await ensureCad2();
|
|
17120
17566
|
try {
|
|
17121
17567
|
const code = `(progn
|
|
17122
17568
|
(setq prefix (vl-princ-to-string (getvar "dwgprefix")))
|
|
@@ -17149,7 +17595,7 @@ async function getBlockRefs(params = {}) {
|
|
|
17149
17595
|
const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
|
|
17150
17596
|
const cached = getCached(cacheKey);
|
|
17151
17597
|
if (cached) return cached;
|
|
17152
|
-
await
|
|
17598
|
+
await ensureCad2();
|
|
17153
17599
|
try {
|
|
17154
17600
|
const code = buildBlockRefsCode(params.blockName);
|
|
17155
17601
|
const resultStr = await cad.sendCommandWithResult(code);
|
|
@@ -17211,7 +17657,7 @@ async function getTables(params = {}) {
|
|
|
17211
17657
|
const cacheKey = `dwg:tbl:${tblName}`;
|
|
17212
17658
|
const cached = getCached(cacheKey);
|
|
17213
17659
|
if (cached) return cached;
|
|
17214
|
-
await
|
|
17660
|
+
await ensureCad2();
|
|
17215
17661
|
try {
|
|
17216
17662
|
const code = buildTablesCode(tblName);
|
|
17217
17663
|
const resultStr = await cad.sendCommandWithResult(code);
|
|
@@ -17293,7 +17739,7 @@ async function getPackages(filterName = null) {
|
|
|
17293
17739
|
const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
|
|
17294
17740
|
const cached = getCached(cacheKey);
|
|
17295
17741
|
if (cached) return cached;
|
|
17296
|
-
await
|
|
17742
|
+
await ensureCad2();
|
|
17297
17743
|
try {
|
|
17298
17744
|
const code = `(mapcar 'cdr @::*local-pkgs*)`;
|
|
17299
17745
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -17366,7 +17812,7 @@ async function getDwgList() {
|
|
|
17366
17812
|
const cacheKey = "cad:dwgs";
|
|
17367
17813
|
const cached = getCached(cacheKey);
|
|
17368
17814
|
if (cached) return cached;
|
|
17369
|
-
await
|
|
17815
|
+
await ensureCad2();
|
|
17370
17816
|
try {
|
|
17371
17817
|
const code = `(progn
|
|
17372
17818
|
(vl-load-com)
|
|
@@ -17436,7 +17882,7 @@ function getCodingStandards() {
|
|
|
17436
17882
|
return data || { error: "\u7F16\u7801\u89C4\u8303\u6587\u4EF6\u52A0\u8F7D\u5931\u8D25" };
|
|
17437
17883
|
}
|
|
17438
17884
|
async function getCadEvents(params) {
|
|
17439
|
-
await
|
|
17885
|
+
await ensureCad2();
|
|
17440
17886
|
try {
|
|
17441
17887
|
const code = `(progn (setq cnt 0) (if (setq ss (ssget "_X")) (setq cnt (sslength ss))) (list (cons "entityCount" cnt) (cons "dwgName" (getvar "dwgname")) (cons "dwgPath" (getvar "dwgprefix"))))`;
|
|
17442
17888
|
const result = await cad.sendCommandWithResult(code);
|
|
@@ -17870,7 +18316,7 @@ init_subscription_manager();
|
|
|
17870
18316
|
init_mcp_server_state();
|
|
17871
18317
|
init_sse_session();
|
|
17872
18318
|
import express from "express";
|
|
17873
|
-
import { randomUUID as
|
|
18319
|
+
import { randomUUID as randomUUID6, createHash } from "crypto";
|
|
17874
18320
|
import fs14 from "fs";
|
|
17875
18321
|
import path17 from "path";
|
|
17876
18322
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
@@ -18058,7 +18504,7 @@ var cachedToolsJson = null;
|
|
|
18058
18504
|
var cachedToolsJsonAt = 0;
|
|
18059
18505
|
function getToolsJson() {
|
|
18060
18506
|
if (cachedToolsJson && Date.now() - cachedToolsJsonAt < 3e4) return cachedToolsJson;
|
|
18061
|
-
cachedToolsJson = JSON.stringify(
|
|
18507
|
+
cachedToolsJson = JSON.stringify(tools42.map((t) => ({
|
|
18062
18508
|
name: t.name,
|
|
18063
18509
|
description: t.description,
|
|
18064
18510
|
inputSchema: t.inputSchema
|
|
@@ -18227,7 +18673,7 @@ function setupRoutes(app) {
|
|
|
18227
18673
|
},
|
|
18228
18674
|
mcp: {
|
|
18229
18675
|
sessions: sessionServers.size,
|
|
18230
|
-
tools:
|
|
18676
|
+
tools: tools42.length,
|
|
18231
18677
|
sseSessions: sseCount
|
|
18232
18678
|
},
|
|
18233
18679
|
pool: {
|
|
@@ -18250,7 +18696,7 @@ function setupRoutes(app) {
|
|
|
18250
18696
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18251
18697
|
cad: { connected: cad.connected, platform: cad.getPlatform?.(), version: cad.getVersion?.(), commandQueueSize: cad._getQueueSize ? cad._getQueueSize() : 0, restartCount: cad._getRestartCount ? cad._getRestartCount() : 0 },
|
|
18252
18698
|
system: { uptime: process.uptime(), memory: { rssMB: Math.round(memUsage.rss / 1024 / 1024), heapUsedMB: Math.round(memUsage.heapUsed / 1024 / 1024), heapTotalMB: Math.round(memUsage.heapTotal / 1024 / 1024) }, cpu: process.cpuUsage() },
|
|
18253
|
-
mcp: { sessions: sessionServers.size, tools:
|
|
18699
|
+
mcp: { sessions: sessionServers.size, tools: tools42.length, sseSessions: sseCount },
|
|
18254
18700
|
pool: poolStats
|
|
18255
18701
|
});
|
|
18256
18702
|
});
|
|
@@ -18288,7 +18734,7 @@ function setupRoutes(app) {
|
|
|
18288
18734
|
app.get("/api/docs", (req, res) => {
|
|
18289
18735
|
const html = loadHtml("api-docs", {
|
|
18290
18736
|
VERSION: SERVER_VERSION,
|
|
18291
|
-
TOOLS_COUNT:
|
|
18737
|
+
TOOLS_COUNT: tools42.length
|
|
18292
18738
|
});
|
|
18293
18739
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
18294
18740
|
res.send(html);
|
|
@@ -18309,7 +18755,7 @@ function setupRoutes(app) {
|
|
|
18309
18755
|
SESSIONS_COUNT: sessionServers.size,
|
|
18310
18756
|
CAD_STATUS_CLASS: cadConnected ? "status-ok" : "status-error",
|
|
18311
18757
|
CAD_STATUS_TEXT: cadStatusText,
|
|
18312
|
-
TOOLS_COUNT:
|
|
18758
|
+
TOOLS_COUNT: tools42.length
|
|
18313
18759
|
});
|
|
18314
18760
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
18315
18761
|
res.send(html);
|
|
@@ -18327,7 +18773,7 @@ function setupRoutes(app) {
|
|
|
18327
18773
|
app.get("/sse", mcpLimiter, handleSse);
|
|
18328
18774
|
app.post("/message", mcpLimiter, handleMessage);
|
|
18329
18775
|
app.get("/cad/events", (req, res) => {
|
|
18330
|
-
const sessionId =
|
|
18776
|
+
const sessionId = randomUUID6();
|
|
18331
18777
|
subscribeEvents(sessionId, res);
|
|
18332
18778
|
req.on("close", () => {
|
|
18333
18779
|
unsubscribeEvents(sessionId);
|
|
@@ -18337,7 +18783,7 @@ function setupRoutes(app) {
|
|
|
18337
18783
|
return app;
|
|
18338
18784
|
}
|
|
18339
18785
|
async function handleMcpPost(req, res) {
|
|
18340
|
-
const sessionId = req.headers["mcp-session-id"] || req.query.sessionId ||
|
|
18786
|
+
const sessionId = req.headers["mcp-session-id"] || req.query.sessionId || randomUUID6();
|
|
18341
18787
|
sessionManager.createSession(sessionId);
|
|
18342
18788
|
const body = req.body;
|
|
18343
18789
|
if (!body) {
|
|
@@ -18405,7 +18851,7 @@ async function getMcpResponse(sessionId, body) {
|
|
|
18405
18851
|
}
|
|
18406
18852
|
async function handleSse(req, res) {
|
|
18407
18853
|
const lastEventId = parseLastEventId(req);
|
|
18408
|
-
let sessionId =
|
|
18854
|
+
let sessionId = randomUUID6();
|
|
18409
18855
|
let resumeMessages = [];
|
|
18410
18856
|
if (lastEventId !== null) {
|
|
18411
18857
|
const existingSession = sessionManager.get(sessionId);
|
|
@@ -18471,7 +18917,7 @@ init_cad();
|
|
|
18471
18917
|
init_constants();
|
|
18472
18918
|
init_tools();
|
|
18473
18919
|
init_subscription_manager();
|
|
18474
|
-
import { randomUUID as
|
|
18920
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
18475
18921
|
import { WebSocketServer } from "ws";
|
|
18476
18922
|
var PING_INTERVAL = 3e4;
|
|
18477
18923
|
var CAD_POLL_INTERVAL = 5e3;
|
|
@@ -18501,7 +18947,7 @@ function sendWelcome(ws, clientId) {
|
|
|
18501
18947
|
server: { name: SERVER_NAME, version: SERVER_VERSION },
|
|
18502
18948
|
capabilities: SERVER_CAPABILITIES,
|
|
18503
18949
|
clientId,
|
|
18504
|
-
toolCount:
|
|
18950
|
+
toolCount: tools42.length,
|
|
18505
18951
|
cadConnected: cad.connected,
|
|
18506
18952
|
cadPlatform: cad.connected ? cad.getPlatform() : null,
|
|
18507
18953
|
cadVersion: cad.connected ? cad.getVersion() : null
|
|
@@ -18668,7 +19114,7 @@ function createWebSocketServer(httpServer) {
|
|
|
18668
19114
|
startCadPolling();
|
|
18669
19115
|
_wss = new WebSocketServer({ server: httpServer, path: "/ws" });
|
|
18670
19116
|
_wss.on("connection", (ws, req) => {
|
|
18671
|
-
const clientId =
|
|
19117
|
+
const clientId = randomUUID7();
|
|
18672
19118
|
connectedClients.set(clientId, ws);
|
|
18673
19119
|
log(`WebSocket connected: ${clientId} (${connectedClients.size} total) from ${req.socket.remoteAddress}`);
|
|
18674
19120
|
sendWelcome(ws, clientId);
|
|
@@ -18875,14 +19321,14 @@ init_logger();
|
|
|
18875
19321
|
init_mcp_handlers();
|
|
18876
19322
|
init_mcp_tools();
|
|
18877
19323
|
import { StreamableHTTPServerTransport as StreamableHTTPServerTransport2 } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
18878
|
-
import { randomUUID as
|
|
19324
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
18879
19325
|
var mcpServer = null;
|
|
18880
19326
|
var streamableTransport = null;
|
|
18881
19327
|
async function initStreamableHttpServer() {
|
|
18882
19328
|
if (mcpServer) return;
|
|
18883
|
-
mcpServer = createMcpServer({ tools:
|
|
19329
|
+
mcpServer = createMcpServer({ tools: tools42, handleToolCall });
|
|
18884
19330
|
streamableTransport = new StreamableHTTPServerTransport2({
|
|
18885
|
-
sessionIdGenerator: () =>
|
|
19331
|
+
sessionIdGenerator: () => randomUUID8()
|
|
18886
19332
|
});
|
|
18887
19333
|
await mcpServer.connect(streamableTransport);
|
|
18888
19334
|
streamableTransport.onerror = (err) => error(`Streamable HTTP transport error: ${err.message}`);
|
|
@@ -19065,7 +19511,7 @@ async function initCadConnection() {
|
|
|
19065
19511
|
}
|
|
19066
19512
|
async function startServer() {
|
|
19067
19513
|
await loadPlugins();
|
|
19068
|
-
initPlugins({ cad, config: config_default, log, registerTool, tools:
|
|
19514
|
+
initPlugins({ cad, config: config_default, log, registerTool, tools: tools42 });
|
|
19069
19515
|
onPluginChange((type, name) => {
|
|
19070
19516
|
log(`Plugin changed: ${type} ${name}`);
|
|
19071
19517
|
broadcastToolListChanged();
|
|
@@ -19089,7 +19535,7 @@ async function startServer() {
|
|
|
19089
19535
|
}
|
|
19090
19536
|
if (config_default.transport === "stdio") {
|
|
19091
19537
|
await initCadConnection();
|
|
19092
|
-
const mcpServer2 = createStdioServer({ tools:
|
|
19538
|
+
const mcpServer2 = createStdioServer({ tools: tools42, handleToolCall });
|
|
19093
19539
|
const transport = new StdioServerTransport();
|
|
19094
19540
|
const sessionId = "stdio-session";
|
|
19095
19541
|
sessionManager.createSession(sessionId);
|
|
@@ -19190,5 +19636,5 @@ export {
|
|
|
19190
19636
|
handleToolCall,
|
|
19191
19637
|
loadAtlibFunctionLib,
|
|
19192
19638
|
startServer,
|
|
19193
|
-
|
|
19639
|
+
tools42 as tools
|
|
19194
19640
|
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { withCadConnection, mcpSuccess, mcpError } from '../handler-utils.js';
|
|
2
|
+
import {
|
|
3
|
+
createSession, getSession, closeSession, listSessions,
|
|
4
|
+
loadHelpers, fastForward, executeStep, continueExecution, evaluateExpression,
|
|
5
|
+
} from '../debug-engine.js';
|
|
6
|
+
|
|
7
|
+
export const debugStart = withCadConnection(async (args) => {
|
|
8
|
+
try {
|
|
9
|
+
const { code, chunks, encoding } = args || {};
|
|
10
|
+
if (!code) return mcpError('Missing required argument: code');
|
|
11
|
+
if (!chunks || !Array.isArray(chunks)) return mcpError('Missing required argument: chunks (must be an array)');
|
|
12
|
+
|
|
13
|
+
const sessionId = await createSession(code, chunks, encoding);
|
|
14
|
+
const session = getSession(sessionId);
|
|
15
|
+
if (!session) return mcpError('Failed to create debug session');
|
|
16
|
+
|
|
17
|
+
await loadHelpers(session);
|
|
18
|
+
|
|
19
|
+
const ffResult = await fastForward(session);
|
|
20
|
+
|
|
21
|
+
if (session.state === 'error') {
|
|
22
|
+
await closeSession(sessionId);
|
|
23
|
+
return mcpError(session.error);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return mcpSuccess(JSON.stringify({
|
|
27
|
+
sessionId,
|
|
28
|
+
totalChunks: session.totalChunks,
|
|
29
|
+
...ffResult,
|
|
30
|
+
}));
|
|
31
|
+
} catch (e) {
|
|
32
|
+
return mcpError(e.message);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const debugStep = withCadConnection(async (args) => {
|
|
37
|
+
try {
|
|
38
|
+
const { sessionId, action } = args || {};
|
|
39
|
+
if (!sessionId) return mcpError('Missing required argument: sessionId');
|
|
40
|
+
if (!action) return mcpError('Missing required argument: action');
|
|
41
|
+
|
|
42
|
+
const session = getSession(sessionId);
|
|
43
|
+
if (!session) return mcpError(`Debug session not found: ${sessionId}`);
|
|
44
|
+
|
|
45
|
+
if (session.state !== 'paused' && session.state !== 'ready') {
|
|
46
|
+
return mcpError(`Invalid state: ${session.state} (expected paused or ready)`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let result;
|
|
50
|
+
if (action === 'step') {
|
|
51
|
+
result = await executeStep(session);
|
|
52
|
+
} else if (action === 'continue') {
|
|
53
|
+
result = await continueExecution(session);
|
|
54
|
+
} else {
|
|
55
|
+
return mcpError(`Invalid action: ${action} (expected step or continue)`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (session.state === 'error') {
|
|
59
|
+
return mcpError(session.error);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return mcpSuccess(JSON.stringify(result));
|
|
63
|
+
} catch (e) {
|
|
64
|
+
return mcpError(e.message);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export const debugEvaluate = withCadConnection(async (args) => {
|
|
69
|
+
try {
|
|
70
|
+
const { sessionId, expression } = args || {};
|
|
71
|
+
if (!sessionId) return mcpError('Missing required argument: sessionId');
|
|
72
|
+
if (!expression) return mcpError('Missing required argument: expression');
|
|
73
|
+
|
|
74
|
+
const session = getSession(sessionId);
|
|
75
|
+
if (!session) return mcpError(`Debug session not found: ${sessionId}`);
|
|
76
|
+
|
|
77
|
+
if (session.state !== 'paused') {
|
|
78
|
+
return mcpError(`Invalid state: ${session.state} (expected paused)`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const result = await evaluateExpression(session, expression);
|
|
82
|
+
if (result.error) return mcpError(result.error);
|
|
83
|
+
|
|
84
|
+
return mcpSuccess(JSON.stringify({ value: result.value }));
|
|
85
|
+
} catch (e) {
|
|
86
|
+
return mcpError(e.message);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
export async function debugGetState(args) {
|
|
91
|
+
try {
|
|
92
|
+
const { sessionId } = args || {};
|
|
93
|
+
if (!sessionId) return mcpError('Missing required argument: sessionId');
|
|
94
|
+
|
|
95
|
+
const session = getSession(sessionId);
|
|
96
|
+
if (!session) return mcpError(`Debug session not found: ${sessionId}`);
|
|
97
|
+
|
|
98
|
+
const checkpoint = session.lastCheckpoint;
|
|
99
|
+
return mcpSuccess(JSON.stringify({
|
|
100
|
+
state: session.state,
|
|
101
|
+
currentIndex: session.currentIndex,
|
|
102
|
+
totalChunks: session.totalChunks,
|
|
103
|
+
currentCheckpoint: checkpoint || undefined,
|
|
104
|
+
error: session.error,
|
|
105
|
+
}));
|
|
106
|
+
} catch (e) {
|
|
107
|
+
return mcpError(e.message);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function debugStop(args) {
|
|
112
|
+
try {
|
|
113
|
+
const { sessionId } = args || {};
|
|
114
|
+
if (!sessionId) return mcpError('Missing required argument: sessionId');
|
|
115
|
+
|
|
116
|
+
const session = getSession(sessionId);
|
|
117
|
+
if (!session) {
|
|
118
|
+
return mcpError(`Debug session not found: ${sessionId}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const ok = await closeSession(sessionId);
|
|
122
|
+
return mcpSuccess(JSON.stringify({ success: ok }));
|
|
123
|
+
} catch (e) {
|
|
124
|
+
return mcpError(e.message);
|
|
125
|
+
}
|
|
126
|
+
}
|