@figtools/cli 0.2.1 → 0.3.1

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/cli.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export type OutputFormat = "json" | "markdown";
2
+ export type ImageFormat = "webp" | "png" | "jpg";
2
3
  export interface ParsedArgs {
3
4
  urls: string[];
4
5
  format: OutputFormat;
5
6
  outputPath?: string;
7
+ imageFormat: ImageFormat;
6
8
  quiet: boolean;
7
9
  command?: "login";
8
10
  }
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,oBAAoB,GAAG,kCAAkC,GAAG,iBAAiB,CAAC;IACpF,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAMF,KAAK,aAAa,GAAG;IAAE,IAAI,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAEvC,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AA8DzD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAmCzD;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,YAAY,GACnB,YAAY,CAad"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,oBAAoB,GAAG,kCAAkC,GAAG,iBAAiB,CAAC;IACpF,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAMF,KAAK,aAAa,GAAG;IAAE,IAAI,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAEvC,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAuEzD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAmCzD;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,YAAY,GACnB,YAAY,CAad"}
package/dist/cli.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
2
3
  import { extname, join } from "node:path";
3
4
  import { fileURLToPath } from "node:url";
4
5
  import { Command, CommanderError, InvalidArgumentError } from "commander";
5
- import { CookieSessionStore, PlaywrightFigmaGateway, PlaywrightLogin, createFigmaScraperCore } from "@figtools/core";
6
+ import { CookieSessionStore, PlaywrightFigmaNodeSource, PlaywrightLogin, createFigmaScraperCore } from "@figtools/core";
6
7
  import { mkdir, writeFile } from "node:fs/promises";
7
8
  async function resolveAll(core, urls) {
8
9
  const sessionResult = await core.ensureSession();
@@ -55,70 +56,148 @@ function slugifyWithCollisions(names) {
55
56
  function isFigmaPage(result) {
56
57
  return "nodes" in result;
57
58
  }
59
+ function colorToHex({ r, g, b, a }) {
60
+ const hex = [
61
+ r,
62
+ g,
63
+ b
64
+ ].map((c)=>Math.round(c).toString(16).padStart(2, "0")).join("").toUpperCase();
65
+ return a < 1 ? `#${hex} ${Math.round(100 * a)}%` : `#${hex}`;
66
+ }
58
67
  function formatPaint(paint) {
59
- const { r, g, b, a } = paint.color;
60
- const color = `rgba(${r}, ${g}, ${b}, ${a})`;
61
- return paint.styleName ? `${paint.styleName} (${color})` : color;
68
+ const hex = colorToHex(paint.color);
69
+ return paint.styleName ? `${hex} (${paint.styleName})` : hex;
70
+ }
71
+ function formatEffect(effect) {
72
+ const color = effect.color ? colorToHex(effect.color) : "";
73
+ return [
74
+ effect.type,
75
+ `x=${effect.x}`,
76
+ `y=${effect.y}`,
77
+ `blur=${effect.blur}`,
78
+ `spread=${effect.spread}`,
79
+ color
80
+ ].filter(Boolean).join(" ");
62
81
  }
63
- function metadataLines(node) {
82
+ function formatSize(value, mode) {
83
+ if ("Fill" === mode) return null !== value ? `Fill (${value}px)` : "Fill";
84
+ if (null === value) return null;
85
+ if ("Hug" === mode) return `Hug (${value}px)`;
86
+ if ("Fixed" === mode) return `Fixed (${value}px)`;
87
+ return `${value}px`;
88
+ }
89
+ function nodePropertyLines(node) {
64
90
  const lines = [
65
91
  `type: ${node.type}`
66
92
  ];
67
- if (null !== node.position.x && null !== node.position.y) lines.push(`position: x=${node.position.x}, y=${node.position.y}`);
68
- if (null !== node.size.width && null !== node.size.height) lines.push(`size: width=${node.size.width}, height=${node.size.height}`);
69
- const { typography, fills, strokes, ...rest } = node.styles;
70
- for (const [key, value] of Object.entries(rest))if (void 0 !== value) lines.push(`${key}: ${value}`);
71
- if (fills && fills.length > 0) lines.push(`fills: ${fills.map(formatPaint).join(", ")}`);
72
- if (strokes && strokes.length > 0) lines.push(`strokes: ${strokes.map(formatPaint).join(", ")}`);
93
+ if (!node.visible) lines.push("visible: false");
94
+ const { flow, widthSizing, heightSizing, fills, strokes, strokeWeight, strokeSide, cornerRadius, effects, opacity, paddingTop, paddingRight, paddingBottom, paddingLeft, itemSpacing, typography } = node.styles;
95
+ const layoutLines = [];
96
+ if (flow) layoutLines.push(`Flow: ${flow}`);
97
+ if (null !== node.position.x && null !== node.position.y) layoutLines.push(`Position: x=${node.position.x} y=${node.position.y}`);
98
+ const w = formatSize(node.size.width, widthSizing);
99
+ const h = formatSize(node.size.height, heightSizing);
100
+ if (null !== w) layoutLines.push(`Width: ${w}`);
101
+ if (null !== h) layoutLines.push(`Height: ${h}`);
102
+ if (void 0 !== paddingTop) layoutLines.push(`Padding top: ${paddingTop}px`);
103
+ if (void 0 !== paddingRight) layoutLines.push(`Padding right: ${paddingRight}px`);
104
+ if (void 0 !== paddingBottom) layoutLines.push(`Padding bottom: ${paddingBottom}px`);
105
+ if (void 0 !== paddingLeft) layoutLines.push(`Padding left: ${paddingLeft}px`);
106
+ if (void 0 !== itemSpacing) layoutLines.push(`Gap: ${itemSpacing}px`);
107
+ if (void 0 !== opacity) layoutLines.push(`Opacity: ${opacity}%`);
108
+ if (layoutLines.length > 0) lines.push("", "## Layout", ...layoutLines);
109
+ if (fills && fills.length > 0) lines.push("", "## Fill", ...fills.map(formatPaint));
110
+ const borderLines = [];
111
+ if (void 0 !== strokeWeight || strokes && strokes.length > 0) {
112
+ const label = strokeSide ? `Border ${strokeSide.toLowerCase()}` : "Border";
113
+ const parts = [];
114
+ if (void 0 !== strokeWeight) parts.push(`${strokeWeight}px`);
115
+ if (strokes && strokes.length > 0) parts.push(strokes.map(formatPaint).join(", "));
116
+ borderLines.push(`${label}: ${parts.join(" ")}`);
117
+ }
118
+ if (void 0 !== cornerRadius) borderLines.push(`Radius: ${cornerRadius}px`);
119
+ if (effects && effects.length > 0) for (const effect of effects)borderLines.push(formatEffect(effect));
120
+ if (borderLines.length > 0) lines.push("", "## Border", ...borderLines);
73
121
  if (typography) {
74
- for (const [key, value] of Object.entries(typography))if (null != value) lines.push(`typography.${key}: ${value}`);
122
+ const typoLines = [];
123
+ if (typography.styleName) typoLines.push(`Text style: ${typography.styleName}`);
124
+ if (typography.fontFamily) typoLines.push(`Font: ${typography.fontFamily}`);
125
+ if (typography.style) typoLines.push(`Style: ${typography.style}`);
126
+ if (null !== typography.fontWeight && void 0 !== typography.fontWeight) typoLines.push(`Weight: ${typography.fontWeight}`);
127
+ if (null !== typography.fontSize && void 0 !== typography.fontSize) typoLines.push(`Size: ${typography.fontSize}px`);
128
+ if (null !== typography.lineHeightPx && void 0 !== typography.lineHeightPx) typoLines.push(`Line height: ${typography.lineHeightPx}px`);
129
+ if (void 0 !== typography.letterSpacing) typoLines.push(`Letter spacing: ${typography.letterSpacing}`);
130
+ if (typography.textAlignHorizontal) typoLines.push(`Align: ${typography.textAlignHorizontal}`);
131
+ if (typography.textAlignVertical) typoLines.push(`Vertical align: ${typography.textAlignVertical}`);
132
+ if (typoLines.length > 0) lines.push("", "## Typography", ...typoLines);
75
133
  }
134
+ if (null !== node.characters) lines.push("", "## Content", node.characters);
76
135
  return lines;
77
136
  }
78
- function leafContent(node) {
79
- return `# ${node.name}\n\n${metadataLines(node).join("\n")}\n`;
137
+ function mediaHead(node, slug, format) {
138
+ const lines = [];
139
+ if (null !== node.image) lines.push(`![${node.name}](./${slug}.${format})`);
140
+ if (null !== node.svgCode) lines.push(`[SVG](./${slug}.svg)`);
141
+ return lines.length > 0 ? `\n\n${lines.join("\n")}` : "";
80
142
  }
81
- function containerContent(name, children, childSlugs) {
82
- const links = children.map((child, i)=>{
83
- const slug = childSlugs[i];
84
- const href = 0 === child.children.length ? `${slug}.md` : `${slug}/index.md`;
85
- return `- [${child.name}](${href})`;
86
- }).join("\n");
143
+ function nodeContent(node, slug, format) {
144
+ return `# ${node.name}${mediaHead(node, slug, format)}\n\n${nodePropertyLines(node).join("\n")}\n`;
145
+ }
146
+ function pageContent(name, nodes, childSlugs) {
147
+ const links = nodes.map((node, i)=>`- [${node.name}](${childSlugs[i]}/index.md)`).join("\n");
87
148
  return `# ${name}\n\n${links}\n`;
88
149
  }
89
- async function writeChildNode(node, parentDir, slug) {
90
- if (0 === node.children.length) return void await writeFile(join(parentDir, `${slug}.md`), leafContent(node), "utf8");
150
+ function containerContent(node, childSlugs, slug, format) {
151
+ const meta = nodePropertyLines(node);
152
+ const links = node.children.map((child, i)=>`- [${child.name}](${childSlugs[i]}/index.md)`).join("\n");
153
+ return `# ${node.name}${mediaHead(node, slug, format)}\n\n${meta.join("\n")}\n\n## Children\n\n${links}\n`;
154
+ }
155
+ async function writeNodeAssets(node, dir, slug, format) {
156
+ if (null !== node.image) await writeFile(join(dir, `${slug}.${format}`), node.image);
157
+ if (null !== node.svgCode) await writeFile(join(dir, `${slug}.svg`), node.svgCode, "utf8");
158
+ }
159
+ async function writeChildNode(node, parentDir, slug, options) {
91
160
  const nodeDir = join(parentDir, slug);
92
161
  await mkdir(nodeDir, {
93
162
  recursive: true
94
163
  });
164
+ const format = options.imageFormat ?? "png";
165
+ await writeNodeAssets(node, nodeDir, slug, format);
166
+ if (0 === node.children.length) return void await writeFile(join(nodeDir, "index.md"), nodeContent(node, slug, format), "utf8");
95
167
  const childSlugs = slugifyWithCollisions(node.children.map((c)=>c.name));
96
- await writeFile(join(nodeDir, "index.md"), containerContent(node.name, node.children, childSlugs), "utf8");
97
- for(let i = 0; i < node.children.length; i++)await writeChildNode(node.children[i], nodeDir, childSlugs[i]);
168
+ await writeFile(join(nodeDir, "index.md"), containerContent(node, childSlugs, slug, format), "utf8");
169
+ for(let i = 0; i < node.children.length; i++)await writeChildNode(node.children[i], nodeDir, childSlugs[i], options);
98
170
  }
99
171
  async function writeAsMarkdownTree(fileKey, result, options) {
100
172
  const fileKeyDir = join(options.outputDir, fileKey);
101
173
  await mkdir(fileKeyDir, {
102
174
  recursive: true
103
175
  });
176
+ const format = options.imageFormat ?? "png";
104
177
  if (isFigmaPage(result)) {
105
178
  const childSlugs = slugifyWithCollisions(result.nodes.map((n)=>n.name));
106
- await writeFile(join(fileKeyDir, "index.md"), containerContent(result.name, result.nodes, childSlugs), "utf8");
107
- for(let i = 0; i < result.nodes.length; i++)await writeChildNode(result.nodes[i], fileKeyDir, childSlugs[i]);
179
+ await writeFile(join(fileKeyDir, "index.md"), pageContent(result.name, result.nodes, childSlugs), "utf8");
180
+ for(let i = 0; i < result.nodes.length; i++)await writeChildNode(result.nodes[i], fileKeyDir, childSlugs[i], options);
108
181
  return;
109
182
  }
183
+ const [slug] = slugifyWithCollisions([
184
+ result.name
185
+ ]);
110
186
  if (0 === result.children.length) {
111
- const [slug] = slugifyWithCollisions([
112
- result.name
113
- ]);
114
- await writeFile(join(fileKeyDir, `${slug}.md`), leafContent(result), "utf8");
187
+ const nodeDir = join(fileKeyDir, slug);
188
+ await mkdir(nodeDir, {
189
+ recursive: true
190
+ });
191
+ await writeNodeAssets(result, nodeDir, slug, format);
192
+ await writeFile(join(nodeDir, "index.md"), nodeContent(result, slug, format), "utf8");
115
193
  return;
116
194
  }
195
+ await writeNodeAssets(result, fileKeyDir, slug, format);
117
196
  const childSlugs = slugifyWithCollisions(result.children.map((c)=>c.name));
118
- await writeFile(join(fileKeyDir, "index.md"), containerContent(result.name, result.children, childSlugs), "utf8");
119
- for(let i = 0; i < result.children.length; i++)await writeChildNode(result.children[i], fileKeyDir, childSlugs[i]);
197
+ await writeFile(join(fileKeyDir, "index.md"), containerContent(result, childSlugs, slug, format), "utf8");
198
+ for(let i = 0; i < result.children.length; i++)await writeChildNode(result.children[i], fileKeyDir, childSlugs[i], options);
120
199
  }
121
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"0.2.1","h_":"Resolves one or more Figma URLs from the command line and writes the result as JSON or as a navigable markdown tree meant to be used as a data source by an LLM."}');
200
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"0.3.1","h_":"Resolves one or more Figma URLs from the command line and writes the result as JSON or as a navigable markdown tree meant to be used as a data source by an LLM."}');
122
201
  function createProgram() {
123
202
  let output = "";
124
203
  let parsed;
@@ -132,11 +211,12 @@ function createProgram() {
132
211
  });
133
212
  const resolveCommand = program.command("resolve", {
134
213
  isDefault: true
135
- }).description("Resolve one or more Figma URLs and write the result").argument("<urls...>", "One or more Figma URLs to resolve").option("--format <format>", "Output format (json or markdown)", parseFormat, "json").option("--output <path>", "File or directory to write the result to").option("--quiet", "Suppress progress messages on stderr", false).action((urls, opts)=>{
214
+ }).description("Resolve one or more Figma URLs and write the result").argument("<urls...>", "One or more Figma URLs to resolve").option("--format <format>", "Output format (json or markdown)", parseFormat, "json").option("--image-format <format>", "Image format for node previews (webp, png, jpg)", parseImageFormat, "png").option("--output <path>", "File or directory to write the result to").option("--quiet", "Suppress progress messages on stderr", false).action((urls, opts)=>{
136
215
  parsed = {
137
216
  urls,
138
217
  format: opts.format,
139
218
  outputPath: opts.output,
219
+ imageFormat: opts.imageFormat,
140
220
  quiet: opts.quiet
141
221
  };
142
222
  });
@@ -146,6 +226,7 @@ function createProgram() {
146
226
  command: "login",
147
227
  urls: [],
148
228
  format: "json",
229
+ imageFormat: "png",
149
230
  quiet: false
150
231
  };
151
232
  });
@@ -160,6 +241,10 @@ function parseFormat(value) {
160
241
  if ("json" !== value && "markdown" !== value) throw new InvalidArgumentError("Allowed choices are json, markdown.");
161
242
  return value;
162
243
  }
244
+ function parseImageFormat(value) {
245
+ if ("webp" !== value && "png" !== value && "jpg" !== value) throw new InvalidArgumentError("Allowed choices are webp, png, jpg.");
246
+ return value;
247
+ }
163
248
  function parseArgs(argv) {
164
249
  const { program, getParsed, getOutput } = createProgram();
165
250
  try {
@@ -251,11 +336,11 @@ async function main(argv) {
251
336
  process.stderr.write(`Error: ${parsed.error.message}\n`);
252
337
  process.exit(1);
253
338
  }
254
- const { command, urls, format, outputPath, quiet } = parsed.value;
339
+ const { command, urls, format, outputPath, imageFormat, quiet } = parsed.value;
255
340
  const core = createFigmaScraperCore({
256
341
  sessionStore: new CookieSessionStore(),
257
342
  interactiveLogin: new PlaywrightLogin(),
258
- gateway: new PlaywrightFigmaGateway()
343
+ gateway: new PlaywrightFigmaNodeSource()
259
344
  });
260
345
  if ("login" === command) {
261
346
  const result = await core.reauthenticate();
@@ -283,7 +368,8 @@ async function main(argv) {
283
368
  if ("markdown" === format) {
284
369
  const dir = "directory" === outputTarget.kind ? outputTarget.path : ".";
285
370
  await writeAsMarkdownTree(fileKey, result.value, {
286
- outputDir: dir
371
+ outputDir: dir,
372
+ imageFormat
287
373
  });
288
374
  } else {
289
375
  const writePath = "file" === outputTarget.kind ? outputTarget.path : "directory" === outputTarget.kind ? outputTarget.path : void 0;
@@ -299,5 +385,13 @@ async function main(argv) {
299
385
  }
300
386
  process.exit(hadFailure ? 1 : 0);
301
387
  }
302
- if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(2));
388
+ function isMainModule() {
389
+ if (!process.argv[1]) return false;
390
+ try {
391
+ return realpathSync(process.argv[1]) === fileURLToPath(import.meta.url);
392
+ } catch {
393
+ return false;
394
+ }
395
+ }
396
+ if (isMainModule()) main(process.argv.slice(2));
303
397
  export { decideOutputTarget, parseArgs };
@@ -1,6 +1,7 @@
1
1
  import type { FigmaScrapeResult } from "@figtools/core";
2
2
  export interface MarkdownWriterOptions {
3
3
  outputDir: string;
4
+ imageFormat?: "webp" | "png" | "jpg";
4
5
  }
5
6
  export declare function writeAsMarkdownTree(fileKey: string, result: FigmaScrapeResult, options: MarkdownWriterOptions): Promise<void>;
6
7
  //# sourceMappingURL=markdown-writer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-writer.d.ts","sourceRoot":"","sources":["../../src/output/markdown-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoC,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAG1F,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAyED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAgCf"}
1
+ {"version":3,"file":"markdown-writer.d.ts","sourceRoot":"","sources":["../../src/output/markdown-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiD,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGvG,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;CACtC;AA8KD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@figtools/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "Resolves one or more Figma URLs from the command line and writes the result as JSON or as a navigable markdown tree meant to be used as a data source by an LLM.",
5
5
  "keywords": [
6
6
  "figma",
@@ -36,7 +36,7 @@
36
36
  "dependencies": {
37
37
  "commander": "^15.0.0",
38
38
  "playwright": "^1.61.1",
39
- "@figtools/core": "0.1.0"
39
+ "@figtools/core": "0.2.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@rslib/core": "^0.23.2",