agent-orchestrator-kit 0.1.11 → 0.1.12

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/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.12] - 2026-07-21
8
+
9
+ ### Added
10
+ - **`figma-fetch --depth <n>`** — limit Figma node tree depth for large frames (omit = full tree)
11
+
12
+ ### Fixed
13
+ - **`figma-fetch` large payloads** — write API response text as-is instead of pretty-printing via `JSON.stringify` (avoids `Invalid string length` on huge trees)
14
+ - Clearer error when Figma API returns a non-JSON body
15
+
7
16
  ## [0.1.11] - 2026-07-21
8
17
 
9
18
  ### Added
package/README.md CHANGED
@@ -624,6 +624,8 @@ npx agent-orchestrator-kit figma-setup
624
624
  npx agent-orchestrator-kit figma-status
625
625
  npx agent-orchestrator-kit figma-fetch --url "https://www.figma.com/design/FILE_KEY/Name?node-id=1-2" \
626
626
  --out openspec/changes/<name>/assets/figma-nodes.json
627
+ # large frames: limit tree depth
628
+ npx agent-orchestrator-kit figma-fetch --file FILE_KEY --nodes 1:2 --depth 2 --out figma-nodes.json
627
629
  ```
628
630
 
629
631
  `figma-fetch` uses the Figma REST API (`X-Figma-Token`) and writes JSON for design-brief capture. Live Figma is for design-intake only — apply uses `design-brief.md`.
@@ -753,6 +755,10 @@ openspec/ # Committed — spec-driven workflow
753
755
 
754
756
  ## Changelog
755
757
 
758
+ ### 0.1.12
759
+ - `figma-fetch --depth <n>` for large frames
760
+ - Write large Figma JSON as raw API text (avoids `Invalid string length` on huge trees)
761
+
756
762
  ### 0.1.11
757
763
  - Optional **Figma personal token** setup: `.agents/figma.local.env` (gitignored) + `figma-mcp-launcher.cjs` (no secret in `.mcp.json`)
758
764
  - CLI: `figma-setup`, `figma-status`, `figma-fetch` (REST nodes/file JSON)
@@ -260,13 +260,17 @@ async function figmaApiGet(token, path) {
260
260
  try {
261
261
  data = JSON.parse(text);
262
262
  } catch {
263
- data = { err: text };
263
+ data = null;
264
264
  }
265
265
  if (!response.ok) {
266
- const message = data?.err || data?.message || response.statusText || `HTTP ${response.status}`;
266
+ const message =
267
+ (data && (data.err || data.message)) || response.statusText || `HTTP ${response.status}`;
267
268
  throw new Error(String(message));
268
269
  }
269
- return data;
270
+ if (!data) {
271
+ throw new Error('Figma API returned non-JSON response');
272
+ }
273
+ return { data, text };
270
274
  }
271
275
 
272
276
  function resolveTemplate(templateName, profile) {
@@ -1063,6 +1067,7 @@ program
1063
1067
  .option('--url <url>', 'Figma design URL (file key + optional node-id)')
1064
1068
  .option('--file <key>', 'Figma file key')
1065
1069
  .option('--nodes <ids>', 'Comma-separated node ids (1:2 or 1-2)')
1070
+ .option('--depth <n>', 'Limit node tree depth (use for large frames; omit = full tree)')
1066
1071
  .option('--out <path>', 'Output JSON path', 'figma-nodes.json')
1067
1072
  .action(async (opts) => {
1068
1073
  const projectDir = process.cwd();
@@ -1096,16 +1101,36 @@ program
1096
1101
  .filter(Boolean)
1097
1102
  .map((id) => id.replace(/-/g, ':'));
1098
1103
 
1104
+ const query = [];
1105
+ if (nodeIds.length) {
1106
+ query.push(`ids=${encodeURIComponent(nodeIds.join(','))}`);
1107
+ }
1108
+ if (opts.depth != null && String(opts.depth).trim() !== '') {
1109
+ const depth = Number(opts.depth);
1110
+ if (!Number.isInteger(depth) || depth < 1) {
1111
+ log.err('--depth must be a positive integer');
1112
+ process.exitCode = 1;
1113
+ return;
1114
+ }
1115
+ query.push(`depth=${depth}`);
1116
+ }
1117
+
1099
1118
  try {
1100
- const path = nodeIds.length
1101
- ? `/files/${encodeURIComponent(fileKey)}/nodes?ids=${encodeURIComponent(nodeIds.join(','))}`
1102
- : `/files/${encodeURIComponent(fileKey)}`;
1103
- log.info(nodeIds.length ? `Fetching ${nodeIds.length} node(s)…` : 'Fetching full file…');
1104
- const data = await figmaApiGet(token, path);
1119
+ const apiPath = nodeIds.length
1120
+ ? `/files/${encodeURIComponent(fileKey)}/nodes${query.length ? `?${query.join('&')}` : ''}`
1121
+ : `/files/${encodeURIComponent(fileKey)}${query.length ? `?${query.join('&')}` : ''}`;
1122
+ log.info(
1123
+ nodeIds.length
1124
+ ? `Fetching ${nodeIds.length} node(s)${opts.depth ? ` (depth ${opts.depth})` : ''}…`
1125
+ : `Fetching full file${opts.depth ? ` (depth ${opts.depth})` : ''}…`
1126
+ );
1127
+ const { data, text } = await figmaApiGet(token, apiPath);
1105
1128
  const outPath = join(projectDir, opts.out);
1106
1129
  mkdirSync(dirname(outPath), { recursive: true });
1107
- writeFileSync(outPath, `${JSON.stringify(data, null, 2)}\n`);
1108
- log.ok(`Wrote ${opts.out}`);
1130
+ // Write API payload as-is — pretty-print of huge trees can throw "Invalid string length"
1131
+ writeFileSync(outPath, text.endsWith('\n') ? text : `${text}\n`);
1132
+ const nodeCount = data.nodes ? Object.keys(data.nodes).length : 0;
1133
+ log.ok(`Wrote ${opts.out}${nodeCount ? ` (${nodeCount} node key(s))` : ''}`);
1109
1134
  } catch (error) {
1110
1135
  log.err(`Figma API error: ${error.message}`);
1111
1136
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-orchestrator-kit",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "Universal AI agent orchestration kit for Cursor, Claude Code, and Amp Code — spec-driven OpenSpec pipeline, cross-IDE subagents, and optional local Figma PAT setup (figma-setup / figma-status / figma-fetch)",
5
5
  "keywords": [
6
6
  "ai-agent",