@genart-dev/mcp-server 0.4.2 → 0.4.3
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/index.cjs +51 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +41 -26
- package/dist/index.js.map +1 -1
- package/dist/lib.cjs +52 -40
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +6 -2
- package/dist/lib.d.ts +6 -2
- package/dist/lib.js +37 -25
- package/dist/lib.js.map +1 -1
- package/package.json +1 -1
package/dist/lib.cjs
CHANGED
|
@@ -2445,6 +2445,7 @@ function isDirectComponent(name, components) {
|
|
|
2445
2445
|
|
|
2446
2446
|
// src/tools/capture.ts
|
|
2447
2447
|
var import_promises6 = require("fs/promises");
|
|
2448
|
+
var import_path8 = require("path");
|
|
2448
2449
|
var import_core8 = require("@genart-dev/core");
|
|
2449
2450
|
|
|
2450
2451
|
// src/capture/headless.ts
|
|
@@ -2547,8 +2548,9 @@ function generateSketchHtml(sketch, opts) {
|
|
|
2547
2548
|
}
|
|
2548
2549
|
return adapter.generateStandaloneHTML(effective);
|
|
2549
2550
|
}
|
|
2550
|
-
function
|
|
2551
|
-
|
|
2551
|
+
function deriveSnapshotPath(sketchPath, sketchId, seed) {
|
|
2552
|
+
const wsDir = (0, import_path8.dirname)(sketchPath);
|
|
2553
|
+
return (0, import_path8.join)(wsDir, "snapshots", `${sketchId}-${seed}-preview.png`);
|
|
2552
2554
|
}
|
|
2553
2555
|
async function captureScreenshot(state, input) {
|
|
2554
2556
|
state.requireWorkspace();
|
|
@@ -2581,11 +2583,12 @@ async function captureScreenshot(state, input) {
|
|
|
2581
2583
|
height,
|
|
2582
2584
|
inlineSize
|
|
2583
2585
|
});
|
|
2584
|
-
const
|
|
2586
|
+
const effectiveSeed = input.seed ?? sketch.state.seed;
|
|
2587
|
+
const previewPath = deriveSnapshotPath(loaded.path, sketchId, effectiveSeed);
|
|
2585
2588
|
const metadata = await buildScreenshotMetadata(state, multi, {
|
|
2586
2589
|
target,
|
|
2587
2590
|
sketchId,
|
|
2588
|
-
seed:
|
|
2591
|
+
seed: effectiveSeed,
|
|
2589
2592
|
previewPath
|
|
2590
2593
|
});
|
|
2591
2594
|
const previewJpegBase64 = Buffer.from(multi.inlineJpeg).toString("base64");
|
|
@@ -2606,8 +2609,10 @@ async function buildScreenshotMetadata(state, multi, info) {
|
|
|
2606
2609
|
previewPath: info.previewPath
|
|
2607
2610
|
};
|
|
2608
2611
|
if (!state.remoteMode) {
|
|
2612
|
+
await (0, import_promises6.mkdir)((0, import_path8.dirname)(info.previewPath), { recursive: true });
|
|
2609
2613
|
await (0, import_promises6.writeFile)(info.previewPath, multi.previewPng);
|
|
2610
2614
|
metadata.savedPreviewTo = info.previewPath;
|
|
2615
|
+
metadata.previewWritten = true;
|
|
2611
2616
|
}
|
|
2612
2617
|
return metadata;
|
|
2613
2618
|
}
|
|
@@ -2636,11 +2641,12 @@ async function captureBatch(state, input) {
|
|
|
2636
2641
|
height,
|
|
2637
2642
|
inlineSize
|
|
2638
2643
|
});
|
|
2639
|
-
const
|
|
2644
|
+
const effectiveSeed = input.seed ?? sketch.state.seed;
|
|
2645
|
+
const previewPath = deriveSnapshotPath(loaded.path, id, effectiveSeed);
|
|
2640
2646
|
const itemMetadata = await buildScreenshotMetadata(state, multi, {
|
|
2641
2647
|
target: "sketch",
|
|
2642
2648
|
sketchId: id,
|
|
2643
|
-
seed:
|
|
2649
|
+
seed: effectiveSeed,
|
|
2644
2650
|
previewPath
|
|
2645
2651
|
});
|
|
2646
2652
|
items.push({
|
|
@@ -3000,7 +3006,7 @@ function gatherRelevantSkills(aspects) {
|
|
|
3000
3006
|
|
|
3001
3007
|
// src/tools/series.ts
|
|
3002
3008
|
var import_promises7 = require("fs/promises");
|
|
3003
|
-
var
|
|
3009
|
+
var import_path9 = require("path");
|
|
3004
3010
|
var import_core10 = require("@genart-dev/core");
|
|
3005
3011
|
function now6() {
|
|
3006
3012
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -3163,7 +3169,7 @@ async function seriesSummary(state, input) {
|
|
|
3163
3169
|
for (const file of series.sketchFiles) {
|
|
3164
3170
|
let found = false;
|
|
3165
3171
|
for (const [id, loaded] of state.sketches) {
|
|
3166
|
-
if ((0,
|
|
3172
|
+
if ((0, import_path9.basename)(loaded.path) === file) {
|
|
3167
3173
|
const def = loaded.definition;
|
|
3168
3174
|
sketchInfos.push({
|
|
3169
3175
|
id,
|
|
@@ -3277,18 +3283,18 @@ async function promoteSketch(state, input) {
|
|
|
3277
3283
|
...input.agent ? { agent: input.agent } : {},
|
|
3278
3284
|
...input.model ? { model: input.model } : {}
|
|
3279
3285
|
};
|
|
3280
|
-
const sourceDir = (0,
|
|
3281
|
-
const newPath = (0,
|
|
3286
|
+
const sourceDir = (0, import_path9.dirname)(source.path);
|
|
3287
|
+
const newPath = (0, import_path9.resolve)(sourceDir, `${newId}.genart`);
|
|
3282
3288
|
const json = (0, import_core10.serializeGenart)(promotedDef);
|
|
3283
3289
|
if (!state.remoteMode) {
|
|
3284
3290
|
await (0, import_promises7.writeFile)(newPath, json, "utf-8");
|
|
3285
3291
|
}
|
|
3286
3292
|
state.sketches.set(newId, { definition: promotedDef, path: newPath });
|
|
3287
3293
|
const sourceRef = ws.sketches.find(
|
|
3288
|
-
(s) => s.file === (0,
|
|
3294
|
+
(s) => s.file === (0, import_path9.basename)(source.path)
|
|
3289
3295
|
);
|
|
3290
3296
|
const position = sourceRef ? { x: sourceRef.position.x, y: sourceRef.position.y + sourceDef.canvas.height + 200 } : { x: 0, y: 0 };
|
|
3291
|
-
const file = (0,
|
|
3297
|
+
const file = (0, import_path9.basename)(newPath);
|
|
3292
3298
|
state.workspace = {
|
|
3293
3299
|
...ws,
|
|
3294
3300
|
modified: ts,
|
|
@@ -3348,7 +3354,7 @@ function countBy(items) {
|
|
|
3348
3354
|
|
|
3349
3355
|
// src/tools/reference.ts
|
|
3350
3356
|
var import_promises8 = require("fs/promises");
|
|
3351
|
-
var
|
|
3357
|
+
var import_path10 = require("path");
|
|
3352
3358
|
var import_core11 = require("@genart-dev/core");
|
|
3353
3359
|
var import_promises9 = require("fs/promises");
|
|
3354
3360
|
function now7() {
|
|
@@ -3373,7 +3379,7 @@ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
3373
3379
|
".svg"
|
|
3374
3380
|
]);
|
|
3375
3381
|
function isImageFile(path) {
|
|
3376
|
-
return IMAGE_EXTENSIONS.has((0,
|
|
3382
|
+
return IMAGE_EXTENSIONS.has((0, import_path10.extname)(path).toLowerCase());
|
|
3377
3383
|
}
|
|
3378
3384
|
var VALID_REFERENCE_TYPES = [
|
|
3379
3385
|
"image",
|
|
@@ -3389,7 +3395,7 @@ async function addReference(state, input) {
|
|
|
3389
3395
|
`Not a recognized image file: ${input.image}. Supported: ${[...IMAGE_EXTENSIONS].join(", ")}`
|
|
3390
3396
|
);
|
|
3391
3397
|
}
|
|
3392
|
-
const id = input.id ?? (0,
|
|
3398
|
+
const id = input.id ?? (0, import_path10.basename)(input.image, (0, import_path10.extname)(input.image)).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
3393
3399
|
if (!id) {
|
|
3394
3400
|
throw new Error("Could not derive a valid ID from the image filename");
|
|
3395
3401
|
}
|
|
@@ -3400,15 +3406,15 @@ async function addReference(state, input) {
|
|
|
3400
3406
|
`Invalid reference type: '${refType}'. Valid types: ${VALID_REFERENCE_TYPES.join(", ")}`
|
|
3401
3407
|
);
|
|
3402
3408
|
}
|
|
3403
|
-
const workspaceDir = (0,
|
|
3404
|
-
const refsDir = (0,
|
|
3409
|
+
const workspaceDir = (0, import_path10.dirname)(state.workspacePath);
|
|
3410
|
+
const refsDir = (0, import_path10.resolve)(workspaceDir, "references");
|
|
3405
3411
|
await (0, import_promises8.mkdir)(refsDir, { recursive: true });
|
|
3406
|
-
const ext = (0,
|
|
3412
|
+
const ext = (0, import_path10.extname)(input.image);
|
|
3407
3413
|
const destFilename = `${id}${ext}`;
|
|
3408
|
-
const destPath = (0,
|
|
3414
|
+
const destPath = (0, import_path10.resolve)(refsDir, destFilename);
|
|
3409
3415
|
const relativePath = `references/${destFilename}`;
|
|
3410
3416
|
if (!state.remoteMode) {
|
|
3411
|
-
await (0, import_promises8.copyFile)((0,
|
|
3417
|
+
await (0, import_promises8.copyFile)((0, import_path10.resolve)(input.image), destPath);
|
|
3412
3418
|
}
|
|
3413
3419
|
const ref = {
|
|
3414
3420
|
id,
|
|
@@ -3490,12 +3496,12 @@ async function addReference(state, input) {
|
|
|
3490
3496
|
async function analyzeReference(state, input) {
|
|
3491
3497
|
state.requireWorkspace();
|
|
3492
3498
|
const { ref, location } = findReference(state, input.referenceId, input.seriesId, input.sketchId);
|
|
3493
|
-
const workspaceDir = (0,
|
|
3494
|
-
const imagePath = (0,
|
|
3499
|
+
const workspaceDir = (0, import_path10.dirname)(state.workspacePath);
|
|
3500
|
+
const imagePath = (0, import_path10.resolve)(workspaceDir, ref.path);
|
|
3495
3501
|
let previewJpegBase64;
|
|
3496
3502
|
try {
|
|
3497
3503
|
const imageBuffer = await (0, import_promises8.readFile)(imagePath);
|
|
3498
|
-
const ext = (0,
|
|
3504
|
+
const ext = (0, import_path10.extname)(ref.path).toLowerCase();
|
|
3499
3505
|
const mimeMap = {
|
|
3500
3506
|
".png": "image/png",
|
|
3501
3507
|
".jpg": "image/jpeg",
|
|
@@ -3650,8 +3656,8 @@ async function extractPalette(state, input) {
|
|
|
3650
3656
|
input.sketchId
|
|
3651
3657
|
);
|
|
3652
3658
|
const count = input.count ?? 6;
|
|
3653
|
-
const workspaceDir = (0,
|
|
3654
|
-
const imagePath = (0,
|
|
3659
|
+
const workspaceDir = (0, import_path10.dirname)(state.workspacePath);
|
|
3660
|
+
const imagePath = (0, import_path10.resolve)(workspaceDir, ref.path);
|
|
3655
3661
|
let previewJpegBase64;
|
|
3656
3662
|
try {
|
|
3657
3663
|
const imageBuffer = await (0, import_promises8.readFile)(imagePath);
|
|
@@ -3727,12 +3733,12 @@ function findReference(state, referenceId, seriesId, sketchId) {
|
|
|
3727
3733
|
// src/tools/export.ts
|
|
3728
3734
|
var import_fs = require("fs");
|
|
3729
3735
|
var import_promises10 = require("fs/promises");
|
|
3730
|
-
var
|
|
3736
|
+
var import_path11 = require("path");
|
|
3731
3737
|
var import_archiver = __toESM(require("archiver"), 1);
|
|
3732
3738
|
var import_core12 = require("@genart-dev/core");
|
|
3733
3739
|
var registry4 = (0, import_core12.createDefaultRegistry)();
|
|
3734
3740
|
async function validateOutputPath(outputPath) {
|
|
3735
|
-
const parentDir = (0,
|
|
3741
|
+
const parentDir = (0, import_path11.dirname)(outputPath);
|
|
3736
3742
|
try {
|
|
3737
3743
|
const s = await (0, import_promises10.stat)(parentDir);
|
|
3738
3744
|
if (!s.isDirectory()) {
|
|
@@ -4998,20 +5004,24 @@ async function initializePluginRegistry() {
|
|
|
4998
5004
|
await registry5.register(import_plugin_trace.default);
|
|
4999
5005
|
return registry5;
|
|
5000
5006
|
}
|
|
5001
|
-
function createServer(state) {
|
|
5007
|
+
function createServer(state, options) {
|
|
5008
|
+
const captureOnly = options?.captureOnly ?? false;
|
|
5002
5009
|
const server = new import_mcp.McpServer(
|
|
5003
5010
|
{
|
|
5004
|
-
name: "@genart/mcp-server",
|
|
5011
|
+
name: captureOnly ? "@genart/mcp-capture" : "@genart/mcp-server",
|
|
5005
5012
|
version: "0.4.0"
|
|
5006
5013
|
},
|
|
5007
5014
|
{
|
|
5008
5015
|
capabilities: {
|
|
5009
5016
|
tools: {},
|
|
5010
|
-
resources: {},
|
|
5011
|
-
prompts: {}
|
|
5017
|
+
...!captureOnly && { resources: {}, prompts: {} }
|
|
5012
5018
|
}
|
|
5013
5019
|
}
|
|
5014
5020
|
);
|
|
5021
|
+
if (captureOnly) {
|
|
5022
|
+
registerCaptureTools(server, state);
|
|
5023
|
+
return server;
|
|
5024
|
+
}
|
|
5015
5025
|
const registryReady = initializePluginRegistry().then((registry5) => {
|
|
5016
5026
|
state.pluginRegistry = registry5;
|
|
5017
5027
|
registerPluginMcpTools(server, registry5, state);
|
|
@@ -5028,7 +5038,9 @@ function createServer(state) {
|
|
|
5028
5038
|
registerSnapshotTools(server, state);
|
|
5029
5039
|
registerKnowledgeTools(server, state);
|
|
5030
5040
|
registerDesignTools(server, state);
|
|
5031
|
-
|
|
5041
|
+
if (!state.remoteMode) {
|
|
5042
|
+
registerCaptureTools(server, state);
|
|
5043
|
+
}
|
|
5032
5044
|
registerCritiqueTools(server, state);
|
|
5033
5045
|
registerSeriesTools(server, state);
|
|
5034
5046
|
registerReferenceTools(server, state);
|
|
@@ -5738,7 +5750,7 @@ function registerSnapshotTools(server, state) {
|
|
|
5738
5750
|
function registerCaptureTools(server, state) {
|
|
5739
5751
|
server.tool(
|
|
5740
5752
|
"capture_screenshot",
|
|
5741
|
-
"Capture a screenshot of a sketch. Returns metadata as text + a small inline JPEG image for visual review. In
|
|
5753
|
+
"Capture a screenshot of a sketch. Returns metadata as text + a small inline JPEG image for visual review. In local mode, writes a full-res PNG to snapshots/<sketchId>-<seed>-preview.png next to the workspace. The savedPreviewTo path in metadata points to the file on disk.",
|
|
5742
5754
|
{
|
|
5743
5755
|
target: import_zod2.z.enum(["selected", "sketch"]).optional().describe("What to capture (default: selected)"),
|
|
5744
5756
|
sketchId: import_zod2.z.string().optional().describe("Required when target is 'sketch'"),
|
|
@@ -6401,7 +6413,7 @@ function registerKnowledgeTools(server, state) {
|
|
|
6401
6413
|
// src/state.ts
|
|
6402
6414
|
var import_events = require("events");
|
|
6403
6415
|
var import_promises11 = require("fs/promises");
|
|
6404
|
-
var
|
|
6416
|
+
var import_path12 = require("path");
|
|
6405
6417
|
|
|
6406
6418
|
// src/sidecar.ts
|
|
6407
6419
|
function isSidecarMode() {
|
|
@@ -6458,7 +6470,7 @@ var EditorState = class extends import_events.EventEmitter {
|
|
|
6458
6470
|
}
|
|
6459
6471
|
/** Resolve a file path, respecting the sandbox basePath when set. */
|
|
6460
6472
|
resolvePath(file) {
|
|
6461
|
-
if ((0,
|
|
6473
|
+
if ((0, import_path12.isAbsolute)(file)) {
|
|
6462
6474
|
if (this.basePath && !file.startsWith(this.basePath)) {
|
|
6463
6475
|
throw new Error(`Path escapes sandbox: ${file}`);
|
|
6464
6476
|
}
|
|
@@ -6466,10 +6478,10 @@ var EditorState = class extends import_events.EventEmitter {
|
|
|
6466
6478
|
}
|
|
6467
6479
|
if ((file.startsWith("~/") || file === "~") && !this.basePath) {
|
|
6468
6480
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
6469
|
-
return (0,
|
|
6481
|
+
return (0, import_path12.resolve)(home, file.slice(2));
|
|
6470
6482
|
}
|
|
6471
6483
|
const base = this.basePath ?? process.cwd();
|
|
6472
|
-
const resolved = (0,
|
|
6484
|
+
const resolved = (0, import_path12.resolve)(base, file);
|
|
6473
6485
|
if (this.basePath && !resolved.startsWith(this.basePath)) {
|
|
6474
6486
|
throw new Error(`Path escapes sandbox: ${resolved}`);
|
|
6475
6487
|
}
|
|
@@ -6477,7 +6489,7 @@ var EditorState = class extends import_events.EventEmitter {
|
|
|
6477
6489
|
}
|
|
6478
6490
|
/** Resolve a sketch file reference (relative to workspace dir) to an absolute path. */
|
|
6479
6491
|
resolveSketchPath(file) {
|
|
6480
|
-
if ((0,
|
|
6492
|
+
if ((0, import_path12.isAbsolute)(file)) {
|
|
6481
6493
|
if (this.basePath && !file.startsWith(this.basePath)) {
|
|
6482
6494
|
throw new Error(`Path escapes sandbox: ${file}`);
|
|
6483
6495
|
}
|
|
@@ -6485,11 +6497,11 @@ var EditorState = class extends import_events.EventEmitter {
|
|
|
6485
6497
|
}
|
|
6486
6498
|
if (!this.workspacePath) {
|
|
6487
6499
|
if (this.basePath) {
|
|
6488
|
-
return (0,
|
|
6500
|
+
return (0, import_path12.resolve)(this.basePath, file);
|
|
6489
6501
|
}
|
|
6490
6502
|
throw new Error("No workspace is currently open");
|
|
6491
6503
|
}
|
|
6492
|
-
const resolved = (0,
|
|
6504
|
+
const resolved = (0, import_path12.resolve)((0, import_path12.dirname)(this.workspacePath), file);
|
|
6493
6505
|
if (this.basePath && !resolved.startsWith(this.basePath)) {
|
|
6494
6506
|
throw new Error(`Path escapes sandbox: ${resolved}`);
|
|
6495
6507
|
}
|