@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 CHANGED
@@ -2744,6 +2744,7 @@ function isDirectComponent(name, components) {
2744
2744
 
2745
2745
  // src/tools/capture.ts
2746
2746
  var import_promises8 = require("fs/promises");
2747
+ var import_path9 = require("path");
2747
2748
  var import_core9 = require("@genart-dev/core");
2748
2749
 
2749
2750
  // src/capture/headless.ts
@@ -2846,8 +2847,9 @@ function generateSketchHtml(sketch, opts) {
2846
2847
  }
2847
2848
  return adapter.generateStandaloneHTML(effective);
2848
2849
  }
2849
- function derivePreviewPath(sketchPath) {
2850
- return sketchPath.replace(/\.genart$/, ".png");
2850
+ function deriveSnapshotPath(sketchPath, sketchId, seed) {
2851
+ const wsDir = (0, import_path9.dirname)(sketchPath);
2852
+ return (0, import_path9.join)(wsDir, "snapshots", `${sketchId}-${seed}-preview.png`);
2851
2853
  }
2852
2854
  async function captureScreenshot(state, input) {
2853
2855
  state.requireWorkspace();
@@ -2880,11 +2882,12 @@ async function captureScreenshot(state, input) {
2880
2882
  height,
2881
2883
  inlineSize
2882
2884
  });
2883
- const previewPath = derivePreviewPath(loaded.path);
2885
+ const effectiveSeed = input.seed ?? sketch.state.seed;
2886
+ const previewPath = deriveSnapshotPath(loaded.path, sketchId, effectiveSeed);
2884
2887
  const metadata = await buildScreenshotMetadata(state, multi, {
2885
2888
  target,
2886
2889
  sketchId,
2887
- seed: input.seed ?? sketch.state.seed,
2890
+ seed: effectiveSeed,
2888
2891
  previewPath
2889
2892
  });
2890
2893
  const previewJpegBase64 = Buffer.from(multi.inlineJpeg).toString("base64");
@@ -2905,8 +2908,10 @@ async function buildScreenshotMetadata(state, multi, info) {
2905
2908
  previewPath: info.previewPath
2906
2909
  };
2907
2910
  if (!state.remoteMode) {
2911
+ await (0, import_promises8.mkdir)((0, import_path9.dirname)(info.previewPath), { recursive: true });
2908
2912
  await (0, import_promises8.writeFile)(info.previewPath, multi.previewPng);
2909
2913
  metadata.savedPreviewTo = info.previewPath;
2914
+ metadata.previewWritten = true;
2910
2915
  }
2911
2916
  return metadata;
2912
2917
  }
@@ -2935,11 +2940,12 @@ async function captureBatch(state, input) {
2935
2940
  height,
2936
2941
  inlineSize
2937
2942
  });
2938
- const previewPath = derivePreviewPath(loaded.path);
2943
+ const effectiveSeed = input.seed ?? sketch.state.seed;
2944
+ const previewPath = deriveSnapshotPath(loaded.path, id, effectiveSeed);
2939
2945
  const itemMetadata = await buildScreenshotMetadata(state, multi, {
2940
2946
  target: "sketch",
2941
2947
  sketchId: id,
2942
- seed: input.seed ?? sketch.state.seed,
2948
+ seed: effectiveSeed,
2943
2949
  previewPath
2944
2950
  });
2945
2951
  items.push({
@@ -3299,7 +3305,7 @@ function gatherRelevantSkills(aspects) {
3299
3305
 
3300
3306
  // src/tools/series.ts
3301
3307
  var import_promises9 = require("fs/promises");
3302
- var import_path9 = require("path");
3308
+ var import_path10 = require("path");
3303
3309
  var import_core11 = require("@genart-dev/core");
3304
3310
  function now6() {
3305
3311
  return (/* @__PURE__ */ new Date()).toISOString();
@@ -3462,7 +3468,7 @@ async function seriesSummary(state, input) {
3462
3468
  for (const file of series.sketchFiles) {
3463
3469
  let found = false;
3464
3470
  for (const [id, loaded] of state.sketches) {
3465
- if ((0, import_path9.basename)(loaded.path) === file) {
3471
+ if ((0, import_path10.basename)(loaded.path) === file) {
3466
3472
  const def = loaded.definition;
3467
3473
  sketchInfos.push({
3468
3474
  id,
@@ -3576,18 +3582,18 @@ async function promoteSketch(state, input) {
3576
3582
  ...input.agent ? { agent: input.agent } : {},
3577
3583
  ...input.model ? { model: input.model } : {}
3578
3584
  };
3579
- const sourceDir = (0, import_path9.dirname)(source.path);
3580
- const newPath = (0, import_path9.resolve)(sourceDir, `${newId}.genart`);
3585
+ const sourceDir = (0, import_path10.dirname)(source.path);
3586
+ const newPath = (0, import_path10.resolve)(sourceDir, `${newId}.genart`);
3581
3587
  const json = (0, import_core11.serializeGenart)(promotedDef);
3582
3588
  if (!state.remoteMode) {
3583
3589
  await (0, import_promises9.writeFile)(newPath, json, "utf-8");
3584
3590
  }
3585
3591
  state.sketches.set(newId, { definition: promotedDef, path: newPath });
3586
3592
  const sourceRef = ws.sketches.find(
3587
- (s) => s.file === (0, import_path9.basename)(source.path)
3593
+ (s) => s.file === (0, import_path10.basename)(source.path)
3588
3594
  );
3589
3595
  const position = sourceRef ? { x: sourceRef.position.x, y: sourceRef.position.y + sourceDef.canvas.height + 200 } : { x: 0, y: 0 };
3590
- const file = (0, import_path9.basename)(newPath);
3596
+ const file = (0, import_path10.basename)(newPath);
3591
3597
  state.workspace = {
3592
3598
  ...ws,
3593
3599
  modified: ts,
@@ -3647,7 +3653,7 @@ function countBy(items) {
3647
3653
 
3648
3654
  // src/tools/reference.ts
3649
3655
  var import_promises10 = require("fs/promises");
3650
- var import_path10 = require("path");
3656
+ var import_path11 = require("path");
3651
3657
  var import_core12 = require("@genart-dev/core");
3652
3658
  var import_promises11 = require("fs/promises");
3653
3659
  function now7() {
@@ -3672,7 +3678,7 @@ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
3672
3678
  ".svg"
3673
3679
  ]);
3674
3680
  function isImageFile(path) {
3675
- return IMAGE_EXTENSIONS.has((0, import_path10.extname)(path).toLowerCase());
3681
+ return IMAGE_EXTENSIONS.has((0, import_path11.extname)(path).toLowerCase());
3676
3682
  }
3677
3683
  var VALID_REFERENCE_TYPES = [
3678
3684
  "image",
@@ -3688,7 +3694,7 @@ async function addReference(state, input) {
3688
3694
  `Not a recognized image file: ${input.image}. Supported: ${[...IMAGE_EXTENSIONS].join(", ")}`
3689
3695
  );
3690
3696
  }
3691
- const id = input.id ?? (0, import_path10.basename)(input.image, (0, import_path10.extname)(input.image)).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
3697
+ const id = input.id ?? (0, import_path11.basename)(input.image, (0, import_path11.extname)(input.image)).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
3692
3698
  if (!id) {
3693
3699
  throw new Error("Could not derive a valid ID from the image filename");
3694
3700
  }
@@ -3699,15 +3705,15 @@ async function addReference(state, input) {
3699
3705
  `Invalid reference type: '${refType}'. Valid types: ${VALID_REFERENCE_TYPES.join(", ")}`
3700
3706
  );
3701
3707
  }
3702
- const workspaceDir = (0, import_path10.dirname)(state.workspacePath);
3703
- const refsDir = (0, import_path10.resolve)(workspaceDir, "references");
3708
+ const workspaceDir = (0, import_path11.dirname)(state.workspacePath);
3709
+ const refsDir = (0, import_path11.resolve)(workspaceDir, "references");
3704
3710
  await (0, import_promises10.mkdir)(refsDir, { recursive: true });
3705
- const ext = (0, import_path10.extname)(input.image);
3711
+ const ext = (0, import_path11.extname)(input.image);
3706
3712
  const destFilename = `${id}${ext}`;
3707
- const destPath = (0, import_path10.resolve)(refsDir, destFilename);
3713
+ const destPath = (0, import_path11.resolve)(refsDir, destFilename);
3708
3714
  const relativePath = `references/${destFilename}`;
3709
3715
  if (!state.remoteMode) {
3710
- await (0, import_promises10.copyFile)((0, import_path10.resolve)(input.image), destPath);
3716
+ await (0, import_promises10.copyFile)((0, import_path11.resolve)(input.image), destPath);
3711
3717
  }
3712
3718
  const ref = {
3713
3719
  id,
@@ -3789,12 +3795,12 @@ async function addReference(state, input) {
3789
3795
  async function analyzeReference(state, input) {
3790
3796
  state.requireWorkspace();
3791
3797
  const { ref, location } = findReference(state, input.referenceId, input.seriesId, input.sketchId);
3792
- const workspaceDir = (0, import_path10.dirname)(state.workspacePath);
3793
- const imagePath = (0, import_path10.resolve)(workspaceDir, ref.path);
3798
+ const workspaceDir = (0, import_path11.dirname)(state.workspacePath);
3799
+ const imagePath = (0, import_path11.resolve)(workspaceDir, ref.path);
3794
3800
  let previewJpegBase64;
3795
3801
  try {
3796
3802
  const imageBuffer = await (0, import_promises10.readFile)(imagePath);
3797
- const ext = (0, import_path10.extname)(ref.path).toLowerCase();
3803
+ const ext = (0, import_path11.extname)(ref.path).toLowerCase();
3798
3804
  const mimeMap = {
3799
3805
  ".png": "image/png",
3800
3806
  ".jpg": "image/jpeg",
@@ -3949,8 +3955,8 @@ async function extractPalette(state, input) {
3949
3955
  input.sketchId
3950
3956
  );
3951
3957
  const count = input.count ?? 6;
3952
- const workspaceDir = (0, import_path10.dirname)(state.workspacePath);
3953
- const imagePath = (0, import_path10.resolve)(workspaceDir, ref.path);
3958
+ const workspaceDir = (0, import_path11.dirname)(state.workspacePath);
3959
+ const imagePath = (0, import_path11.resolve)(workspaceDir, ref.path);
3954
3960
  let previewJpegBase64;
3955
3961
  try {
3956
3962
  const imageBuffer = await (0, import_promises10.readFile)(imagePath);
@@ -4026,12 +4032,12 @@ function findReference(state, referenceId, seriesId, sketchId) {
4026
4032
  // src/tools/export.ts
4027
4033
  var import_fs = require("fs");
4028
4034
  var import_promises12 = require("fs/promises");
4029
- var import_path11 = require("path");
4035
+ var import_path12 = require("path");
4030
4036
  var import_archiver = __toESM(require("archiver"), 1);
4031
4037
  var import_core13 = require("@genart-dev/core");
4032
4038
  var registry4 = (0, import_core13.createDefaultRegistry)();
4033
4039
  async function validateOutputPath(outputPath) {
4034
- const parentDir = (0, import_path11.dirname)(outputPath);
4040
+ const parentDir = (0, import_path12.dirname)(outputPath);
4035
4041
  try {
4036
4042
  const s = await (0, import_promises12.stat)(parentDir);
4037
4043
  if (!s.isDirectory()) {
@@ -5297,20 +5303,24 @@ async function initializePluginRegistry() {
5297
5303
  await registry5.register(import_plugin_trace.default);
5298
5304
  return registry5;
5299
5305
  }
5300
- function createServer(state) {
5306
+ function createServer(state, options) {
5307
+ const captureOnly = options?.captureOnly ?? false;
5301
5308
  const server = new import_mcp.McpServer(
5302
5309
  {
5303
- name: "@genart/mcp-server",
5310
+ name: captureOnly ? "@genart/mcp-capture" : "@genart/mcp-server",
5304
5311
  version: "0.4.0"
5305
5312
  },
5306
5313
  {
5307
5314
  capabilities: {
5308
5315
  tools: {},
5309
- resources: {},
5310
- prompts: {}
5316
+ ...!captureOnly && { resources: {}, prompts: {} }
5311
5317
  }
5312
5318
  }
5313
5319
  );
5320
+ if (captureOnly) {
5321
+ registerCaptureTools(server, state);
5322
+ return server;
5323
+ }
5314
5324
  const registryReady = initializePluginRegistry().then((registry5) => {
5315
5325
  state.pluginRegistry = registry5;
5316
5326
  registerPluginMcpTools(server, registry5, state);
@@ -5327,7 +5337,9 @@ function createServer(state) {
5327
5337
  registerSnapshotTools(server, state);
5328
5338
  registerKnowledgeTools(server, state);
5329
5339
  registerDesignTools(server, state);
5330
- registerCaptureTools(server, state);
5340
+ if (!state.remoteMode) {
5341
+ registerCaptureTools(server, state);
5342
+ }
5331
5343
  registerCritiqueTools(server, state);
5332
5344
  registerSeriesTools(server, state);
5333
5345
  registerReferenceTools(server, state);
@@ -6037,7 +6049,7 @@ function registerSnapshotTools(server, state) {
6037
6049
  function registerCaptureTools(server, state) {
6038
6050
  server.tool(
6039
6051
  "capture_screenshot",
6040
- "Capture a screenshot of a sketch. Returns metadata as text + a small inline JPEG image for visual review. In remote mode, metadata includes previewFileContent (base64 PNG) to Write locally.",
6052
+ "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.",
6041
6053
  {
6042
6054
  target: import_zod2.z.enum(["selected", "sketch"]).optional().describe("What to capture (default: selected)"),
6043
6055
  sketchId: import_zod2.z.string().optional().describe("Required when target is 'sketch'"),
@@ -6699,14 +6711,17 @@ function registerKnowledgeTools(server, state) {
6699
6711
 
6700
6712
  // src/index.ts
6701
6713
  async function main() {
6702
- const sidecar = isSidecarMode();
6703
- if (sidecar) {
6714
+ const captureOnly = process.argv.includes("--capture-only");
6715
+ const sidecar = !captureOnly && isSidecarMode();
6716
+ if (captureOnly) {
6717
+ console.error("[genart-mcp] Starting in capture-only mode");
6718
+ } else if (sidecar) {
6704
6719
  console.error("[genart-mcp] Starting in sidecar mode");
6705
6720
  } else {
6706
6721
  console.error("[genart-mcp] Starting in stdio mode");
6707
6722
  }
6708
6723
  const state = new EditorState();
6709
- const server = createServer(state);
6724
+ const server = createServer(state, { captureOnly });
6710
6725
  const transport = new import_stdio.StdioServerTransport();
6711
6726
  await server.connect(transport);
6712
6727
  console.error("[genart-mcp] Server connected and ready");