/** * figma_map — cheapest possible file overview. * * Returns the page/frame tree (id + name + type + children) to configurable * depth. No visuals, no text content, no components. The ENTRY POINT tool: * the agent uses it to discover what exists and pick a targeted follow-up. * * Typical payload: 1-10 KB for most real files at depth=3. */ import { Type } from "@sinclair/typebox"; import { defineTool } from "@mariozechner/pi-coding-agent"; import { getFile, parseFileKey } from "../client.js"; import { outlineNode } from "../transforms.js"; export const mapTool = defineTool({ name: "figma_map", label: "Figma Map", description: "Map the page/frame structure of a Figma file (id + name + type only). Cheap. Call this first to discover node ids; then use figma_inspect for details on a specific frame.", promptSnippet: "figma_map(file, depth) — page/frame structure only, no visuals.", promptGuidelines: [ "Always call figma_map BEFORE figma_inspect to discover node ids cheaply.", "Use the smallest depth that reveals the frames you need (default 3 is fine for most files).", ], parameters: Type.Object({ file: Type.String({ description: "Figma file key OR full file URL (figma.com/file/... or /design/...).", }), depth: Type.Optional( Type.Integer({ minimum: 1, maximum: 10, description: "How many tree levels to include. Default 3. Increase only if needed.", }), ), }), async execute(_id, params, signal) { const fileKey = parseFileKey(params.file); const depth = params.depth ?? 3; const file = await getFile(fileKey, depth, signal); const outline = outlineNode(file.document, depth); const summary = { file: { name: file.name, key: fileKey, version: file.version, lastModified: file.lastModified }, depth, outline, }; return { content: [ { type: "text" as const, text: JSON.stringify(summary, null, 2), }, ], details: { fileKey, version: file.version, depth }, }; }, });