{"data":{"skill":{"slug":"heygen-com-figma","name":"figma","icon":"📦","repo":"https://github.com/heygen-com/hyperframes/tree/main/skills/figma/","status":"approved","author":"heygen-com","authorVersion":null,"skillstoreRevision":2},"audit":{"id":"dbc298ca-46e3-40e0-b86f-b73eb067591b","skill_id":"f0b39598-6087-48e1-ab7d-2c318eeebd5b","version":5,"content_hash":"v3:77d0e66fbadeb1f5d1e6a5aada7861240b8ed2d7:c985935aa8d64acdb3ab8dbbc7920fd6b60117e37bc4f20942cb5552d934d25b:21691a40f4d5fb6ce954521f35e5c5183b0c72c855f0fb9ecf9cc0ce7bac5433:736b696c6c732f68657967656e2d636f6d2f6669676d61:076fa8c981274309e286a9df67e65360","risk_level":"high","is_blocked":false,"safe_to_publish":false,"analysis_status":"ok","agent_auto_install_policy":"confirmation_required","manual_install_policy":"allowed","summary":"Most static alerts are false positives caused by Markdown backticks or a local ffmpeg verification helper that uses fixed executables with argument arrays. Two material issues remain: the skill requests a silent, unpinned npx self-update, and it recommends persistent storage of a Figma access token without sufficient safeguards. No prompt-injection text or intentional data-exfiltration behavior was found.","remediation":[{"issue":"Silent unpinned npx self-update","severity":"high","suggestion":"Remove the automatic update instruction. Ask for explicit user confirmation and use a pinned, integrity-verified release when an update is requested."},{"issue":"Persistent Figma token guidance","severity":"high","suggestion":"Recommend a secret manager or a local ignored credential file, warn users never to commit tokens, and document restrictive file permissions."},{"issue":"Temporary artifact cleanup on failures","severity":"low","suggestion":"Wrap temporary-directory processing in a try/finally block so ffmpeg failures do not leave exported frames on disk."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"scripts/verify-motion.mjs","line_end":24,"line_start":24},{"file":"scripts/verify-motion.mjs","line_end":47,"line_start":47},{"file":"scripts/verify-motion.mjs","line_end":63,"line_start":63},{"file":"scripts/verify-motion.mjs","line_end":94,"line_start":94},{"file":"scripts/verify-motion.mjs","line_end":97,"line_start":97},{"file":"scripts/verify-motion.mjs","line_end":111,"line_start":111},{"file":"scripts/verify-motion.mjs","line_end":5,"line_start":5},{"file":"scripts/verify-motion.mjs","line_end":30,"line_start":30},{"file":"scripts/verify-motion.mjs","line_end":87,"line_start":87},{"file":"scripts/verify-motion.mjs","line_end":118,"line_start":118},{"file":"scripts/verify-motion.mjs","line_end":140,"line_start":140},{"file":"scripts/verify-motion.mjs","line_end":143,"line_start":143},{"file":"SKILL.md","line_end":6,"line_start":6},{"file":"SKILL.md","line_end":14,"line_start":14},{"file":"SKILL.md","line_end":15,"line_start":15},{"file":"SKILL.md","line_end":16,"line_start":16},{"file":"SKILL.md","line_end":17,"line_start":17},{"file":"SKILL.md","line_end":24,"line_start":24},{"file":"SKILL.md","line_end":27,"line_start":27},{"file":"SKILL.md","line_end":28,"line_start":28},{"file":"SKILL.md","line_end":34,"line_start":34},{"file":"SKILL.md","line_end":36,"line_start":36},{"file":"SKILL.md","line_end":40,"line_start":40},{"file":"SKILL.md","line_end":55,"line_start":53},{"file":"SKILL.md","line_end":57,"line_start":55},{"file":"SKILL.md","line_end":57,"line_start":57},{"file":"SKILL.md","line_end":59,"line_start":59},{"file":"SKILL.md","line_end":65,"line_start":63},{"file":"SKILL.md","line_end":67,"line_start":65},{"file":"SKILL.md","line_end":67,"line_start":67},{"file":"SKILL.md","line_end":71,"line_start":71},{"file":"SKILL.md","line_end":73,"line_start":73},{"file":"SKILL.md","line_end":79,"line_start":77},{"file":"SKILL.md","line_end":81,"line_start":79},{"file":"SKILL.md","line_end":83,"line_start":81},{"file":"SKILL.md","line_end":83,"line_start":83},{"file":"SKILL.md","line_end":85,"line_start":84},{"file":"SKILL.md","line_end":85,"line_start":85},{"file":"SKILL.md","line_end":89,"line_start":89},{"file":"SKILL.md","line_end":93,"line_start":91},{"file":"SKILL.md","line_end":93,"line_start":93},{"file":"SKILL.md","line_end":94,"line_start":94},{"file":"SKILL.md","line_end":95,"line_start":95},{"file":"SKILL.md","line_end":96,"line_start":96},{"file":"SKILL.md","line_end":97,"line_start":97},{"file":"SKILL.md","line_end":111,"line_start":98},{"file":"SKILL.md","line_end":115,"line_start":111},{"file":"SKILL.md","line_end":120,"line_start":115},{"file":"SKILL.md","line_end":127,"line_start":120},{"file":"SKILL.md","line_end":132,"line_start":127}]},{"factor":"filesystem","evidence":[{"file":"scripts/verify-motion.mjs","line_end":25,"line_start":25},{"file":"scripts/verify-motion.mjs","line_end":90,"line_start":90}]},{"factor":"scripts","evidence":[{"file":"SKILL.md","line_end":126,"line_start":126}]}],"critical_findings":[],"high_findings":[{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":6,"line_start":6}],"confidence":0.96,"description":"> **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update figma`.","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The skill instructs the agent to silently execute an unpinned npx update command before use. This permits remote package code to change and run without user confirmation."},{"title":"Environment file access","locations":[{"file":"SKILL.md","line_end":28,"line_start":28}],"confidence":0.88,"description":"3. `export FIGMA_TOKEN=\"figd_...\"` — and suggest persisting it (shell profile or project `.env`) so ","review_kind":"security","source_category":"sensitive","source_severity":"high","confidence_reasoning":"The documentation recommends persisting a Figma access token in a shell profile or project .env file. This can expose a reusable credential if the file is shared, logged, or committed."},{"title":"Silent Unpinned Self-Update","locations":[{"file":"SKILL.md","line_end":6,"line_start":6}],"confidence":0.97,"description":"The skill directs an agent to run a silent npx self-update before use. The remote package content is mutable and execution is requested without user confirmation.","review_kind":"security","source_category":"semantic","source_severity":"high","confidence_reasoning":"The instruction explicitly says to run silently and names an npx update command. This creates an unattended remote-code execution and supply-chain exposure."},{"title":"Credential Persistence Guidance","locations":[{"file":"SKILL.md","line_end":28,"line_start":28}],"confidence":0.9,"description":"The setup guidance encourages persisting a Figma personal access token in a shell profile or project .env file without a warning about access controls or version control.","review_kind":"security","source_category":"semantic","source_severity":"high","confidence_reasoning":"The line explicitly directs persistent storage of a reusable token. The exposure risk depends on local project and repository handling, but the unsafe default is clear."}],"medium_findings":[],"low_findings":[],"dangerous_patterns":[],"files_scanned":2,"total_lines":285,"audit_model":"claude","audited_at":"2026-07-19T10:42:39.789+00:00","created_at":"2026-07-19T15:34:04.746355+00:00","static_findings":[{"id":"external_commands:scripts/verify-motion.mjs:24:node-js-child-process-module","file":"scripts/verify-motion.mjs","pattern":"Node.js child_process module","snippet":"import { execFileSync, spawnSync } from \"node:child_process\";","category":"external_commands","line_end":24,"severity":"high","line_start":24},{"id":"external_commands:scripts/verify-motion.mjs:47:synchronous-file-execution","file":"scripts/verify-motion.mjs","pattern":"Synchronous file execution","snippet":"execFileSync(\"ffprobe\", [","category":"external_commands","line_end":47,"severity":"high","line_start":47},{"id":"external_commands:scripts/verify-motion.mjs:63:synchronous-file-execution","file":"scripts/verify-motion.mjs","pattern":"Synchronous file execution","snippet":"const dims = execFileSync(\"ffprobe\", [","category":"external_commands","line_end":63,"severity":"high","line_start":63},{"id":"external_commands:scripts/verify-motion.mjs:94:synchronous-file-execution","file":"scripts/verify-motion.mjs","pattern":"Synchronous file execution","snippet":"execFileSync(\"ffmpeg\", args.concat(dst));","category":"external_commands","line_end":94,"severity":"high","line_start":94},{"id":"external_commands:scripts/verify-motion.mjs:97:synchronous-file-execution","file":"scripts/verify-motion.mjs","pattern":"Synchronous file execution","snippet":"execFileSync(\"ffmpeg\", [","category":"external_commands","line_end":97,"severity":"high","line_start":97},{"id":"external_commands:scripts/verify-motion.mjs:111:synchronous-spawn","file":"scripts/verify-motion.mjs","pattern":"Synchronous spawn","snippet":"const r = spawnSync(\"ffmpeg\", [\"-i\", a, \"-i\", b, \"-lavfi\", \"psnr\", \"-f\", \"null\", \"-\"], {","category":"external_commands","line_end":111,"severity":"high","line_start":111},{"id":"external_commands:scripts/verify-motion.mjs:5:ruby-shell-backtick-execution","file":"scripts/verify-motion.mjs","pattern":"Ruby/shell backtick execution","snippet":"* Compares the HyperFrames render against Figma's own `export_video` output","category":"external_commands","line_end":5,"severity":"medium","line_start":5},{"id":"external_commands:scripts/verify-motion.mjs:30:ruby-shell-backtick-execution","file":"scripts/verify-motion.mjs","pattern":"Ruby/shell backtick execution","snippet":"const i = process.argv.indexOf(`--${name}`);","category":"external_commands","line_end":30,"severity":"medium","line_start":30},{"id":"external_commands:scripts/verify-motion.mjs:87:ruby-shell-backtick-execution","file":"scripts/verify-motion.mjs","pattern":"Ruby/shell backtick execution","snippet":"cropFilter = `crop=${m[1]}:${m[2]}:${m[3]}:${m[4]},`;","category":"external_commands","line_end":87,"severity":"medium","line_start":87},{"id":"external_commands:scripts/verify-motion.mjs:118:ruby-shell-backtick-execution","file":"scripts/verify-motion.mjs","pattern":"Ruby/shell backtick execution","snippet":"const renderVf = `${cropFilter}scale=${rw}:${rh}`;","category":"external_commands","line_end":118,"severity":"medium","line_start":118},{"id":"external_commands:scripts/verify-motion.mjs:140:ruby-shell-backtick-execution","file":"scripts/verify-motion.mjs","pattern":"Ruby/shell backtick execution","snippet":"`window ${r.t.toFixed(2)}s→${(r.t + interval).toFixed(2)}s  motion-psnr=${r.motion.toFixed(2)}dB  (a","category":"external_commands","line_end":140,"severity":"medium","line_start":140},{"id":"external_commands:scripts/verify-motion.mjs:143:ruby-shell-backtick-execution","file":"scripts/verify-motion.mjs","pattern":"Ruby/shell backtick execution","snippet":"`\\nwindows=${results.length} min-motion=${min.toFixed(2)}dB mean-motion=${mean.toFixed(2)}dB thresho","category":"external_commands","line_end":143,"severity":"medium","line_start":143},{"id":"filesystem:scripts/verify-motion.mjs:25:temp-file-creation","file":"scripts/verify-motion.mjs","pattern":"Temp file creation","snippet":"import { mkdtempSync, rmSync } from \"node:fs\";","category":"filesystem","line_end":25,"severity":"low","line_start":25},{"id":"filesystem:scripts/verify-motion.mjs:90:temp-file-creation","file":"scripts/verify-motion.mjs","pattern":"Temp file creation","snippet":"const dir = mkdtempSync(join(tmpdir(), \"verify-motion-\"));","category":"filesystem","line_end":90,"severity":"low","line_start":90},{"id":"scripts:SKILL.md:126:dynamic-import-expression","file":"SKILL.md","pattern":"Dynamic import() expression","snippet":"8. **Stills vs. components routing**: a note describing motion _between_ scenes → transition on the ","category":"scripts","line_end":126,"severity":"medium","line_start":126},{"id":"external_commands:SKILL.md:6:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"> **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update figma`.","category":"external_commands","line_end":6,"severity":"medium","line_start":6},{"id":"external_commands:SKILL.md:14:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 1     | Static assets       | REST                         | `hyperframes figma asset`     |","category":"external_commands","line_end":14,"severity":"medium","line_start":14},{"id":"external_commands:SKILL.md:15:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 2     | Brand tokens/styles | REST                         | `hyperframes figma tokens`    |","category":"external_commands","line_end":15,"severity":"medium","line_start":15},{"id":"external_commands:SKILL.md:16:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 3     | Components → HTML   | REST                         | `hyperframes figma component` |","category":"external_commands","line_end":16,"severity":"medium","line_start":16},{"id":"external_commands:SKILL.md:17:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 4     | Motion → GSAP       | **MCP only**                 | you, via `get_motion_context` |","category":"external_commands","line_end":17,"severity":"medium","line_start":17},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Preflight — before the first CLI call, check a token exists**: shell env (`[ -n \"$FIGMA_TOKEN\" ]`)","category":"external_commands","line_end":24,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"2. Scopes — read-only is all this integration ever needs (it never writes to Figma): **File content:","category":"external_commands","line_end":27,"severity":"medium","line_start":27},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"3. `export FIGMA_TOKEN=\"figd_...\"` — and suggest persisting it (shell profile or project `.env`) so ","category":"external_commands","line_end":28,"severity":"medium","line_start":28},{"id":"external_commands:SKILL.md:34:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `BAD_TOKEN` (401) mid-flow → the token is expired/revoked; re-mint. `FORBIDDEN` (403) → the messag","category":"external_commands","line_end":34,"severity":"medium","line_start":34},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Rate-limit awareness (spec §2.1):** MCP on a Starter plan is 6 tool calls/**month** (figma plan ma","category":"external_commands","line_end":36,"severity":"medium","line_start":36},{"id":"external_commands:SKILL.md:40:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Parse the user's figma link with `parseFigmaRef` (URL, `fileKey:nodeId`, bare `fileKey`). Then by in","category":"external_commands","line_end":40,"severity":"medium","line_start":40},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":55,"severity":"medium","line_start":53},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":57,"severity":"medium","line_start":55},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Renders over REST, sanitizes SVG, freezes under `.media/images/`, appends the manifest with provenan","category":"external_commands","line_end":57,"severity":"medium","line_start":57},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Batch many nodes in ONE request** — pass several refs (space-separated or comma-joined) of the SAM","category":"external_commands","line_end":59,"severity":"medium","line_start":59},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":65,"severity":"medium","line_start":63},{"id":"external_commands:SKILL.md:65:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":67,"severity":"medium","line_start":65},{"id":"external_commands:SKILL.md:67:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Imports variables as composition brand-variable entries + `figma-tokens.json` sidecar + binding-inde","category":"external_commands","line_end":67,"severity":"medium","line_start":67},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Non-Enterprise variables path (field-tested):** REST variables are Enterprise-gated, but the Figma","category":"external_commands","line_end":71,"severity":"medium","line_start":71},{"id":"external_commands:SKILL.md:73:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"The runtime defines every declared composition variable as a CSS custom property (document root + su","category":"external_commands","line_end":73,"severity":"medium","line_start":73},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":79,"severity":"medium","line_start":77},{"id":"external_commands:SKILL.md:79:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":81,"severity":"medium","line_start":79},{"id":"external_commands:SKILL.md:81:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Node tree → editable HTML at exact figma geometry, packaged as a registry item under `compositions/c","category":"external_commands","line_end":83,"severity":"medium","line_start":81},{"id":"external_commands:SKILL.md:83:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **Static fidelity self-check (mandatory for hero content)**: after importing, render the fragment ","category":"external_commands","line_end":83,"severity":"medium","line_start":83},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Fill bound to an **imported** token → `var(--slug, #literal)` — brand refresh propagates.","category":"external_commands","line_end":85,"severity":"medium","line_start":84},{"id":"external_commands:SKILL.md:85:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Bound to an **unknown** token → literal + `data-figma-unresolved` flag. The command tells you; off","category":"external_commands","line_end":85,"severity":"medium","line_start":85},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Usage beacon:** MCP phases have no CLI touchpoint, so fire the skill beacon at start and finish (a","category":"external_commands","line_end":89,"severity":"medium","line_start":89},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"No REST equivalent exists. You drive the MCP tools, then hand output to the pure helpers in `@hyperf","category":"external_commands","line_end":93,"severity":"medium","line_start":91},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"1. `get_motion_context(fileKey, nodeId)` — use `recursive:true` on the parent frame (one call for th","category":"external_commands","line_end":93,"severity":"medium","line_start":93},{"id":"external_commands:SKILL.md:94:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"2. Normalize into `MotionDoc`s with `motionContextToDocs(rawResponse, { selectorFor, repeat })` from","category":"external_commands","line_end":94,"severity":"medium","line_start":94},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"2b. **Validate against ground truth before calling it done — mandatory**: `export_video` on the coho","category":"external_commands","line_end":95,"severity":"medium","line_start":95},{"id":"external_commands:SKILL.md:96:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"3. `motionToGsap(doc)` → `emitTimelineScript(spec)` → inject as a `<script>` after the GSAP + Custom","category":"external_commands","line_end":96,"severity":"medium","line_start":96},{"id":"external_commands:SKILL.md:97:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"4. Untranslatable track (shader-driven, unsupported prop, complex masks) → bake: `export_video` → fr","category":"external_commands","line_end":97,"severity":"medium","line_start":97},{"id":"external_commands:SKILL.md:98:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"5. Run `npx hyperframes check` before calling it done.","category":"external_commands","line_end":111,"severity":"medium","line_start":98},{"id":"external_commands:SKILL.md:111:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"2. **Order = x-position** (row-major if the strip wraps). Sort scenes by `absoluteBoundingBox.x`.","category":"external_commands","line_end":115,"severity":"medium","line_start":111},{"id":"external_commands:SKILL.md:115:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"6. **Batch exports** (elements or stills): `GET /v1/images` accepts comma-separated ids, but big sce","category":"external_commands","line_end":120,"severity":"medium","line_start":115},{"id":"external_commands:SKILL.md:120:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| EXPLOSION / BURST               | incoming scale ~1.5→1 + fade, `power3.out`                      ","category":"external_commands","line_end":127,"severity":"medium","line_start":120},{"id":"external_commands:SKILL.md:127:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"9. One `main` timeline sequences everything (opacity/x/y per scene at absolute times) — no per-scene","category":"external_commands","line_end":132,"severity":"medium","line_start":127},{"id":"external_commands:SKILL.md:132:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Never leave a Figma URL in the composition — freeze first. Never emit `repeat: -1`. Timelines paused","category":"external_commands","line_end":132,"severity":"medium","line_start":132},{"id":"sensitive:SKILL.md:24:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"**Preflight — before the first CLI call, check a token exists**: shell env (`[ -n \"$FIGMA_TOKEN\" ]`)","category":"sensitive","line_end":24,"severity":"high","line_start":24},{"id":"sensitive:SKILL.md:28:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"3. `export FIGMA_TOKEN=\"figd_...\"` — and suggest persisting it (shell profile or project `.env`) so ","category":"sensitive","line_end":28,"severity":"high","line_start":28},{"id":"blocker:SKILL.md:49:system-reconnaissance","file":"SKILL.md","pattern":"System reconnaissance","snippet":"**Narrate every step for the user** — before each command say what you're about to pull from Figma; ","category":"blocker","line_end":49,"severity":"low","line_start":49},{"id":"blocker:SKILL.md:102:system-reconnaissance","file":"SKILL.md","pattern":"System reconnaissance","snippet":"Figma's MCP render path does not execute shaders (they flatten to the base color), and shader source","category":"blocker","line_end":102,"severity":"low","line_start":102}],"finding_verdicts":[{"id":"external_commands:scripts/verify-motion.mjs:24:node-js-child-process-module","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:47:synchronous-file-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:63:synchronous-file-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:94:synchronous-file-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:97:synchronous-file-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:111:synchronous-spawn","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:5:ruby-shell-backtick-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:30:ruby-shell-backtick-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:87:ruby-shell-backtick-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:118:ruby-shell-backtick-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:140:ruby-shell-backtick-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/verify-motion.mjs:143:ruby-shell-backtick-execution","reason":"The verification utility invokes fixed ffmpeg or ffprobe binaries with argument arrays and never enables a shell. Its inputs are passed as arguments, and the crop value is constrained by a numeric regular expression.","verdict":"false_positive","confidence":0.94},{"id":"filesystem:scripts/verify-motion.mjs:25:temp-file-creation","reason":"The utility creates a uniquely named operating-system temporary directory and removes it recursively after use. No arbitrary destination or privileged path is used.","verdict":"false_positive","confidence":0.95},{"id":"filesystem:scripts/verify-motion.mjs:90:temp-file-creation","reason":"The utility creates a uniquely named operating-system temporary directory and removes it recursively after use. No arbitrary destination or privileged path is used.","verdict":"false_positive","confidence":0.95},{"id":"scripts:SKILL.md:126:dynamic-import-expression","reason":"The detected import() text is prose about component routing, not JavaScript code or a dynamic module load.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:6:ruby-shell-backtick-execution","reason":"The skill instructs the agent to silently execute an unpinned npx update command before use. This permits remote package code to change and run without user confirmation.","verdict":"confirmed","severity":"high","confidence":0.96},{"id":"external_commands:SKILL.md:14:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:15:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:16:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:17:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:34:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:40:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:65:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:67:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:73:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:79:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:81:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:83:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:85:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:94:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:96:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:97:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:98:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:111:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:115:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:120:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:127:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:132:ruby-shell-backtick-execution","reason":"This is Markdown documentation that names CLI commands, API paths, identifiers, or inline code. Backticks are formatting delimiters, not executable shell substitutions.","verdict":"false_positive","confidence":0.98},{"id":"sensitive:SKILL.md:24:environment-file-access","reason":"The preflight only checks whether FIGMA_TOKEN is configured and directs the user through setup if absent. It does not print, transmit, or otherwise expose the token.","verdict":"false_positive","confidence":0.94},{"id":"sensitive:SKILL.md:28:environment-file-access","reason":"The documentation recommends persisting a Figma access token in a shell profile or project .env file. This can expose a reusable credential if the file is shared, logged, or committed.","verdict":"confirmed","severity":"high","confidence":0.88},{"id":"blocker:SKILL.md:49:system-reconnaissance","reason":"This is user-facing workflow guidance or technical documentation, not a command that enumerates the host system.","verdict":"false_positive","confidence":0.98},{"id":"blocker:SKILL.md:102:system-reconnaissance","reason":"This is user-facing workflow guidance or technical documentation, not a command that enumerates the host system.","verdict":"false_positive","confidence":0.98}],"semantic_findings":[{"title":"Silent Unpinned Self-Update","severity":"high","locations":[{"file":"SKILL.md","line_end":6,"line_start":6}],"confidence":0.97,"description":"The skill directs an agent to run a silent npx self-update before use. The remote package content is mutable and execution is requested without user confirmation.","confidence_reasoning":"The instruction explicitly says to run silently and names an npx update command. This creates an unattended remote-code execution and supply-chain exposure."},{"title":"Credential Persistence Guidance","severity":"high","locations":[{"file":"SKILL.md","line_end":28,"line_start":28}],"confidence":0.9,"description":"The setup guidance encourages persisting a Figma personal access token in a shell profile or project .env file without a warning about access controls or version control.","confidence_reasoning":"The line explicitly directs persistent storage of a reusable token. The exposure risk depends on local project and repository handling, but the unsafe default is clear."}],"subject_marketplace_commit_sha":"77d0e66fbadeb1f5d1e6a5aada7861240b8ed2d7","subject_content_hash":"c985935aa8d64acdb3ab8dbbc7920fd6b60117e37bc4f20942cb5552d934d25b","subject_tree_hash":"21691a40f4d5fb6ce954521f35e5c5183b0c72c855f0fb9ecf9cc0ce7bac5433","subject_plugin_path":"skills/heygen-com/figma","audit_payload_hash":"076fa8c981274309e286a9df67e65360","confirmed_risk_level":"high","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"77d0e66fbadeb1f5d1e6a5aada7861240b8ed2d7","contentHash":"c985935aa8d64acdb3ab8dbbc7920fd6b60117e37bc4f20942cb5552d934d25b","treeHash":"21691a40f4d5fb6ce954521f35e5c5183b0c72c855f0fb9ecf9cc0ce7bac5433","pluginPath":"skills/heygen-com/figma","auditPayloadHash":"076fa8c981274309e286a9df67e65360"},"scannerVersion":"3.0.0","policyVersion":"skillstore-security-audit-policy-v1"},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"issued","url":"/api/skills/heygen-com-figma/audits/5/attestation","status":"active"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"high","confirmedFindingCount":3,"capabilityReviewCount":1,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"confirmation_required","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"active","verificationState":"not_verified"},"isLatest":true}}