@zeroxsolutions/zaku 0.0.2 → 0.0.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.
Files changed (2) hide show
  1. package/dist/zaku.mjs +361 -107
  2. package/package.json +1 -1
package/dist/zaku.mjs CHANGED
@@ -17351,49 +17351,49 @@ var require_fast_uri = __commonJS({
17351
17351
  schemelessOptions.skipEscape = true;
17352
17352
  return serialize(resolved, schemelessOptions);
17353
17353
  }
17354
- function resolveComponent(base, relative, options, skipNormalization) {
17354
+ function resolveComponent(base, relative2, options, skipNormalization) {
17355
17355
  const target = {};
17356
17356
  if (!skipNormalization) {
17357
17357
  base = parse4(serialize(base, options), options);
17358
- relative = parse4(serialize(relative, options), options);
17358
+ relative2 = parse4(serialize(relative2, options), options);
17359
17359
  }
17360
17360
  options = options || {};
17361
- if (!options.tolerant && relative.scheme) {
17362
- target.scheme = relative.scheme;
17363
- target.userinfo = relative.userinfo;
17364
- target.host = relative.host;
17365
- target.port = relative.port;
17366
- target.path = removeDotSegments(relative.path || "");
17367
- target.query = relative.query;
17361
+ if (!options.tolerant && relative2.scheme) {
17362
+ target.scheme = relative2.scheme;
17363
+ target.userinfo = relative2.userinfo;
17364
+ target.host = relative2.host;
17365
+ target.port = relative2.port;
17366
+ target.path = removeDotSegments(relative2.path || "");
17367
+ target.query = relative2.query;
17368
17368
  } else {
17369
- if (relative.userinfo !== void 0 || relative.host !== void 0 || relative.port !== void 0) {
17370
- target.userinfo = relative.userinfo;
17371
- target.host = relative.host;
17372
- target.port = relative.port;
17373
- target.path = removeDotSegments(relative.path || "");
17374
- target.query = relative.query;
17369
+ if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
17370
+ target.userinfo = relative2.userinfo;
17371
+ target.host = relative2.host;
17372
+ target.port = relative2.port;
17373
+ target.path = removeDotSegments(relative2.path || "");
17374
+ target.query = relative2.query;
17375
17375
  } else {
17376
- if (!relative.path) {
17376
+ if (!relative2.path) {
17377
17377
  target.path = base.path;
17378
- if (relative.query !== void 0) {
17379
- target.query = relative.query;
17378
+ if (relative2.query !== void 0) {
17379
+ target.query = relative2.query;
17380
17380
  } else {
17381
17381
  target.query = base.query;
17382
17382
  }
17383
17383
  } else {
17384
- if (relative.path[0] === "/") {
17385
- target.path = removeDotSegments(relative.path);
17384
+ if (relative2.path[0] === "/") {
17385
+ target.path = removeDotSegments(relative2.path);
17386
17386
  } else {
17387
17387
  if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
17388
- target.path = "/" + relative.path;
17388
+ target.path = "/" + relative2.path;
17389
17389
  } else if (!base.path) {
17390
- target.path = relative.path;
17390
+ target.path = relative2.path;
17391
17391
  } else {
17392
- target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path;
17392
+ target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
17393
17393
  }
17394
17394
  target.path = removeDotSegments(target.path);
17395
17395
  }
17396
- target.query = relative.query;
17396
+ target.query = relative2.query;
17397
17397
  }
17398
17398
  target.userinfo = base.userinfo;
17399
17399
  target.host = base.host;
@@ -17401,7 +17401,7 @@ var require_fast_uri = __commonJS({
17401
17401
  }
17402
17402
  target.scheme = base.scheme;
17403
17403
  }
17404
- target.fragment = relative.fragment;
17404
+ target.fragment = relative2.fragment;
17405
17405
  return target;
17406
17406
  }
17407
17407
  function equal(uriA, uriB, options) {
@@ -20678,10 +20678,10 @@ var require_dist2 = __commonJS({
20678
20678
 
20679
20679
  // apps/zaku-cli/src/cli.ts
20680
20680
  var import_reflect_metadata3 = __toESM(require_Reflect(), 1);
20681
- import { readFile as readFile5 } from "node:fs/promises";
20681
+ import { readFile as readFile6 } from "node:fs/promises";
20682
20682
  import { createRequire } from "node:module";
20683
20683
  import { homedir as homedir2 } from "node:os";
20684
- import { dirname as dirname4, join as join10, resolve as resolve2, sep } from "node:path";
20684
+ import { dirname as dirname4, join as join11, resolve as resolve2, sep } from "node:path";
20685
20685
  import { fileURLToPath } from "node:url";
20686
20686
 
20687
20687
  // node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
@@ -21859,7 +21859,7 @@ var Command = class _Command extends EventEmitter {
21859
21859
  this._outputConfiguration = {
21860
21860
  writeOut: (str) => process2.stdout.write(str),
21861
21861
  writeErr: (str) => process2.stderr.write(str),
21862
- outputError: (str, write) => write(str),
21862
+ outputError: (str, write2) => write2(str),
21863
21863
  getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : void 0,
21864
21864
  getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : void 0,
21865
21865
  getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
@@ -23844,11 +23844,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
23844
23844
  hasColors = this._outputConfiguration.getOutHasColors();
23845
23845
  helpWidth = this._outputConfiguration.getOutHelpWidth();
23846
23846
  }
23847
- const write = (str) => {
23847
+ const write2 = (str) => {
23848
23848
  if (!hasColors) str = this._outputConfiguration.stripColor(str);
23849
23849
  return baseWrite(str);
23850
23850
  };
23851
- return { error: error62, write, hasColors, helpWidth };
23851
+ return { error: error62, write: write2, hasColors, helpWidth };
23852
23852
  }
23853
23853
  /**
23854
23854
  * Output help information for this command.
@@ -24325,8 +24325,8 @@ function parseCssColour(value) {
24325
24325
  return null;
24326
24326
  return name === "oklch" ? oklchToRgba(l, x, y, round(alpha)) : oklabToRgba(l, x, y, round(alpha));
24327
24327
  }
24328
- function rgbaToOklab(colour2) {
24329
- const [r, g, b] = [decode(colour2.r), decode(colour2.g), decode(colour2.b)];
24328
+ function rgbaToOklab(colour3) {
24329
+ const [r, g, b] = [decode(colour3.r), decode(colour3.g), decode(colour3.b)];
24330
24330
  const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
24331
24331
  const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
24332
24332
  const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
@@ -24341,12 +24341,12 @@ function deltaEOk(a, b) {
24341
24341
  const [l2, a2, b2] = rgbaToOklab(b);
24342
24342
  return Math.round(Math.hypot(l1 - l2, a1 - a2, b1 - b2, a.a - b.a) * 100 * 1e3) / 1e3;
24343
24343
  }
24344
- function toHex(colour2) {
24345
- const channels = [colour2.r, colour2.g, colour2.b].map((value) => Math.round(clamp(value) * 255).toString(16).padStart(2, "0"));
24344
+ function toHex(colour3) {
24345
+ const channels = [colour3.r, colour3.g, colour3.b].map((value) => Math.round(clamp(value) * 255).toString(16).padStart(2, "0"));
24346
24346
  return `#${channels.join("")}`;
24347
24347
  }
24348
- function luminance(colour2) {
24349
- return 0.2126 * decode(colour2.r) + 0.7152 * decode(colour2.g) + 0.0722 * decode(colour2.b);
24348
+ function luminance(colour3) {
24349
+ return 0.2126 * decode(colour3.r) + 0.7152 * decode(colour3.g) + 0.0722 * decode(colour3.b);
24350
24350
  }
24351
24351
  function contrastRatio(fg, bg) {
24352
24352
  const over = (front, back) => front * fg.a + back * (1 - fg.a);
@@ -44518,18 +44518,18 @@ function radiiOf(raw) {
44518
44518
  return fitRadii(corners, raw.width, raw.height);
44519
44519
  }
44520
44520
  function partOf(raw, at) {
44521
- const colour2 = (field, value) => {
44521
+ const colour3 = (field, value) => {
44522
44522
  const parsed = parseCssColour(value);
44523
44523
  if (!parsed)
44524
44524
  throw new Error(`${at}, part ${raw.part}: ${field} is ${value}, which zaku does not read`);
44525
44525
  return parsed;
44526
44526
  };
44527
- const background = colour2("background", raw.background);
44527
+ const background = colour3("background", raw.background);
44528
44528
  const gap = Number.parseFloat(raw.gap);
44529
44529
  return {
44530
44530
  background: background.a === 0 ? null : background,
44531
- color: colour2("color", raw.color),
44532
- borderColor: raw.borderWidths.some((width) => width > 0) ? colour2("borderColor", raw.borderColor) : null,
44531
+ color: colour3("color", raw.color),
44532
+ borderColor: raw.borderWidths.some((width) => width > 0) ? colour3("borderColor", raw.borderColor) : null,
44533
44533
  borderWidths: raw.borderWidths,
44534
44534
  width: raw.width,
44535
44535
  height: raw.height,
@@ -44611,7 +44611,6 @@ WriteRecipeHandler = __decorate2([
44611
44611
 
44612
44612
  // packages/zaku/dist/lib/handlers/save-library.js
44613
44613
  var import_tsyringe3 = __toESM(require_cjs(), 1);
44614
- import { writeFile as writeFile2 } from "node:fs/promises";
44615
44614
 
44616
44615
  // packages/zaku/dist/lib/domain/copy-defaults.js
44617
44616
  var DEFAULT_COPY = { locales: ["en"], currencies: [] };
@@ -44790,12 +44789,18 @@ function designPaths(root) {
44790
44789
  maps: join2(root, "map"),
44791
44790
  outline: join2(root, "outline"),
44792
44791
  unmapped: join2(root, "outline", "unmapped.yaml"),
44793
- library: join2(root, "library.json"),
44792
+ library: join2(root, "library"),
44793
+ libraryIndex: join2(root, "library", "index.json"),
44794
+ legacyLibrary: join2(root, "library.json"),
44794
44795
  tokens: join2(root, "tokens.json"),
44795
44796
  recipe: join2(root, "recipe.json")
44796
44797
  };
44797
44798
  }
44798
44799
 
44800
+ // packages/zaku/dist/lib/repositories/library-snapshot.js
44801
+ import { mkdir, readdir, readFile as readFile2, rename as rename2, rm, writeFile as writeFile2 } from "node:fs/promises";
44802
+ import { join as join3, relative } from "node:path";
44803
+
44799
44804
  // packages/zaku/dist/lib/domain/library.js
44800
44805
  var rgbaSchema = external_exports.object({ r: external_exports.number(), g: external_exports.number(), b: external_exports.number(), a: external_exports.number() }).strict();
44801
44806
  var libraryItemSchema = external_exports.object({
@@ -44873,6 +44878,253 @@ var variablePartSchema = external_exports.object({
44873
44878
  }).strict();
44874
44879
  var librarySnapshotSchema = libraryPartSchema.extend({ source: external_exports.string(), version: external_exports.string() }).strict();
44875
44880
 
44881
+ // packages/zaku/dist/lib/domain/library-files.js
44882
+ import { isDeepStrictEqual } from "node:util";
44883
+ var storedItemSchema = libraryItemSchema.partial().required({ nodeId: true, path: true, type: true, width: true, height: true }).extend({ bindings: libraryItemSchema.shape.bindings.optional(), glyph: rgbaSchema.optional() }).strict();
44884
+ var libraryFileSchema = external_exports.object({
44885
+ name: external_exports.string(),
44886
+ key: external_exports.string(),
44887
+ variants: external_exports.array(external_exports.object({
44888
+ key: external_exports.string(),
44889
+ /** The items in the first mode of the index's tokens. */
44890
+ items: external_exports.array(storedItemSchema),
44891
+ /** Only the modes whose stored items differ from the first. */
44892
+ modes: external_exports.array(external_exports.object({ combo: external_exports.record(external_exports.string(), external_exports.string()), items: external_exports.array(storedItemSchema) }).strict()).optional()
44893
+ }).strict())
44894
+ }).strict();
44895
+ var libraryIndexSchema = librarySnapshotSchema.extend({
44896
+ components: external_exports.array(libraryComponentSchema.omit({ variants: true }).extend({
44897
+ file: external_exports.string(),
44898
+ variants: external_exports.array(libraryVariantSchema.pick({ key: true, name: true, props: true }).strict())
44899
+ }).strict())
44900
+ }).strict();
44901
+ var NULLABLE = [
44902
+ "fill",
44903
+ "stroke",
44904
+ "textColor",
44905
+ "padding",
44906
+ "gap",
44907
+ "radii",
44908
+ "strokeWeights",
44909
+ "fontSize",
44910
+ "fontFamily",
44911
+ "textStyleKey",
44912
+ "componentKey"
44913
+ ];
44914
+ var RESOLVED = ["fill", "stroke", "textColor", "glyph", "radii"];
44915
+ function colour(name, values) {
44916
+ const value = name ? values[name] : void 0;
44917
+ return value !== void 0 && typeof value === "object" ? value : null;
44918
+ }
44919
+ function expandItem(stored, values) {
44920
+ const bindings = {
44921
+ fill: null,
44922
+ stroke: null,
44923
+ textColor: null,
44924
+ radius: null,
44925
+ ...stored.bindings
44926
+ };
44927
+ const radius = bindings.radius ? values[bindings.radius] : void 0;
44928
+ const glyph = stored.glyph ?? (bindings["glyph"] ? colour(bindings["glyph"], values) : null);
44929
+ return {
44930
+ nodeId: stored.nodeId,
44931
+ path: stored.path,
44932
+ type: stored.type,
44933
+ fill: stored.fill !== void 0 ? stored.fill : colour(bindings.fill, values),
44934
+ stroke: stored.stroke !== void 0 ? stored.stroke : colour(bindings.stroke, values),
44935
+ textColor: stored.textColor !== void 0 ? stored.textColor : colour(bindings.textColor, values),
44936
+ ...glyph ? { glyph } : {},
44937
+ width: stored.width,
44938
+ height: stored.height,
44939
+ padding: stored.padding ?? null,
44940
+ gap: stored.gap ?? null,
44941
+ radii: stored.radii !== void 0 ? stored.radii : typeof radius === "number" ? [radius, radius, radius, radius] : null,
44942
+ strokeWeights: stored.strokeWeights ?? null,
44943
+ fontSize: stored.fontSize ?? null,
44944
+ fontFamily: stored.fontFamily ?? null,
44945
+ textStyleKey: stored.textStyleKey ?? null,
44946
+ componentKey: stored.componentKey ?? null,
44947
+ bindings
44948
+ };
44949
+ }
44950
+ function compactItem(item, values) {
44951
+ const stored = {
44952
+ nodeId: item.nodeId,
44953
+ path: item.path,
44954
+ type: item.type,
44955
+ width: item.width,
44956
+ height: item.height
44957
+ };
44958
+ for (const field of NULLABLE)
44959
+ if (item[field] !== null)
44960
+ stored[field] = item[field];
44961
+ if (item.glyph)
44962
+ stored["glyph"] = item.glyph;
44963
+ const bindings = Object.fromEntries(Object.entries(item.bindings).filter(([name, value]) => value !== null || name === "glyph"));
44964
+ if (Object.keys(bindings).length > 0)
44965
+ stored["bindings"] = bindings;
44966
+ for (const field of RESOLVED) {
44967
+ if (!(field in stored))
44968
+ continue;
44969
+ const without = { ...stored };
44970
+ delete without[field];
44971
+ if (isDeepStrictEqual(expandItem(without, values), item))
44972
+ delete stored[field];
44973
+ }
44974
+ return isDeepStrictEqual(expandItem(stored, values), item) ? stored : item;
44975
+ }
44976
+ function comboKey(combo) {
44977
+ return JSON.stringify(Object.entries(combo).sort(([a], [b]) => a.localeCompare(b)));
44978
+ }
44979
+ function fileName(name, key, taken) {
44980
+ const slug2 = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "component";
44981
+ const file2 = taken.has(slug2) ? `${slug2}-${key.slice(0, 8)}` : slug2;
44982
+ taken.add(file2);
44983
+ return `components/${file2}.json`;
44984
+ }
44985
+ function splitLibrary(snapshot) {
44986
+ const valuesOf = new Map(snapshot.tokens.map((token) => [comboKey(token.combo), token.values]));
44987
+ const taken = /* @__PURE__ */ new Set();
44988
+ const files2 = /* @__PURE__ */ new Map();
44989
+ const components = [];
44990
+ for (const { variants, ...component2 } of snapshot.components) {
44991
+ const file2 = fileName(component2.name, component2.key, taken);
44992
+ files2.set(file2, {
44993
+ name: component2.name,
44994
+ key: component2.key,
44995
+ variants: variants.map((variant) => {
44996
+ const stored = variant.modes.map((mode) => ({
44997
+ combo: mode.combo,
44998
+ items: mode.items.map((item) => compactItem(item, valuesOf.get(comboKey(mode.combo)) ?? {}))
44999
+ }));
45000
+ const [first, ...rest] = stored;
45001
+ const modes = rest.filter((mode) => !isDeepStrictEqual(mode.items, first?.items));
45002
+ return { key: variant.key, items: first?.items ?? [], ...modes.length > 0 ? { modes } : {} };
45003
+ })
45004
+ });
45005
+ components.push({
45006
+ ...component2,
45007
+ file: file2,
45008
+ variants: variants.map(({ key, name, props }) => ({ key, name, props }))
45009
+ });
45010
+ }
45011
+ return { index: { ...snapshot, components }, files: files2 };
45012
+ }
45013
+ function joinLibrary(index, files2) {
45014
+ return {
45015
+ ...index,
45016
+ components: index.components.map(({ file: file2, variants, ...component2 }) => {
45017
+ const stored = files2.get(file2);
45018
+ if (!stored)
45019
+ throw new Error(`library/${file2} is not loaded`);
45020
+ return {
45021
+ ...component2,
45022
+ variants: variants.map((variant, at) => {
45023
+ const items = stored.variants[at];
45024
+ return {
45025
+ ...variant,
45026
+ modes: index.tokens.map((token) => ({
45027
+ combo: token.combo,
45028
+ items: (items?.modes?.find((mode) => comboKey(mode.combo) === comboKey(token.combo))?.items ?? items?.items ?? []).map((item) => expandItem(item, token.values))
45029
+ }))
45030
+ };
45031
+ })
45032
+ };
45033
+ })
45034
+ };
45035
+ }
45036
+ var ONE_LINE = 100;
45037
+ function write(value, pad, key) {
45038
+ const line = JSON.stringify(value);
45039
+ if (value === null || typeof value !== "object" || line.length <= ONE_LINE)
45040
+ return line;
45041
+ const inner = `${pad} `;
45042
+ if (Array.isArray(value)) {
45043
+ if (value.length === 0)
45044
+ return "[]";
45045
+ const element = (child) => key === "items" ? JSON.stringify(child) : write(child, inner, null);
45046
+ return `[
45047
+ ${value.map((child) => `${inner}${element(child)}`).join(",\n")}
45048
+ ${pad}]`;
45049
+ }
45050
+ const entries = Object.entries(value).filter(([, child]) => child !== void 0);
45051
+ if (entries.length === 0)
45052
+ return "{}";
45053
+ return `{
45054
+ ${entries.map(([name, child]) => `${inner}${JSON.stringify(name)}: ${write(child, inner, name)}`).join(",\n")}
45055
+ ${pad}}`;
45056
+ }
45057
+ function formatLibraryFile(value) {
45058
+ return `${write(value, "", null)}
45059
+ `;
45060
+ }
45061
+
45062
+ // packages/zaku/dist/lib/repositories/library-snapshot.js
45063
+ async function readText(path2) {
45064
+ try {
45065
+ return await readFile2(path2, "utf8");
45066
+ } catch (error62) {
45067
+ if (error62.code === "ENOENT")
45068
+ return null;
45069
+ throw error62;
45070
+ }
45071
+ }
45072
+ async function writeText(path2, text) {
45073
+ const temporary = `${path2}.${process.pid}.tmp`;
45074
+ await writeFile2(temporary, text);
45075
+ await rename2(temporary, path2);
45076
+ }
45077
+ async function readLibrarySnapshot(paths) {
45078
+ const index = await readOptionalDesignFile(paths.libraryIndex, libraryIndexSchema);
45079
+ if (!index)
45080
+ return readOptionalDesignFile(paths.legacyLibrary, librarySnapshotSchema);
45081
+ const files2 = /* @__PURE__ */ new Map();
45082
+ for (const component2 of index.components) {
45083
+ const path2 = join3(paths.library, component2.file);
45084
+ const text = await readText(path2);
45085
+ if (text === null)
45086
+ throw new DesignFileInvalid(path2, ["the index names it and it is missing; run zaku library save"]);
45087
+ const file2 = parseDesignFile(path2, text, libraryFileSchema);
45088
+ const keys = file2.variants.map((variant) => variant.key);
45089
+ if (keys.join("\n") !== component2.variants.map((variant) => variant.key).join("\n")) {
45090
+ throw new DesignFileInvalid(path2, ["its variants are not the index's; run zaku library save"]);
45091
+ }
45092
+ files2.set(component2.file, file2);
45093
+ }
45094
+ return joinLibrary(index, files2);
45095
+ }
45096
+ async function writeLibrarySnapshot(paths, snapshot) {
45097
+ const { index, files: files2 } = splitLibrary(snapshot);
45098
+ const directory = join3(paths.library, "components");
45099
+ await mkdir(directory, { recursive: true });
45100
+ const written = [];
45101
+ let unchanged = 0;
45102
+ for (const [file2, content] of files2) {
45103
+ const path2 = join3(paths.library, file2);
45104
+ const text = formatLibraryFile(content);
45105
+ if (await readText(path2) === text) {
45106
+ unchanged += 1;
45107
+ continue;
45108
+ }
45109
+ await writeText(path2, text);
45110
+ written.push(file2);
45111
+ }
45112
+ const removed = [];
45113
+ for (const name of (await readdir(directory)).sort()) {
45114
+ const file2 = `components/${name}`;
45115
+ if (!name.endsWith(".json") || files2.has(file2))
45116
+ continue;
45117
+ await rm(join3(directory, name));
45118
+ removed.push(file2);
45119
+ }
45120
+ await writeText(paths.libraryIndex, formatLibraryFile(index));
45121
+ if (await readText(paths.legacyLibrary) !== null) {
45122
+ await rm(paths.legacyLibrary);
45123
+ removed.push(relative(paths.root, paths.legacyLibrary));
45124
+ }
45125
+ return { written, unchanged, removed };
45126
+ }
45127
+
44876
45128
  // packages/zaku/dist/lib/adapters/figma-rest-library.js
44877
45129
  var DOCUMENTATION_PREFIXES = ["DS/"];
44878
45130
  var round3 = (value) => Math.round(value * 1e4) / 1e4;
@@ -45085,9 +45337,7 @@ async function saveLibrary(options) {
45085
45337
  if (fileKey2 === void 0)
45086
45338
  throw new FigmaFileKeyMissing("figma.library");
45087
45339
  const snapshot = librarySnapshotSchema.parse(await readLibrary({ rest: options.rest, fileKey: fileKey2, part: options.part }));
45088
- await writeFile2(paths.library, `${JSON.stringify(snapshot, null, 2)}
45089
- `);
45090
- return snapshot;
45340
+ return { snapshot, ...await writeLibrarySnapshot(paths, snapshot) };
45091
45341
  }
45092
45342
  var SaveLibraryHandler = class SaveLibraryHandler2 {
45093
45343
  rest;
@@ -45107,7 +45357,7 @@ SaveLibraryHandler = __decorate2([
45107
45357
  // packages/zaku/dist/lib/handlers/write-outline.js
45108
45358
  var import_tsyringe4 = __toESM(require_cjs(), 1);
45109
45359
  var import_yaml2 = __toESM(require_dist(), 1);
45110
- import { mkdir, rm, writeFile as writeFile3 } from "node:fs/promises";
45360
+ import { mkdir as mkdir2, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
45111
45361
  import { dirname as dirname2 } from "node:path";
45112
45362
 
45113
45363
  // packages/zaku/dist/lib/domain/documentation-measures.js
@@ -45496,8 +45746,8 @@ var DOCUMENTATION_PARTS = [
45496
45746
 
45497
45747
  // packages/zaku/dist/lib/repositories/feature-maps.js
45498
45748
  import { createHash } from "node:crypto";
45499
- import { readdir, readFile as readFile2 } from "node:fs/promises";
45500
- import { basename, join as join3 } from "node:path";
45749
+ import { readdir as readdir2, readFile as readFile3 } from "node:fs/promises";
45750
+ import { basename, join as join4 } from "node:path";
45501
45751
 
45502
45752
  // packages/zaku/dist/lib/domain/feature-map.js
45503
45753
  var slug = external_exports.string().regex(/^[a-z][a-z0-9-]*$/, "lowercase letters, digits and dashes, starting with a letter");
@@ -45565,7 +45815,7 @@ function digestOf(text) {
45565
45815
  async function loadMaps(dir) {
45566
45816
  let names;
45567
45817
  try {
45568
- names = (await readdir(dir)).filter((name) => name.endsWith(".yaml")).sort();
45818
+ names = (await readdir2(dir)).filter((name) => name.endsWith(".yaml")).sort();
45569
45819
  } catch (error62) {
45570
45820
  if (error62.code === "ENOENT")
45571
45821
  return { maps: [], errors: [] };
@@ -45574,8 +45824,8 @@ async function loadMaps(dir) {
45574
45824
  const maps = [];
45575
45825
  const errors = [];
45576
45826
  for (const name of names) {
45577
- const path2 = join3(dir, name);
45578
- const text = await readFile2(path2, "utf8");
45827
+ const path2 = join4(dir, name);
45828
+ const text = await readFile3(path2, "utf8");
45579
45829
  try {
45580
45830
  const map2 = parseDesignFile(path2, text, featureMapSchema);
45581
45831
  if (`${map2.feature}.yaml` !== basename(path2)) {
@@ -45684,7 +45934,7 @@ function outlineFrame(frame, where, ctx) {
45684
45934
  const images2 = [];
45685
45935
  const defaultNames = [];
45686
45936
  const links = [];
45687
- const relative = (node2) => {
45937
+ const relative2 = (node2) => {
45688
45938
  const box = node2.absoluteBoundingBox;
45689
45939
  return box ? { x: box.x - origin.x, y: box.y - origin.y, width: box.width, height: box.height } : null;
45690
45940
  };
@@ -45713,7 +45963,7 @@ function outlineFrame(frame, where, ctx) {
45713
45963
  componentKey: ctx.components[child.componentId ?? ""]?.key ?? "",
45714
45964
  component: component2,
45715
45965
  interactive: ctx.interactive.has(component2),
45716
- bounds: relative(child)
45966
+ bounds: relative2(child)
45717
45967
  });
45718
45968
  } else if (child.type === "TEXT") {
45719
45969
  instance.texts.push({
@@ -45754,7 +46004,7 @@ function outlineFrame(frame, where, ctx) {
45754
46004
  texts: [],
45755
46005
  interactive: ctx.interactive.has(component2),
45756
46006
  local: meta3?.remote === false,
45757
- bounds: relative(node2),
46007
+ bounds: relative2(node2),
45758
46008
  sizing: {
45759
46009
  horizontal: node2.layoutSizingHorizontal ?? "FIXED",
45760
46010
  vertical: node2.layoutSizingVertical ?? "FIXED"
@@ -45821,8 +46071,8 @@ function outlineFrame(frame, where, ctx) {
45821
46071
  }
45822
46072
 
45823
46073
  // packages/zaku/dist/lib/repositories/outlines.js
45824
- import { readdir as readdir2 } from "node:fs/promises";
45825
- import { join as join4 } from "node:path";
46074
+ import { readdir as readdir3 } from "node:fs/promises";
46075
+ import { join as join5 } from "node:path";
45826
46076
 
45827
46077
  // packages/zaku/dist/lib/domain/outline.js
45828
46078
  var boundsSchema = external_exports.object({ x: external_exports.number(), y: external_exports.number(), width: external_exports.number(), height: external_exports.number() }).strict();
@@ -45901,24 +46151,24 @@ var unmappedSchema = external_exports.object({
45901
46151
 
45902
46152
  // packages/zaku/dist/lib/repositories/outlines.js
45903
46153
  function outlinePath(dir, feature, screen) {
45904
- return join4(dir, feature, `${screen}.yaml`);
46154
+ return join5(dir, feature, `${screen}.yaml`);
45905
46155
  }
45906
46156
  async function loadOutlines(dir) {
45907
46157
  const outlines = [];
45908
46158
  const errors = [];
45909
46159
  let features;
45910
46160
  try {
45911
- features = (await readdir2(dir, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
46161
+ features = (await readdir3(dir, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
45912
46162
  } catch (error62) {
45913
46163
  if (error62.code === "ENOENT")
45914
46164
  return { outlines, unmapped: null, errors };
45915
46165
  throw error62;
45916
46166
  }
45917
46167
  for (const feature of features) {
45918
- const files2 = (await readdir2(join4(dir, feature))).filter((name) => name.endsWith(".yaml")).sort();
46168
+ const files2 = (await readdir3(join5(dir, feature))).filter((name) => name.endsWith(".yaml")).sort();
45919
46169
  for (const file2 of files2) {
45920
46170
  try {
45921
- outlines.push(await readDesignFile(join4(dir, feature, file2), screenOutlineSchema));
46171
+ outlines.push(await readDesignFile(join5(dir, feature, file2), screenOutlineSchema));
45922
46172
  } catch (error62) {
45923
46173
  if (error62 instanceof DesignFileInvalid)
45924
46174
  errors.push(error62);
@@ -45929,7 +46179,7 @@ async function loadOutlines(dir) {
45929
46179
  }
45930
46180
  let unmapped = null;
45931
46181
  try {
45932
- unmapped = await readOptionalDesignFile(join4(dir, "unmapped.yaml"), unmappedSchema);
46182
+ unmapped = await readOptionalDesignFile(join5(dir, "unmapped.yaml"), unmappedSchema);
45933
46183
  } catch (error62) {
45934
46184
  if (error62 instanceof DesignFileInvalid)
45935
46185
  errors.push(error62);
@@ -45991,7 +46241,7 @@ async function runOutline(options) {
45991
46241
  if (errors[0])
45992
46242
  throw errors[0];
45993
46243
  const digests = new Map(maps.map((loaded) => [loaded.map.feature, loaded.digest]));
45994
- const library = await readOptionalDesignFile(paths.library, librarySnapshotSchema);
46244
+ const library = await readLibrarySnapshot(paths);
45995
46245
  const existing = await loadOutlines(paths.outline);
45996
46246
  const file2 = await options.rest.file(fileKey2, INDEX_DEPTH);
45997
46247
  const listed = listFrames(file2.document);
@@ -46064,17 +46314,17 @@ async function runOutline(options) {
46064
46314
  if (options.frames === null) {
46065
46315
  for (const outline of existing.outlines) {
46066
46316
  if (!byScreen.has(`${outline.feature}/${outline.screen}`))
46067
- await rm(outlinePath(paths.outline, outline.feature, outline.screen), { force: true });
46317
+ await rm2(outlinePath(paths.outline, outline.feature, outline.screen), { force: true });
46068
46318
  }
46069
46319
  }
46070
46320
  const written = [];
46071
46321
  for (const outline of byScreen.values()) {
46072
46322
  const path2 = outlinePath(paths.outline, outline.feature, outline.screen);
46073
- await mkdir(dirname2(path2), { recursive: true });
46323
+ await mkdir2(dirname2(path2), { recursive: true });
46074
46324
  await writeFile3(path2, (0, import_yaml2.stringify)(outline));
46075
46325
  written.push(path2);
46076
46326
  }
46077
- await mkdir(paths.outline, { recursive: true });
46327
+ await mkdir2(paths.outline, { recursive: true });
46078
46328
  await writeFile3(paths.unmapped, (0, import_yaml2.stringify)(unmapped));
46079
46329
  return {
46080
46330
  skipped: false,
@@ -46190,14 +46440,14 @@ RecipeRepository = __decorate2([
46190
46440
 
46191
46441
  // packages/zaku/dist/lib/repositories/json-schema-files.js
46192
46442
  var import_tsyringe10 = __toESM(require_cjs(), 1);
46193
- import { mkdir as mkdir2 } from "node:fs/promises";
46194
- import { join as join5 } from "node:path";
46443
+ import { mkdir as mkdir3 } from "node:fs/promises";
46444
+ import { join as join6 } from "node:path";
46195
46445
  var JsonSchemaFiles = class JsonSchemaFiles2 {
46196
46446
  async write(dir, schemas) {
46197
- await mkdir2(dir, { recursive: true });
46447
+ await mkdir3(dir, { recursive: true });
46198
46448
  const written = [];
46199
46449
  for (const [name, schema] of Object.entries(schemas)) {
46200
- const path2 = join5(dir, name);
46450
+ const path2 = join6(dir, name);
46201
46451
  await writeDesignFile(path2, schema);
46202
46452
  written.push(path2);
46203
46453
  }
@@ -46210,13 +46460,13 @@ JsonSchemaFiles = __decorate2([
46210
46460
 
46211
46461
  // packages/zaku/dist/lib/repositories/source-files.js
46212
46462
  var import_tsyringe11 = __toESM(require_cjs(), 1);
46213
- import { readFile as readFile3 } from "node:fs/promises";
46463
+ import { readFile as readFile4 } from "node:fs/promises";
46214
46464
  var SourceFiles = class SourceFiles2 {
46215
46465
  readText(path2) {
46216
- return readFile3(path2, "utf8");
46466
+ return readFile4(path2, "utf8");
46217
46467
  }
46218
46468
  async readJson(path2) {
46219
- return JSON.parse(await readFile3(path2, "utf8"));
46469
+ return JSON.parse(await readFile4(path2, "utf8"));
46220
46470
  }
46221
46471
  };
46222
46472
  SourceFiles = __decorate2([
@@ -46224,11 +46474,11 @@ SourceFiles = __decorate2([
46224
46474
  ], SourceFiles);
46225
46475
 
46226
46476
  // packages/zaku/dist/lib/repositories/budget-ledger.js
46227
- import { mkdir as mkdir3, readFile as readFile4, rename as rename2, writeFile as writeFile4 } from "node:fs/promises";
46228
- import { dirname as dirname3, join as join6 } from "node:path";
46477
+ import { mkdir as mkdir4, readFile as readFile5, rename as rename3, writeFile as writeFile4 } from "node:fs/promises";
46478
+ import { dirname as dirname3, join as join7 } from "node:path";
46229
46479
  function ledgerPath(env, platform, home) {
46230
- const cache = env["XDG_CACHE_HOME"] ?? (platform === "darwin" ? join6(home, "Library", "Caches") : join6(home, ".cache"));
46231
- return join6(cache, "zaku", "ledger.json");
46480
+ const cache = env["XDG_CACHE_HOME"] ?? (platform === "darwin" ? join7(home, "Library", "Caches") : join7(home, ".cache"));
46481
+ return join7(cache, "zaku", "ledger.json");
46232
46482
  }
46233
46483
  function today(now) {
46234
46484
  return now.toISOString().slice(0, 10);
@@ -46238,7 +46488,7 @@ function seatAndRun(env) {
46238
46488
  }
46239
46489
  async function readLedger(path2, day) {
46240
46490
  try {
46241
- const parsed = JSON.parse(await readFile4(path2, "utf8"));
46491
+ const parsed = JSON.parse(await readFile5(path2, "utf8"));
46242
46492
  const isCount = (seat) => {
46243
46493
  const count = seat;
46244
46494
  return typeof count === "object" && count !== null && typeof count.mcp === "number" && typeof count.rest === "number" && typeof count.runs === "object" && count.runs !== null && Object.values(count.runs).every((value) => typeof value === "number");
@@ -46257,11 +46507,11 @@ async function recordCalls(path2, entry) {
46257
46507
  if (entry.kind === "mcp")
46258
46508
  seat.runs[entry.run] = (seat.runs[entry.run] ?? 0) + entry.count;
46259
46509
  ledger.seats[entry.seat] = seat;
46260
- await mkdir3(dirname3(path2), { recursive: true });
46510
+ await mkdir4(dirname3(path2), { recursive: true });
46261
46511
  const temporary = `${path2}.${process.pid}.tmp`;
46262
46512
  await writeFile4(temporary, `${JSON.stringify(ledger)}
46263
46513
  `);
46264
- await rename2(temporary, path2);
46514
+ await rename3(temporary, path2);
46265
46515
  return ledger;
46266
46516
  }
46267
46517
  function mcpAllowance(ledger, seat, run, budget) {
@@ -47845,7 +48095,7 @@ var GENERIC = /* @__PURE__ */ new Set(["serif", "sans-serif", "monospace", "curs
47845
48095
  function families(stack) {
47846
48096
  return stack.split(",").map((family) => family.trim().replace(/^["']|["']$/g, "")).filter((family) => family !== "" && !GENERIC.has(family.toLowerCase()));
47847
48097
  }
47848
- function colour(at, field, library, code) {
48098
+ function colour2(at, field, library, code) {
47849
48099
  const transparent = { r: 0, g: 0, b: 0, a: 0 };
47850
48100
  const drawn = library ?? transparent;
47851
48101
  const coded = code ?? transparent;
@@ -47874,12 +48124,12 @@ function size(at, field, library, code) {
47874
48124
  }
47875
48125
  function comparePart(at, part) {
47876
48126
  const { item } = at;
47877
- colour(at, "background", item.fill, part.background);
48127
+ colour2(at, "background", item.fill, part.background);
47878
48128
  if (item.type.toUpperCase() === "TEXT")
47879
- colour(at, "color", item.textColor, part.color);
47880
- colour(at, "borderColor", item.stroke, part.borderColor);
48129
+ colour2(at, "color", item.textColor, part.color);
48130
+ colour2(at, "borderColor", item.stroke, part.borderColor);
47881
48131
  if (item.glyph)
47882
- colour(at, "glyph", item.glyph, part.color);
48132
+ colour2(at, "glyph", item.glyph, part.color);
47883
48133
  if (item.path === "") {
47884
48134
  if (!at.fallback)
47885
48135
  size(at, "width", item.width, part.width);
@@ -48390,7 +48640,7 @@ async function loadDesign(root) {
48390
48640
  }
48391
48641
  const { outlines, unmapped, errors: outlineErrors } = await loadOutlines(paths.outline);
48392
48642
  findings.push(...outlineErrors.map(schemaFinding));
48393
- const library = await optional3(() => readOptionalDesignFile(paths.library, librarySnapshotSchema), findings);
48643
+ const library = await optional3(() => readLibrarySnapshot(paths), findings);
48394
48644
  const tokens = await optional3(() => readOptionalDesignFile(paths.tokens, tokenDocumentSchema), findings);
48395
48645
  const recipe2 = await optional3(() => readOptionalDesignFile(paths.recipe, recipeDocumentSchema), findings);
48396
48646
  return {
@@ -58116,34 +58366,34 @@ var StdioServerTransport = class {
58116
58366
  };
58117
58367
 
58118
58368
  // apps/zaku-cli/src/mcp/server.ts
58119
- import { mkdir as mkdir4 } from "node:fs/promises";
58369
+ import { mkdir as mkdir5 } from "node:fs/promises";
58120
58370
  import { tmpdir } from "node:os";
58121
- import { join as join9 } from "node:path";
58371
+ import { join as join10 } from "node:path";
58122
58372
 
58123
58373
  // apps/zaku-cli/src/mcp/screenshots.ts
58124
- import { readdir as readdir3, rm as rm2, stat } from "node:fs/promises";
58125
- import { join as join7 } from "node:path";
58374
+ import { readdir as readdir4, rm as rm3, stat } from "node:fs/promises";
58375
+ import { join as join8 } from "node:path";
58126
58376
  var KEPT_MS = 24 * 60 * 60 * 1e3;
58127
58377
  async function pruneScreenshots(dir, now) {
58128
58378
  let names;
58129
58379
  try {
58130
- names = await readdir3(dir);
58380
+ names = await readdir4(dir);
58131
58381
  } catch {
58132
58382
  return;
58133
58383
  }
58134
58384
  for (const name of names.filter((entry) => entry.endsWith(".png"))) {
58135
- const path2 = join7(dir, name);
58385
+ const path2 = join8(dir, name);
58136
58386
  const written = await stat(path2).then(
58137
58387
  (stats) => stats.mtimeMs,
58138
58388
  () => now
58139
58389
  );
58140
- if (now - written > KEPT_MS) await rm2(path2, { force: true });
58390
+ if (now - written > KEPT_MS) await rm3(path2, { force: true });
58141
58391
  }
58142
58392
  }
58143
58393
 
58144
58394
  // apps/zaku-cli/src/mcp/tools.ts
58145
58395
  import { writeFile as writeFile5 } from "node:fs/promises";
58146
- import { join as join8 } from "node:path";
58396
+ import { join as join9 } from "node:path";
58147
58397
  var fileKey = external_exports.string().min(1).regex(/^[0-9a-zA-Z]{22,128}$/).describe(
58148
58398
  "The key of the Figma file to use. If the URL is provided, extract the file key from the URL: https://figma.com/design/:fileKey/:fileName."
58149
58399
  );
@@ -58187,7 +58437,7 @@ function registerFigmaTools(server, bridge, options) {
58187
58437
  options.timeoutMs
58188
58438
  );
58189
58439
  if (!answer.ok) return { isError: true, content: [{ type: "text", text: answer.error }] };
58190
- const path2 = join8(options.imageDir, `${id2.replace(":", "-")}-${Date.now()}.png`);
58440
+ const path2 = join9(options.imageDir, `${id2.replace(":", "-")}-${Date.now()}.png`);
58191
58441
  await writeFile5(path2, Buffer.from(answer.png, "base64"));
58192
58442
  const text = JSON.stringify({
58193
58443
  path: path2,
@@ -58213,8 +58463,8 @@ async function serveMcp(log) {
58213
58463
  log(
58214
58464
  bridge.port === null ? "zaku mcp: no port from 7337 to 7346 was free; every call will say so" : `zaku mcp: listening for the zaku plugin on localhost:${bridge.port}`
58215
58465
  );
58216
- const imageDir = join9(tmpdir(), "zaku-screenshots");
58217
- await mkdir4(imageDir, { recursive: true });
58466
+ const imageDir = join10(tmpdir(), "zaku-screenshots");
58467
+ await mkdir5(imageDir, { recursive: true });
58218
58468
  await pruneScreenshots(imageDir, Date.now());
58219
58469
  const server = new McpServer({ name: "zaku", version: "1" });
58220
58470
  registerFigmaTools(server, bridge, { timeoutMs: CALL_TIMEOUT_MS, imageDir, log });
@@ -58260,7 +58510,7 @@ var checkCommand = (program2, io, finish) => {
58260
58510
  const loaded = await loadDesign(resolve2(io.cwd, options.root));
58261
58511
  const report = loaded.input ? runChecks(loaded.input, ALL_CHECKS) : { findings: [], notRun: [], passed: [] };
58262
58512
  report.findings.unshift(...loaded.findings);
58263
- const ran = options.input ? parseDesignFile(options.input, await readFile5(resolve2(io.cwd, options.input), "utf8"), rulesAnswerSchema) : null;
58513
+ const ran = options.input ? parseDesignFile(options.input, await readFile6(resolve2(io.cwd, options.input), "utf8"), rulesAnswerSchema) : null;
58264
58514
  if (ran && "rulesError" in ran) {
58265
58515
  io.err(`zaku check: the rules did not run after the write: ${ran.rulesError}`);
58266
58516
  finish(1);
@@ -58274,7 +58524,7 @@ var checkCommand = (program2, io, finish) => {
58274
58524
  });
58275
58525
  };
58276
58526
  async function productPlaywright(cwd) {
58277
- const require2 = createRequire(join10(cwd, "package.json"));
58527
+ const require2 = createRequire(join11(cwd, "package.json"));
58278
58528
  let resolved;
58279
58529
  try {
58280
58530
  resolved = require2.resolve("playwright");
@@ -58286,14 +58536,14 @@ async function productPlaywright(cwd) {
58286
58536
  }
58287
58537
  function fromProductTree(cwd, resolved) {
58288
58538
  for (let dir = resolve2(cwd); ; dir = dirname4(dir)) {
58289
- if (resolved.startsWith(join10(dir, "node_modules") + sep)) return true;
58539
+ if (resolved.startsWith(join11(dir, "node_modules") + sep)) return true;
58290
58540
  if (dirname4(dir) === dir) return false;
58291
58541
  }
58292
58542
  }
58293
58543
  var runners = {
58294
58544
  run: execRun,
58295
58545
  loadPlaywright: productPlaywright,
58296
- rulesLibrary: () => readFile5(fileURLToPath(new URL("./rules.js", import.meta.url)), "utf8")
58546
+ rulesLibrary: () => readFile6(fileURLToPath(new URL("./rules.js", import.meta.url)), "utf8")
58297
58547
  };
58298
58548
  var mcpCommand = (program2, io, finish) => {
58299
58549
  program2.command("mcp").description(
@@ -58411,7 +58661,7 @@ var libraryCommand = (program2, io, finish, cli) => {
58411
58661
  finish(0);
58412
58662
  }
58413
58663
  );
58414
- library.command("save").description("write library.json: the library components read over Figma REST, joined to the variables export").option("--root <dir>", "the design directory", "docs/design").option(
58664
+ library.command("save").description("write library/: the library components read over Figma REST, joined to the variables export").option("--root <dir>", "the design directory", "docs/design").option(
58415
58665
  "--input <variables.json>",
58416
58666
  "what use_figma returned for zaku library script; once per page export for a library in the product file",
58417
58667
  (value, previous = []) => [...previous, value]
@@ -58430,20 +58680,24 @@ var libraryCommand = (program2, io, finish, cli) => {
58430
58680
  const part = mergeParts(
58431
58681
  await Promise.all(
58432
58682
  options.input.map(
58433
- async (input2) => parseDesignFile(input2, await readFile5(resolve2(io.cwd, input2), "utf8"), variablePartSchema)
58683
+ async (input2) => parseDesignFile(input2, await readFile6(resolve2(io.cwd, input2), "utf8"), variablePartSchema)
58434
58684
  )
58435
58685
  )
58436
58686
  );
58437
58687
  try {
58438
- const snapshot = await cli.bus.send(new SaveLibrary({ root, part }));
58688
+ const { snapshot, written, unchanged, removed } = await cli.bus.send(
58689
+ new SaveLibrary({ root, part })
58690
+ );
58439
58691
  if (snapshot.components.length === 0) {
58440
58692
  io.err(
58441
- "library.json holds no components: the file publishes none and the export listed none; for a library in the product file, run zaku library script --local"
58693
+ "library/ holds no components: the file publishes none and the export listed none; for a library in the product file, run zaku library script --local"
58442
58694
  );
58443
58695
  finish(1);
58444
58696
  return;
58445
58697
  }
58446
- io.out(`wrote library.json: ${snapshot.components.length} components at version ${snapshot.version}`);
58698
+ io.out(
58699
+ `wrote library/: ${snapshot.components.length} components at version ${snapshot.version}; ${written.length} component files written, ${unchanged} unchanged, ${removed.length} removed`
58700
+ );
58447
58701
  finish(0);
58448
58702
  } finally {
58449
58703
  await recordRestCalls(cli, io);
@@ -58468,11 +58722,11 @@ return ${check2};`);
58468
58722
  finish(0);
58469
58723
  return;
58470
58724
  }
58471
- const write = await readFile5(resolve2(io.cwd, options.after), "utf8");
58725
+ const write2 = await readFile6(resolve2(io.cwd, options.after), "utf8");
58472
58726
  const body = [
58473
58727
  library,
58474
58728
  `const zakuWrite = async () => {
58475
- ${write}
58729
+ ${write2}
58476
58730
  };`,
58477
58731
  "const zakuValue = await zakuWrite();",
58478
58732
  "const value = zakuValue === undefined ? null : zakuValue;",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxsolutions/zaku",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "private": false,
5
5
  "description": "zaku's checker: checks a product's design data against its code and prints the rules script every Figma write runs.",
6
6
  "license": "MIT",