fresnel-mcp 0.2.1 → 0.2.2

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.
Files changed (2) hide show
  1. package/dist/server.js +17 -8
  2. package/package.json +3 -3
package/dist/server.js CHANGED
@@ -1056,6 +1056,11 @@ function addLayer(doc, groupId, asset, opts = {}) {
1056
1056
  return l;
1057
1057
  }
1058
1058
  function setProp(doc, ref, key, value, appearance, detached) {
1059
+ const old = key === "image-name" && !detached && ref.kind === "layer" ? imagesOf([findLayer(doc, ref.id)?.layer].filter((l) => !!l)) : null;
1060
+ setPropRaw(doc, ref, key, value, appearance, detached);
1061
+ if (old?.size) pruneAssets(doc, old);
1062
+ }
1063
+ function setPropRaw(doc, ref, key, value, appearance, detached) {
1059
1064
  const node = detached ? { kind: "layer", props: detached.props } : nodeOf(doc, ref);
1060
1065
  if (key === "layers" || key === "groups") throw new OpError(`"${key}" can't be set directly`);
1061
1066
  if (key.endsWith("-specializations")) throw new OpError(`Set "${key.replace(/-specializations$/, "")}" with an appearance instead`);
@@ -1935,7 +1940,7 @@ function renderSvg(doc, opts = {}) {
1935
1940
  let darken = 0;
1936
1941
  if (dark && !darkOverridden && bgFill !== "automatic" && bgFill !== "system-dark" && bgFill !== "none") darken = 0.62;
1937
1942
  let bgPaint;
1938
- const P = mask === "circle" || ctx.idiom === "watchOS" ? 32 : 0;
1943
+ const P = mask === "circle" || mask === "none" && ctx.idiom === "watchOS" ? 32 : 0;
1939
1944
  const full = { x: -P, y: -P, w: C2 + 2 * P, h: C2 + 2 * P };
1940
1945
  const monoOverride = (isClear || isTinted) && !!fillProp?.specs?.some((s) => s.appearance === "tinted" && forPlatform(s));
1941
1946
  if (monoOverride) {
@@ -1985,6 +1990,10 @@ function renderSvg(doc, opts = {}) {
1985
1990
  const gs = gp?.scale ?? 1;
1986
1991
  const gtx = gp?.tx ?? 0;
1987
1992
  const gty = gp?.ty ?? 0;
1993
+ const gx0 = H2 + (-PAD - H2 - gtx) / gs;
1994
+ const gy0 = H2 + (-PAD - H2 - gty) / gs;
1995
+ const gw = (C2 + 2 * PAD) / gs;
1996
+ const localRegion = `x="${n(gx0)}" y="${n(gy0)}" width="${n(gw)}" height="${n(gw)}"`;
1988
1997
  const layers = FRONT_FIRST ? [...g.layers].reverse() : [...g.layers];
1989
1998
  const placed = [];
1990
1999
  for (const l of layers) {
@@ -2033,7 +2042,7 @@ function renderSvg(doc, opts = {}) {
2033
2042
  let el;
2034
2043
  if (paint) {
2035
2044
  const mid = defs.id("lm");
2036
- defs.add(`<mask id="${mid}" mask-type="alpha" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="${-PAD}" y="${-PAD}" width="${C2 + 2 * PAD}" height="${C2 + 2 * PAD}"><use href="#${iid}" ${place}/></mask>`);
2045
+ defs.add(`<mask id="${mid}" mask-type="alpha" style="mask-type:alpha" maskUnits="userSpaceOnUse" ${localRegion}><use href="#${iid}" ${place}/></mask>`);
2037
2046
  el = `<rect x="${n(p.x)}" y="${n(p.y)}" width="${n(p.w)}" height="${n(p.h)}" fill="${paint}" mask="url(#${mid})"/>`;
2038
2047
  } else {
2039
2048
  el = `<use href="#${iid}" ${place}/>`;
@@ -2047,9 +2056,7 @@ function renderSvg(doc, opts = {}) {
2047
2056
  }
2048
2057
  const gTransform = gp ? ` transform="translate(${n(H2 + gtx)} ${n(H2 + gty)}) scale(${n(gs)}) translate(${-H2} ${-H2})"` : "";
2049
2058
  const canvasRegion = `filterUnits="userSpaceOnUse" x="${-PAD}" y="${-PAD}" width="${C2 + 2 * PAD}" height="${C2 + 2 * PAD}"`;
2050
- const gx0 = H2 + (-PAD - H2 - gtx) / gs;
2051
- const gy0 = H2 + (-PAD - H2 - gty) / gs;
2052
- const groupRegion = `filterUnits="userSpaceOnUse" x="${n(gx0)}" y="${n(gy0)}" width="${n((C2 + 2 * PAD) / gs)}" height="${n((C2 + 2 * PAD) / gs)}"`;
2059
+ const groupRegion = `filterUnits="userSpaceOnUse" ${localRegion}`;
2053
2060
  const contentId = defs.id("gc");
2054
2061
  defs.add(`<g id="${contentId}"${gTransform}>${layerEls.join("")}</g>`);
2055
2062
  contentIds.push(contentId);
@@ -2161,7 +2168,7 @@ function renderSvg(doc, opts = {}) {
2161
2168
  if (M > 0) {
2162
2169
  const sid = defs.id("ish");
2163
2170
  defs.add(
2164
- `<filter id="${sid}" ${'filterUnits="userSpaceOnUse"'} x="${-PAD}" y="${-PAD}" width="${C2 + 2 * PAD}" height="${C2 + 2 * PAD}"><feGaussianBlur in="SourceAlpha" stdDeviation="${n(C2 * 0.012)}"/><feOffset dy="${n(C2 * 0.012)}" result="b"/><feFlood flood-color="#000" flood-opacity="0.3"/><feComposite in2="b" operator="in" result="s"/><feMerge><feMergeNode in="s"/><feMergeNode in="SourceGraphic"/></feMerge></filter>`
2171
+ `<filter id="${sid}" filterUnits="userSpaceOnUse" x="${-(M + 64)}" y="${-(M + 64)}" width="${C2 + 2 * (M + 64)}" height="${C2 + 2 * (M + 64)}"><feGaussianBlur in="SourceAlpha" stdDeviation="${n(C2 * 0.012)}"/><feOffset dy="${n(C2 * 0.012)}" result="b"/><feFlood flood-color="#000" flood-opacity="0.3"/><feComposite in2="b" operator="in" result="s"/><feMerge><feMergeNode in="s"/><feMergeNode in="SourceGraphic"/></feMerge></filter>`
2165
2172
  );
2166
2173
  body.push(`<g filter="url(#${sid})"><g clip-path="url(#${clipId})">${top}</g></g>`);
2167
2174
  } else body.push(`<g clip-path="url(#${clipId})">${top}</g>`);
@@ -2826,7 +2833,7 @@ async function runTool(ws, t, args) {
2826
2833
  }
2827
2834
 
2828
2835
  // src/version.ts
2829
- var VERSION = "0.2.1";
2836
+ var VERSION = "0.2.2";
2830
2837
 
2831
2838
  // src/contract.ts
2832
2839
  var RESOURCES = [
@@ -3091,7 +3098,9 @@ var Workspace = class {
3091
3098
  const full = suffix ? resolve2(real, suffix) : real;
3092
3099
  if (suffix) {
3093
3100
  const first = resolve2(real, suffix.split(sep3)[0]);
3094
- if (await lstat2(first).then(() => true, () => false)) throw new Error(`Access denied: ${p} goes through a symbolic link that points nowhere`);
3101
+ const st = await lstat2(first).catch(() => null);
3102
+ if (st?.isSymbolicLink()) throw new Error(`Access denied: ${p} goes through a symbolic link that points nowhere`);
3103
+ if (st) throw new Error(`Invalid path: ${p} (${suffix.split(sep3)[0]} is not a folder)`);
3095
3104
  }
3096
3105
  if (!await this.allowed(full)) throw new Error(`Access denied: ${p} is outside the allowed roots (${this.roots.join(", ")})`);
3097
3106
  if (opts.mustExist && full !== real) throw new Error(`Not found: ${p}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fresnel-mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "MCP server for fresnel: let AI agents create, edit, preview and export Liquid Glass app icons (.icon bundles)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,8 +38,8 @@
38
38
  "devDependencies": {
39
39
  "tsup": "9.0.0",
40
40
  "tsx": "4.23.15",
41
- "@fresnel/core": "0.2.1",
42
- "@fresnel/render": "0.2.1"
41
+ "@fresnel/core": "0.2.2",
42
+ "@fresnel/render": "0.2.2"
43
43
  },
44
44
  "scripts": {
45
45
  "build": "tsup",