← EnkioCONTENT HISTORY

Update to Enkio

Snapshot Oct 26, 2026 · 06:08 UTC · version 1.0.1

Collection source: downloaded plugin package.

WHAT CHANGED

Instructions updated for reference-to-video

Skill instructions — Now says: **Membership check (required).** Creating tasks with `i2v_create_task` requires an active membership. If `get_user_profile()` returns an `is_member` value...

Observed in instructions or declared skills. Runtime behavior has not been tested.

Save Enkio and check future changes in Following.

Up to 10 plugins free · no card required.

All fields and original values.

Skill instructions

Before

Oct 24, 2026 · 13:32 UTC

No removed lines (ordering may have changed)

After

Oct 26, 2026 · 06:08 UTC

**Membership check (required).** Creating tasks with `i2v_create_task` requires an active membership. If `get_user_profile()` returns an `is_member` value other than `true`, stop here: call `get_pricing_url` and give the user the returne...

Supporting files

Before

Oct 24, 2026 · 13:32 UTC

[{"relative_path":"references/auth.md","size_in_bytes":4896},{"relative_path":"references/credits.md","size_in_bytes":3563},{"relative_path":"references/errors.md","size_in_bytes":7510},{"relative_path":"references/workflow.md","size_in_...

After

Oct 26, 2026 · 06:08 UTC

[{"relative_path":"references/auth.md","size_in_bytes":4896},{"relative_path":"references/credits.md","size_in_bytes":4031},{"relative_path":"references/errors.md","size_in_bytes":8433},{"relative_path":"references/workflow.md","size_in_...

Compare saved observations

Download comparison JSON

SKILL.md text changes

− removed · + added

--- before
+++ after
@@ -137,6 +137,13 @@
 The returned `credit` is the current credit balance. Record it so you can compare it with the estimated
 cost in Step 2.
 
+**Membership check (required).** Creating tasks with `i2v_create_task` requires an active membership. If
+`get_user_profile()` returns an `is_member` value other than `true`, stop here: call `get_pricing_url`
+and give the user the returned `pricing_url` to open in a browser, signed in with the same Wondershare
+account used to authorize this MCP, to purchase a membership. Do not continue with model selection,
+uploads, quoting, or task creation; after the user says the purchase is complete, call
+`get_user_profile()` again and continue only when `is_member` is `true`.
+
 ## Step 1: Choose a Model
 
 ```
Full technical diff · 2 changed fields

changed /included_files

BEFORE
[
  {
    "relative_path": "references/auth.md",
    "size_in_bytes": 4896
  },
  {
    "relative_path": "references/credits.md",
    "size_in_bytes": 3563
  },
  {
    "relative_path": "references/errors.md",
    "size_in_bytes": 7510
  },
  {
    "relative_path": "references/workflow.md",
    "size_in_bytes": 7025
  }
]
AFTER
[
  {
    "relative_path": "references/auth.md",
    "size_in_bytes": 4896
  },
  {
    "relative_path": "references/credits.md",
    "size_in_bytes": 4031
  },
  {
    "relative_path": "references/errors.md",
    "size_in_bytes": 8433
  },
  {
    "relative_path": "references/workflow.md",
    "size_in_bytes": 7025
  }
]

changed /skill_md_contents

BEFORE
"---\nname: reference-to-video\ndescription: Generate AI videos from multiple reference images (Enkio / enkiomv.ai). Use when the user wants to combine several images into a video, use one person image plus one clothing/scene/object image to make a video, create reference-image-to-video / multi-image-to-video / reference video, or asks how many images, how many credits, or which models are supported for reference-image-to-video. If the user only wants to animate a single image, use the enkio:image-to-video skill instead; if the user wants a fixed first-frame + end-frame transition, use the enkio:first-end-frame-video skill instead. The entire workflow is completed through the enkio MCP service.\n---\n\n# Reference-Image-to-Video\n\nUse the `enkio` MCP service to call enkiomv.ai's reference-image-to-video capability: provide several\n**reference images** plus a **prompt**, and the model synthesizes the people, clothing, scenes, objects,\nand other elements from those reference images to generate a brand-new video.\n\n## Service Binding\n\nAll capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:\n\n- Its tool namespace in Codex is **`mcp__enkio`**--Codex normalizes `-` in server names to `_`, and tool\n  names have no prefix. Every tool name mentioned below (such as `get_user_profile`) refers to the tool of\n  the same name under the `mcp__enkio` namespace.\n- **If the `mcp__enkio` namespace is not visible, the first judgment is \"not logged in\", not \"plugin\n  not installed\"**: an MCP server that has not completed OAuth will not register its entire namespace.\n  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`\n  authorization URL it prints, and give the user only that link to click -- do not lead with the\n  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has\n  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and\n  explain that after login they must open a new conversation for it to take effect.\n- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are\n  two separate services, two accounts, and two credit pools; cross-use will charge real credits on the wrong\n  account). Also do not mix in a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.\n- When you need to explain which service this skill is connected to, use the `brand` / `brand_website`\n  returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`;\n  do not answer from memory or guesswork. If `brand` is not Enkio, stop immediately and report an error.\n\nThe essential difference from `enkio:image-to-video`: single-image-to-video **animates this image**, while\nreference-image-to-video **uses these images as references to redraw a video**. The frame does not need\nto match any input image exactly.\n\nTasks are **asynchronous**: `i2v_create_task` returns `task_id` immediately, and you must poll\n`i2v_get_task` yourself.\n\n```\n0 Log in/check balance -> 1 Choose model (kind=reference) -> 2 Set parameters, image count, and quote (confirm before charging)\n-> 3 Crop each reference image locally -> 4 Upload each image to get URLs -> 5 Create task (charges credits)\n-> 6 Poll -> 7 Download, display, and deliver\n```\n\n## Hard Constraints\n\n- **Every `i2v_*` call in this skill must include `kind=\"reference\"`**. Reference-image-to-video and\n  image-to-video use completely different model lists. If `kind` is omitted, you will get image-to-video\n  models, and submission will fail with \"nonexistent reference-image-to-video model\".\n- **Creating a task charges credits; before submitting, you must explain the cost to the user and obtain\n  explicit confirmation**. All query tools are free.\n- **The number of reference images is determined by the model**: `i2v_get_options` returns\n  `image_count = { min, max }`; fewer than `min` or more than `max` will be rejected directly by the\n  server. The maximum is 3 images.\n- **`prompt` is required**, and it is the core input for this mode--reference images only provide material;\n  the prompt must clearly state how the frame should combine them. Empty or whitespace-only prompts\n  will be rejected directly.\n- **Refer to reference images in natural language in the prompt; do not use reference syntax such as\n  `@1` or `{img1}`**. The upstream service does not support it and will treat it as ordinary text.\n  See \"How to Write Prompts\" below for the correct style.\n- **Each reference image must be cropped to the target ratio before upload**. The cropping specification\n  comes from `crop` in `i2v_get_options`, and **the server does not accept image binaries; cropping is\n  done locally**.\n- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server already\n  handles them, and they do not exist in the tool inputs.\n- The allowed values for `quality` / `duration` / `mode` **must come from\n  `i2v_list_models(kind=\"reference\")`**.\n- Reference-image-to-video **does not have a fixed first/end frame mode**; passing `end_frame=true` will\n  fail directly.\n- Polling cadence: once every 10 seconds, with an upper limit of about 15 minutes. During that time,\n  briefly tell the user progress; do not wait silently for a long time.\n- When the task `task_status` is `fail`, do not retry blindly. First tell the user the\n  `task_reason`, then ask what to do. Retrying re-submits the task at the normal price--failed\n  credits are refunded automatically, and this billing rule was already disclosed when quoting\n  the cost, so no new price confirmation is needed here.\n- **Before showing the video, you must download it locally first**. A remote URL cannot be previewed\n  directly; see \"Displaying the Artifact\".\n\n## How to Write Prompts\n\nReference images correspond to \"reference image 1 / 2 / 3\" **in submission order**; the order itself is\nsemantic. In the prompt, use natural language to describe what role each image plays, how they combine,\nand what happens in the frame.\n\nRecommended practice: first confirm with the user what each image is (person? clothing? scene? object?\nstyle?), then write that information into the prompt.\n\n```\n✅ The girl in the first image wears the red dress from the second image and slowly walks on the seaside\n   wooden boardwalk in the third image, backlit by sunset, with the camera slowly panning right\n✅ Let the cat from image one sit on the sofa from image two and yawn, warm indoor lighting, static camera\n❌ @1 wears @2 and walks in @3               <- Reference syntax is not supported\n❌ Generate a nice-looking video             <- Does not clarify the relationship between the reference images\n```\n\nDo not exceed `prompt_limit_length`. The model's `prompt_hint` is upstream guidance on prompt writing;\n`prompt_guide_url` is the upstream prompt guide page. You may paraphrase them for the user, but do not\nopen the page on the user's behalf.\n\n## Displaying the Artifact\n\nThe finished video is an Enkio **temporary remote URL**. Codex **cannot embed-preview media files from\nthese domains**; if you paste the URL directly, the user cannot open it.\n\nUse a task-isolated working directory by convention (do not pollute the user's repository):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-r2v/<task_id>\"\nmkdir -p \"$WORKDIR\"\ncurl -sS -L -o \"$WORKDIR/result.mp4\" \"<video_url>\"\n```\n\nVideos cannot be embedded for display. Provide the local absolute path, and also include the original\nremote URL so the user can save it themselves. If download fails (non-200 / empty file), clearly state\n\"preview download failed\" and provide the remote URL; do not falsely claim it was displayed.\n\n## Step 0: Confirm Service Binding, Login, and Credit Balance\n\n**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and\ndo not switch to another MCP. Tell the user that `enkio` is not logged in, then run\n`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and\nhand the user only that link to click (do not lead with the unreliable\n`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that\n**after login they must open a new Codex conversation** for it to take effect (the tool table in the\ncurrent conversation will not hot-refresh).\n\nAfter the namespace is ready, call `get_user_profile()`:\n\n- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then\n  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same\n  way as above (not the `codex://` deep link), and again they need to open a new conversation. See\n  `references/auth.md`.\n- Verify that the returned `brand` must be **Enkio**; if not, it means the call is connected to the wrong\n  service. Stop immediately and tell the user.\n\nThe returned `credit` is the current credit balance. Record it so you can compare it with the estimated\ncost in Step 2.\n\n## Step 1: Choose a Model\n\n```\ni2v_list_models(kind=\"reference\")\n-> { kind, count, models: [ { model, model_name, model_desc, qualities, durations_sec,\n                              modes, ratios, default_ratio, movement_amplitudes,\n                              min_image_count, max_image_count,\n                              prompt_limit_length, prompt_hint, prompt_guide_url,\n                              combinations, ... } ] }\n```\n\n`models[].model` is the model identifier; use it in all subsequent calls. Briefly list the available\nmodels for the user, including each model's supported resolutions, durations, modes, and **how many\nreference images it needs**, and let the user choose. If the user has no preference, choose a cost-effective\ndefault combination from `combinations` and explain why.\n\n`combinations` directly gives the credit cost for each \"mode + quality + duration\" combination. Prefer it\nwhen choosing parameters.\n\n## Step 2: Set Parameters, Image Count, and Quote\n\n```\ni2v_get_options(model, kind=\"reference\", quality?, duration?, mode?, ratio?)\n-> { kind, quality, duration_sec, mode, ratio, credit_cost,\n    image_count: { min, max }, image_role, crop,\n    prompt_required, prompt_limit_length, prompt_hint, prompt_guide_url }\n```\n\nIf parameters are omitted, they fall back to model defaults. The returned object explicitly states the final\neffective values.\n\nAfter you get `image_count`, **first align with the user on which images to submit and what each one\nrepresents**, then decide how to write the prompt. If the user provided fewer images than `min`, do not\npad with filler images; directly explain how many images the model requires at minimum.\n\n**Tell the user both `credit_cost` and the `credit` balance from Step 0, and wait for\nconfirmation**. If the balance is insufficient, prompt the user to recharge first (see\nreferences/credits.md for the recharge link and steps); do not force submission.\n\n## Step 3: Crop Each Reference Image Locally\n\nThe `crop` field gives the target ratio and pixel dimensions:\n\n```\ncrop = { ratio, crop_required, target_width, target_height, strategy, hint }\n```\n\nIf `crop_required` is `false` (the ratio is `free`), skip this step and upload the original images directly.\nOtherwise, **every reference image** must first be center-cropped to the target aspect ratio, then scaled to\n`target_width x target_height`:\n\n```bash\nW=<target_width>; H=<target_height>\ni=1\nfor SRC in \"<reference image 1>\" \"<reference image 2>\" \"<reference image 3>\"; do\n  ffmpeg -y -i \"$SRC\" \\\n    -vf \"crop='min(iw,ih*$W/$H)':'min(ih,iw*$H/$W)',scale=$W:$H\" \\\n    \"$WORKDIR/ref$i.jpg\"\n  i=$((i+1))\ndone\n```\n\nIf ffmpeg is unavailable, use macOS built-in `sips` (note that `--cropToHeightWidth` takes **height\nbefore width**):\n\n```bash\ncp \"<reference image 1>\" \"$WORKDIR/ref1.jpg\"\nsips --cropToHeightWidth \"$H\" \"$W\" \"$WORKDIR/ref1.jpg\" >/dev/null\nsips --resampleHeightWidth \"$H\" \"$W\" \"$WORKDIR/ref1.jpg\" >/dev/null\n```\n\nAfter cropping, confirm that every output file exists and has the correct dimensions\n(`sips -g pixelWidth -g pixelHeight`) before moving to the next step. **Keep the order**: the order of\n`ref1/ref2/ref3` is the order of `image_urls` during submission.\n\n## Step 4: Upload Each Image to Get URLs\n\nThe upload interface accepts only one file at a time. **Call `create_upload_url` separately for each\nreference image**:\n\n```\ncreate_upload_url() -> { upload_url, headers }\n```\n\n```bash\ncurl -sS -X POST \"<upload_url>\" -F \"file=@$WORKDIR/ref1.jpg\" -H \"X-Client-Sn: <value from headers>\"\n# -> {\"c\":200,\"m\":\"Success\",\"d\":\"https://.../ref1.jpg\"}\n```\n\nThe `d` in the response is the image URL. `c != 200` means failure; report `m` to the user.\n**Collect these URLs in reference-image order**; if the order is wrong, the visual composition relationship\nwill be wrong. Uploaded files are **temporary storage and will be cleaned periodically**; submit the task\nas soon as you get the URLs.\n\n## Step 5: Create the Task (Charges Credits)\n\n```\ni2v_create_task(model, kind=\"reference\", image_urls=[<URL1>, <URL2>, ...], prompt,\n                ratio?, quality?, duration?, mode?, movement_amplitude?)\n-> { task_id, task_status, kind, image_count, credit_cost, quality, duration_sec, mode, ratio }\n```\n\n- `kind` must be `\"reference\"`.\n- Pass `image_urls` in **reference image 1/2/3 order**, with the count inside the `image_count` range from\n  Step 2.\n- `prompt` is **required**; see \"How to Write Prompts\".\n- `ratio` must **stay consistent** with the ratio used for cropping in Step 3.\n- Parameters must match the set confirmed during the quote in Step 2, otherwise the actual charge may not\n  match the quote.\n- The returned `end_frame` is always `false`--reference-image-to-video has no first/end frame concept, so\n  ignore this field.\n\n## Step 6: Poll\n\n```\ni2v_get_task(task_id) -> { task_status, task_reason, video_url, finished }\n```\n\nThe query interface is shared with image-to-video; there is no need to pass `kind`.\n\n- `task_status == \"success\"`: `video_url` is the finished video; proceed to Step 7.\n- `task_status == \"fail\"`: relay `task_reason` to the user, and ask whether to adjust\n  parameters and retry or give up. Retrying re-bills at the normal price (failed credits are\n  refunded automatically); this was already disclosed up front, so you do not need to reconfirm\n  the price.\n- Other values: the task is queued or generating. Wait 10 seconds, query again, and briefly tell the user\n  progress.\n\n## Step 7: Download and Deliver\n\nDownload `video_url` to `$WORKDIR/result.mp4` according to \"Displaying the Artifact\", provide the local\npath + original URL, and remind the user: the remote link points to temporary storage and will be cleaned;\nthe local file is also under the system temporary directory and may be reclaimed by the system. The user\nshould save it to their own directory as soon as possible.\n\nIt is normal for the finished video to differ significantly from the reference images (this mode is\n\"reference\", not \"reproduction\"). If the user is dissatisfied, first suggest **rewriting the prompt to make\nthe reference relationship more specific**, rather than immediately switching models and retrying.\n\n## Error Handling\n\nFor login, connection, and service-binding issues, see `references/auth.md` (**when not logged in, the\nentire MCP namespace will not appear**; do not misdiagnose it as the plugin not installed, and do not switch\nto another brand's MCP). For common error codes and remedies, see `references/errors.md`; for credits and\nbilling rules, see `references/credits.md`; for each tool's returned field structures, see\n`references/workflow.md`.\n"
AFTER
"---\nname: reference-to-video\ndescription: Generate AI videos from multiple reference images (Enkio / enkiomv.ai). Use when the user wants to combine several images into a video, use one person image plus one clothing/scene/object image to make a video, create reference-image-to-video / multi-image-to-video / reference video, or asks how many images, how many credits, or which models are supported for reference-image-to-video. If the user only wants to animate a single image, use the enkio:image-to-video skill instead; if the user wants a fixed first-frame + end-frame transition, use the enkio:first-end-frame-video skill instead. The entire workflow is completed through the enkio MCP service.\n---\n\n# Reference-Image-to-Video\n\nUse the `enkio` MCP service to call enkiomv.ai's reference-image-to-video capability: provide several\n**reference images** plus a **prompt**, and the model synthesizes the people, clothing, scenes, objects,\nand other elements from those reference images to generate a brand-new video.\n\n## Service Binding\n\nAll capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:\n\n- Its tool namespace in Codex is **`mcp__enkio`**--Codex normalizes `-` in server names to `_`, and tool\n  names have no prefix. Every tool name mentioned below (such as `get_user_profile`) refers to the tool of\n  the same name under the `mcp__enkio` namespace.\n- **If the `mcp__enkio` namespace is not visible, the first judgment is \"not logged in\", not \"plugin\n  not installed\"**: an MCP server that has not completed OAuth will not register its entire namespace.\n  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`\n  authorization URL it prints, and give the user only that link to click -- do not lead with the\n  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has\n  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and\n  explain that after login they must open a new conversation for it to take effect.\n- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are\n  two separate services, two accounts, and two credit pools; cross-use will charge real credits on the wrong\n  account). Also do not mix in a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.\n- When you need to explain which service this skill is connected to, use the `brand` / `brand_website`\n  returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`;\n  do not answer from memory or guesswork. If `brand` is not Enkio, stop immediately and report an error.\n\nThe essential difference from `enkio:image-to-video`: single-image-to-video **animates this image**, while\nreference-image-to-video **uses these images as references to redraw a video**. The frame does not need\nto match any input image exactly.\n\nTasks are **asynchronous**: `i2v_create_task` returns `task_id` immediately, and you must poll\n`i2v_get_task` yourself.\n\n```\n0 Log in/check balance -> 1 Choose model (kind=reference) -> 2 Set parameters, image count, and quote (confirm before charging)\n-> 3 Crop each reference image locally -> 4 Upload each image to get URLs -> 5 Create task (charges credits)\n-> 6 Poll -> 7 Download, display, and deliver\n```\n\n## Hard Constraints\n\n- **Every `i2v_*` call in this skill must include `kind=\"reference\"`**. Reference-image-to-video and\n  image-to-video use completely different model lists. If `kind` is omitted, you will get image-to-video\n  models, and submission will fail with \"nonexistent reference-image-to-video model\".\n- **Creating a task charges credits; before submitting, you must explain the cost to the user and obtain\n  explicit confirmation**. All query tools are free.\n- **The number of reference images is determined by the model**: `i2v_get_options` returns\n  `image_count = { min, max }`; fewer than `min` or more than `max` will be rejected directly by the\n  server. The maximum is 3 images.\n- **`prompt` is required**, and it is the core input for this mode--reference images only provide material;\n  the prompt must clearly state how the frame should combine them. Empty or whitespace-only prompts\n  will be rejected directly.\n- **Refer to reference images in natural language in the prompt; do not use reference syntax such as\n  `@1` or `{img1}`**. The upstream service does not support it and will treat it as ordinary text.\n  See \"How to Write Prompts\" below for the correct style.\n- **Each reference image must be cropped to the target ratio before upload**. The cropping specification\n  comes from `crop` in `i2v_get_options`, and **the server does not accept image binaries; cropping is\n  done locally**.\n- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server already\n  handles them, and they do not exist in the tool inputs.\n- The allowed values for `quality` / `duration` / `mode` **must come from\n  `i2v_list_models(kind=\"reference\")`**.\n- Reference-image-to-video **does not have a fixed first/end frame mode**; passing `end_frame=true` will\n  fail directly.\n- Polling cadence: once every 10 seconds, with an upper limit of about 15 minutes. During that time,\n  briefly tell the user progress; do not wait silently for a long time.\n- When the task `task_status` is `fail`, do not retry blindly. First tell the user the\n  `task_reason`, then ask what to do. Retrying re-submits the task at the normal price--failed\n  credits are refunded automatically, and this billing rule was already disclosed when quoting\n  the cost, so no new price confirmation is needed here.\n- **Before showing the video, you must download it locally first**. A remote URL cannot be previewed\n  directly; see \"Displaying the Artifact\".\n\n## How to Write Prompts\n\nReference images correspond to \"reference image 1 / 2 / 3\" **in submission order**; the order itself is\nsemantic. In the prompt, use natural language to describe what role each image plays, how they combine,\nand what happens in the frame.\n\nRecommended practice: first confirm with the user what each image is (person? clothing? scene? object?\nstyle?), then write that information into the prompt.\n\n```\n✅ The girl in the first image wears the red dress from the second image and slowly walks on the seaside\n   wooden boardwalk in the third image, backlit by sunset, with the camera slowly panning right\n✅ Let the cat from image one sit on the sofa from image two and yawn, warm indoor lighting, static camera\n❌ @1 wears @2 and walks in @3               <- Reference syntax is not supported\n❌ Generate a nice-looking video             <- Does not clarify the relationship between the reference images\n```\n\nDo not exceed `prompt_limit_length`. The model's `prompt_hint` is upstream guidance on prompt writing;\n`prompt_guide_url` is the upstream prompt guide page. You may paraphrase them for the user, but do not\nopen the page on the user's behalf.\n\n## Displaying the Artifact\n\nThe finished video is an Enkio **temporary remote URL**. Codex **cannot embed-preview media files from\nthese domains**; if you paste the URL directly, the user cannot open it.\n\nUse a task-isolated working directory by convention (do not pollute the user's repository):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-r2v/<task_id>\"\nmkdir -p \"$WORKDIR\"\ncurl -sS -L -o \"$WORKDIR/result.mp4\" \"<video_url>\"\n```\n\nVideos cannot be embedded for display. Provide the local absolute path, and also include the original\nremote URL so the user can save it themselves. If download fails (non-200 / empty file), clearly state\n\"preview download failed\" and provide the remote URL; do not falsely claim it was displayed.\n\n## Step 0: Confirm Service Binding, Login, and Credit Balance\n\n**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and\ndo not switch to another MCP. Tell the user that `enkio` is not logged in, then run\n`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and\nhand the user only that link to click (do not lead with the unreliable\n`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that\n**after login they must open a new Codex conversation** for it to take effect (the tool table in the\ncurrent conversation will not hot-refresh).\n\nAfter the namespace is ready, call `get_user_profile()`:\n\n- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then\n  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same\n  way as above (not the `codex://` deep link), and again they need to open a new conversation. See\n  `references/auth.md`.\n- Verify that the returned `brand` must be **Enkio**; if not, it means the call is connected to the wrong\n  service. Stop immediately and tell the user.\n\nThe returned `credit` is the current credit balance. Record it so you can compare it with the estimated\ncost in Step 2.\n\n**Membership check (required).** Creating tasks with `i2v_create_task` requires an active membership. If\n`get_user_profile()` returns an `is_member` value other than `true`, stop here: call `get_pricing_url`\nand give the user the returned `pricing_url` to open in a browser, signed in with the same Wondershare\naccount used to authorize this MCP, to purchase a membership. Do not continue with model selection,\nuploads, quoting, or task creation; after the user says the purchase is complete, call\n`get_user_profile()` again and continue only when `is_member` is `true`.\n\n## Step 1: Choose a Model\n\n```\ni2v_list_models(kind=\"reference\")\n-> { kind, count, models: [ { model, model_name, model_desc, qualities, durations_sec,\n                              modes, ratios, default_ratio, movement_amplitudes,\n                              min_image_count, max_image_count,\n                              prompt_limit_length, prompt_hint, prompt_guide_url,\n                              combinations, ... } ] }\n```\n\n`models[].model` is the model identifier; use it in all subsequent calls. Briefly list the available\nmodels for the user, including each model's supported resolutions, durations, modes, and **how many\nreference images it needs**, and let the user choose. If the user has no preference, choose a cost-effective\ndefault combination from `combinations` and explain why.\n\n`combinations` directly gives the credit cost for each \"mode + quality + duration\" combination. Prefer it\nwhen choosing parameters.\n\n## Step 2: Set Parameters, Image Count, and Quote\n\n```\ni2v_get_options(model, kind=\"reference\", quality?, duration?, mode?, ratio?)\n-> { kind, quality, duration_sec, mode, ratio, credit_cost,\n    image_count: { min, max }, image_role, crop,\n    prompt_required, prompt_limit_length, prompt_hint, prompt_guide_url }\n```\n\nIf parameters are omitted, they fall back to model defaults. The returned object explicitly states the final\neffective values.\n\nAfter you get `image_count`, **first align with the user on which images to submit and what each one\nrepresents**, then decide how to write the prompt. If the user provided fewer images than `min`, do not\npad with filler images; directly explain how many images the model requires at minimum.\n\n**Tell the user both `credit_cost` and the `credit` balance from Step 0, and wait for\nconfirmation**. If the balance is insufficient, prompt the user to recharge first (see\nreferences/credits.md for the recharge link and steps); do not force submission.\n\n## Step 3: Crop Each Reference Image Locally\n\nThe `crop` field gives the target ratio and pixel dimensions:\n\n```\ncrop = { ratio, crop_required, target_width, target_height, strategy, hint }\n```\n\nIf `crop_required` is `false` (the ratio is `free`), skip this step and upload the original images directly.\nOtherwise, **every reference image** must first be center-cropped to the target aspect ratio, then scaled to\n`target_width x target_height`:\n\n```bash\nW=<target_width>; H=<target_height>\ni=1\nfor SRC in \"<reference image 1>\" \"<reference image 2>\" \"<reference image 3>\"; do\n  ffmpeg -y -i \"$SRC\" \\\n    -vf \"crop='min(iw,ih*$W/$H)':'min(ih,iw*$H/$W)',scale=$W:$H\" \\\n    \"$WORKDIR/ref$i.jpg\"\n  i=$((i+1))\ndone\n```\n\nIf ffmpeg is unavailable, use macOS built-in `sips` (note that `--cropToHeightWidth` takes **height\nbefore width**):\n\n```bash\ncp \"<reference image 1>\" \"$WORKDIR/ref1.jpg\"\nsips --cropToHeightWidth \"$H\" \"$W\" \"$WORKDIR/ref1.jpg\" >/dev/null\nsips --resampleHeightWidth \"$H\" \"$W\" \"$WORKDIR/ref1.jpg\" >/dev/null\n```\n\nAfter cropping, confirm that every output file exists and has the correct dimensions\n(`sips -g pixelWidth -g pixelHeight`) before moving to the next step. **Keep the order**: the order of\n`ref1/ref2/ref3` is the order of `image_urls` during submission.\n\n## Step 4: Upload Each Image to Get URLs\n\nThe upload interface accepts only one file at a time. **Call `create_upload_url` separately for each\nreference image**:\n\n```\ncreate_upload_url() -> { upload_url, headers }\n```\n\n```bash\ncurl -sS -X POST \"<upload_url>\" -F \"file=@$WORKDIR/ref1.jpg\" -H \"X-Client-Sn: <value from headers>\"\n# -> {\"c\":200,\"m\":\"Success\",\"d\":\"https://.../ref1.jpg\"}\n```\n\nThe `d` in the response is the image URL. `c != 200` means failure; report `m` to the user.\n**Collect these URLs in reference-image order**; if the order is wrong, the visual composition relationship\nwill be wrong. Uploaded files are **temporary storage and will be cleaned periodically**; submit the task\nas soon as you get the URLs.\n\n## Step 5: Create the Task (Charges Credits)\n\n```\ni2v_create_task(model, kind=\"reference\", image_urls=[<URL1>, <URL2>, ...], prompt,\n                ratio?, quality?, duration?, mode?, movement_amplitude?)\n-> { task_id, task_status, kind, image_count, credit_cost, quality, duration_sec, mode, ratio }\n```\n\n- `kind` must be `\"reference\"`.\n- Pass `image_urls` in **reference image 1/2/3 order**, with the count inside the `image_count` range from\n  Step 2.\n- `prompt` is **required**; see \"How to Write Prompts\".\n- `ratio` must **stay consistent** with the ratio used for cropping in Step 3.\n- Parameters must match the set confirmed during the quote in Step 2, otherwise the actual charge may not\n  match the quote.\n- The returned `end_frame` is always `false`--reference-image-to-video has no first/end frame concept, so\n  ignore this field.\n\n## Step 6: Poll\n\n```\ni2v_get_task(task_id) -> { task_status, task_reason, video_url, finished }\n```\n\nThe query interface is shared with image-to-video; there is no need to pass `kind`.\n\n- `task_status == \"success\"`: `video_url` is the finished video; proceed to Step 7.\n- `task_status == \"fail\"`: relay `task_reason` to the user, and ask whether to adjust\n  parameters and retry or give up. Retrying re-bills at the normal price (failed credits are\n  refunded automatically); this was already disclosed up front, so you do not need to reconfirm\n  the price.\n- Other values: the task is queued or generating. Wait 10 seconds, query again, and briefly tell the user\n  progress.\n\n## Step 7: Download and Deliver\n\nDownload `video_url` to `$WORKDIR/result.mp4` according to \"Displaying the Artifact\", provide the local\npath + original URL, and remind the user: the remote link points to temporary storage and will be cleaned;\nthe local file is also under the system temporary directory and may be reclaimed by the system. The user\nshould save it to their own directory as soon as possible.\n\nIt is normal for the finished video to differ significantly from the reference images (this mode is\n\"reference\", not \"reproduction\"). If the user is dissatisfied, first suggest **rewriting the prompt to make\nthe reference relationship more specific**, rather than immediately switching models and retrying.\n\n## Error Handling\n\nFor login, connection, and service-binding issues, see `references/auth.md` (**when not logged in, the\nentire MCP namespace will not appear**; do not misdiagnose it as the plugin not installed, and do not switch\nto another brand's MCP). For common error codes and remedies, see `references/errors.md`; for credits and\nbilling rules, see `references/credits.md`; for each tool's returned field structures, see\n`references/workflow.md`.\n"
Full snapshot data
{
  "description": "Generate AI videos from multiple reference images (Enkio / enkiomv.ai). Use when the user wants to combine several images into a video, use one person image plus one clothing/scene/object image to make a video, create reference-image-to-video / multi-image-to-video / reference video, or asks how many images, how many credits, or which models are supported for reference-image-to-video. If the user only wants to animate a single image, use the enkio:image-to-video skill instead; if the user wants a fixed first-frame + end-frame transition, use the enkio:first-end-frame-video skill instead. The entire workflow is completed through the enkio MCP service.",
  "included_files": [
    {
      "relative_path": "references/auth.md",
      "size_in_bytes": 4896
    },
    {
      "relative_path": "references/credits.md",
      "size_in_bytes": 4031
    },
    {
      "relative_path": "references/errors.md",
      "size_in_bytes": 8433
    },
    {
      "relative_path": "references/workflow.md",
      "size_in_bytes": 7025
    }
  ],
  "name": "reference-to-video",
  "skill_md_contents": "---\nname: reference-to-video\ndescription: Generate AI videos from multiple reference images (Enkio / enkiomv.ai). Use when the user wants to combine several images into a video, use one person image plus one clothing/scene/object image to make a video, create reference-image-to-video / multi-image-to-video / reference video, or asks how many images, how many credits, or which models are supported for reference-image-to-video. If the user only wants to animate a single image, use the enkio:image-to-video skill instead; if the user wants a fixed first-frame + end-frame transition, use the enkio:first-end-frame-video skill instead. The entire workflow is completed through the enkio MCP service.\n---\n\n# Reference-Image-to-Video\n\nUse the `enkio` MCP service to call enkiomv.ai's reference-image-to-video capability: provide several\n**reference images** plus a **prompt**, and the model synthesizes the people, clothing, scenes, objects,\nand other elements from those reference images to generate a brand-new video.\n\n## Service Binding\n\nAll capabilities in this skill come from the single `enkio` MCP server, and **it must not be replaced**:\n\n- Its tool namespace in Codex is **`mcp__enkio`**--Codex normalizes `-` in server names to `_`, and tool\n  names have no prefix. Every tool name mentioned below (such as `get_user_profile`) refers to the tool of\n  the same name under the `mcp__enkio` namespace.\n- **If the `mcp__enkio` namespace is not visible, the first judgment is \"not logged in\", not \"plugin\n  not installed\"**: an MCP server that has not completed OAuth will not register its entire namespace.\n  In this case, run `codex mcp login enkio` yourself (not the user), extract the plain `https://`\n  authorization URL it prints, and give the user only that link to click -- do not lead with the\n  `codex://mcp/login?server=enkio` deep link, since it silently does nothing unless the client has\n  registered the `codex://` protocol handler. See `references/auth.md` for the full procedure, and\n  explain that after login they must open a new conversation for it to take effect.\n- **Never substitute another brand's MCP under any circumstances** (`mcp__selfyz_ai` and `mcp__enkio` are\n  two separate services, two accounts, and two credit pools; cross-use will charge real credits on the wrong\n  account). Also do not mix in a `task_id` / `job_id`, credit balance, or artifact URL obtained elsewhere.\n- When you need to explain which service this skill is connected to, use the `brand` / `brand_website`\n  returned by `get_user_profile` and the value of `mcpServers.enkio.url` in this plugin's `.mcp.json`;\n  do not answer from memory or guesswork. If `brand` is not Enkio, stop immediately and report an error.\n\nThe essential difference from `enkio:image-to-video`: single-image-to-video **animates this image**, while\nreference-image-to-video **uses these images as references to redraw a video**. The frame does not need\nto match any input image exactly.\n\nTasks are **asynchronous**: `i2v_create_task` returns `task_id` immediately, and you must poll\n`i2v_get_task` yourself.\n\n```\n0 Log in/check balance -> 1 Choose model (kind=reference) -> 2 Set parameters, image count, and quote (confirm before charging)\n-> 3 Crop each reference image locally -> 4 Upload each image to get URLs -> 5 Create task (charges credits)\n-> 6 Poll -> 7 Download, display, and deliver\n```\n\n## Hard Constraints\n\n- **Every `i2v_*` call in this skill must include `kind=\"reference\"`**. Reference-image-to-video and\n  image-to-video use completely different model lists. If `kind` is omitted, you will get image-to-video\n  models, and submission will fail with \"nonexistent reference-image-to-video model\".\n- **Creating a task charges credits; before submitting, you must explain the cost to the user and obtain\n  explicit confirmation**. All query tools are free.\n- **The number of reference images is determined by the model**: `i2v_get_options` returns\n  `image_count = { min, max }`; fewer than `min` or more than `max` will be rejected directly by the\n  server. The maximum is 3 images.\n- **`prompt` is required**, and it is the core input for this mode--reference images only provide material;\n  the prompt must clearly state how the frame should combine them. Empty or whitespace-only prompts\n  will be rejected directly.\n- **Refer to reference images in natural language in the prompt; do not use reference syntax such as\n  `@1` or `{img1}`**. The upstream service does not support it and will treat it as ordinary text.\n  See \"How to Write Prompts\" below for the correct style.\n- **Each reference image must be cropped to the target ratio before upload**. The cropping specification\n  comes from `crop` in `i2v_get_options`, and **the server does not accept image binaries; cropping is\n  done locally**.\n- **Do not construct or guess parameters such as `user_id`, `example`, or signatures**. The server already\n  handles them, and they do not exist in the tool inputs.\n- The allowed values for `quality` / `duration` / `mode` **must come from\n  `i2v_list_models(kind=\"reference\")`**.\n- Reference-image-to-video **does not have a fixed first/end frame mode**; passing `end_frame=true` will\n  fail directly.\n- Polling cadence: once every 10 seconds, with an upper limit of about 15 minutes. During that time,\n  briefly tell the user progress; do not wait silently for a long time.\n- When the task `task_status` is `fail`, do not retry blindly. First tell the user the\n  `task_reason`, then ask what to do. Retrying re-submits the task at the normal price--failed\n  credits are refunded automatically, and this billing rule was already disclosed when quoting\n  the cost, so no new price confirmation is needed here.\n- **Before showing the video, you must download it locally first**. A remote URL cannot be previewed\n  directly; see \"Displaying the Artifact\".\n\n## How to Write Prompts\n\nReference images correspond to \"reference image 1 / 2 / 3\" **in submission order**; the order itself is\nsemantic. In the prompt, use natural language to describe what role each image plays, how they combine,\nand what happens in the frame.\n\nRecommended practice: first confirm with the user what each image is (person? clothing? scene? object?\nstyle?), then write that information into the prompt.\n\n```\n✅ The girl in the first image wears the red dress from the second image and slowly walks on the seaside\n   wooden boardwalk in the third image, backlit by sunset, with the camera slowly panning right\n✅ Let the cat from image one sit on the sofa from image two and yawn, warm indoor lighting, static camera\n❌ @1 wears @2 and walks in @3               <- Reference syntax is not supported\n❌ Generate a nice-looking video             <- Does not clarify the relationship between the reference images\n```\n\nDo not exceed `prompt_limit_length`. The model's `prompt_hint` is upstream guidance on prompt writing;\n`prompt_guide_url` is the upstream prompt guide page. You may paraphrase them for the user, but do not\nopen the page on the user's behalf.\n\n## Displaying the Artifact\n\nThe finished video is an Enkio **temporary remote URL**. Codex **cannot embed-preview media files from\nthese domains**; if you paste the URL directly, the user cannot open it.\n\nUse a task-isolated working directory by convention (do not pollute the user's repository):\n\n```bash\nWORKDIR=\"${TMPDIR:-/tmp}/enkio-r2v/<task_id>\"\nmkdir -p \"$WORKDIR\"\ncurl -sS -L -o \"$WORKDIR/result.mp4\" \"<video_url>\"\n```\n\nVideos cannot be embedded for display. Provide the local absolute path, and also include the original\nremote URL so the user can save it themselves. If download fails (non-200 / empty file), clearly state\n\"preview download failed\" and provide the remote URL; do not falsely claim it was displayed.\n\n## Step 0: Confirm Service Binding, Login, and Credit Balance\n\n**First confirm that the `mcp__enkio` namespace exists.** If it does not exist, do not continue and\ndo not switch to another MCP. Tell the user that `enkio` is not logged in, then run\n`codex mcp login enkio` yourself, extract the plain `https://` authorization URL from its output, and\nhand the user only that link to click (do not lead with the unreliable\n`codex://mcp/login?server=enkio` deep link). See `references/auth.md` for details, and explain that\n**after login they must open a new Codex conversation** for it to take effect (the tool table in the\ncurrent conversation will not hot-refresh).\n\nAfter the namespace is ready, call `get_user_profile()`:\n\n- **Returns 401 / not logged in**: the token is invalid. Run `codex mcp logout enkio` then\n  `codex mcp login enkio` yourself, relay the newly printed `https://` login URL to the user the same\n  way as above (not the `codex://` deep link), and again they need to open a new conversation. See\n  `references/auth.md`.\n- Verify that the returned `brand` must be **Enkio**; if not, it means the call is connected to the wrong\n  service. Stop immediately and tell the user.\n\nThe returned `credit` is the current credit balance. Record it so you can compare it with the estimated\ncost in Step 2.\n\n**Membership check (required).** Creating tasks with `i2v_create_task` requires an active membership. If\n`get_user_profile()` returns an `is_member` value other than `true`, stop here: call `get_pricing_url`\nand give the user the returned `pricing_url` to open in a browser, signed in with the same Wondershare\naccount used to authorize this MCP, to purchase a membership. Do not continue with model selection,\nuploads, quoting, or task creation; after the user says the purchase is complete, call\n`get_user_profile()` again and continue only when `is_member` is `true`.\n\n## Step 1: Choose a Model\n\n```\ni2v_list_models(kind=\"reference\")\n-> { kind, count, models: [ { model, model_name, model_desc, qualities, durations_sec,\n                              modes, ratios, default_ratio, movement_amplitudes,\n                              min_image_count, max_image_count,\n                              prompt_limit_length, prompt_hint, prompt_guide_url,\n                              combinations, ... } ] }\n```\n\n`models[].model` is the model identifier; use it in all subsequent calls. Briefly list the available\nmodels for the user, including each model's supported resolutions, durations, modes, and **how many\nreference images it needs**, and let the user choose. If the user has no preference, choose a cost-effective\ndefault combination from `combinations` and explain why.\n\n`combinations` directly gives the credit cost for each \"mode + quality + duration\" combination. Prefer it\nwhen choosing parameters.\n\n## Step 2: Set Parameters, Image Count, and Quote\n\n```\ni2v_get_options(model, kind=\"reference\", quality?, duration?, mode?, ratio?)\n-> { kind, quality, duration_sec, mode, ratio, credit_cost,\n    image_count: { min, max }, image_role, crop,\n    prompt_required, prompt_limit_length, prompt_hint, prompt_guide_url }\n```\n\nIf parameters are omitted, they fall back to model defaults. The returned object explicitly states the final\neffective values.\n\nAfter you get `image_count`, **first align with the user on which images to submit and what each one\nrepresents**, then decide how to write the prompt. If the user provided fewer images than `min`, do not\npad with filler images; directly explain how many images the model requires at minimum.\n\n**Tell the user both `credit_cost` and the `credit` balance from Step 0, and wait for\nconfirmation**. If the balance is insufficient, prompt the user to recharge first (see\nreferences/credits.md for the recharge link and steps); do not force submission.\n\n## Step 3: Crop Each Reference Image Locally\n\nThe `crop` field gives the target ratio and pixel dimensions:\n\n```\ncrop = { ratio, crop_required, target_width, target_height, strategy, hint }\n```\n\nIf `crop_required` is `false` (the ratio is `free`), skip this step and upload the original images directly.\nOtherwise, **every reference image** must first be center-cropped to the target aspect ratio, then scaled to\n`target_width x target_height`:\n\n```bash\nW=<target_width>; H=<target_height>\ni=1\nfor SRC in \"<reference image 1>\" \"<reference image 2>\" \"<reference image 3>\"; do\n  ffmpeg -y -i \"$SRC\" \\\n    -vf \"crop='min(iw,ih*$W/$H)':'min(ih,iw*$H/$W)',scale=$W:$H\" \\\n    \"$WORKDIR/ref$i.jpg\"\n  i=$((i+1))\ndone\n```\n\nIf ffmpeg is unavailable, use macOS built-in `sips` (note that `--cropToHeightWidth` takes **height\nbefore width**):\n\n```bash\ncp \"<reference image 1>\" \"$WORKDIR/ref1.jpg\"\nsips --cropToHeightWidth \"$H\" \"$W\" \"$WORKDIR/ref1.jpg\" >/dev/null\nsips --resampleHeightWidth \"$H\" \"$W\" \"$WORKDIR/ref1.jpg\" >/dev/null\n```\n\nAfter cropping, confirm that every output file exists and has the correct dimensions\n(`sips -g pixelWidth -g pixelHeight`) before moving to the next step. **Keep the order**: the order of\n`ref1/ref2/ref3` is the order of `image_urls` during submission.\n\n## Step 4: Upload Each Image to Get URLs\n\nThe upload interface accepts only one file at a time. **Call `create_upload_url` separately for each\nreference image**:\n\n```\ncreate_upload_url() -> { upload_url, headers }\n```\n\n```bash\ncurl -sS -X POST \"<upload_url>\" -F \"file=@$WORKDIR/ref1.jpg\" -H \"X-Client-Sn: <value from headers>\"\n# -> {\"c\":200,\"m\":\"Success\",\"d\":\"https://.../ref1.jpg\"}\n```\n\nThe `d` in the response is the image URL. `c != 200` means failure; report `m` to the user.\n**Collect these URLs in reference-image order**; if the order is wrong, the visual composition relationship\nwill be wrong. Uploaded files are **temporary storage and will be cleaned periodically**; submit the task\nas soon as you get the URLs.\n\n## Step 5: Create the Task (Charges Credits)\n\n```\ni2v_create_task(model, kind=\"reference\", image_urls=[<URL1>, <URL2>, ...], prompt,\n                ratio?, quality?, duration?, mode?, movement_amplitude?)\n-> { task_id, task_status, kind, image_count, credit_cost, quality, duration_sec, mode, ratio }\n```\n\n- `kind` must be `\"reference\"`.\n- Pass `image_urls` in **reference image 1/2/3 order**, with the count inside the `image_count` range from\n  Step 2.\n- `prompt` is **required**; see \"How to Write Prompts\".\n- `ratio` must **stay consistent** with the ratio used for cropping in Step 3.\n- Parameters must match the set confirmed during the quote in Step 2, otherwise the actual charge may not\n  match the quote.\n- The returned `end_frame` is always `false`--reference-image-to-video has no first/end frame concept, so\n  ignore this field.\n\n## Step 6: Poll\n\n```\ni2v_get_task(task_id) -> { task_status, task_reason, video_url, finished }\n```\n\nThe query interface is shared with image-to-video; there is no need to pass `kind`.\n\n- `task_status == \"success\"`: `video_url` is the finished video; proceed to Step 7.\n- `task_status == \"fail\"`: relay `task_reason` to the user, and ask whether to adjust\n  parameters and retry or give up. Retrying re-bills at the normal price (failed credits are\n  refunded automatically); this was already disclosed up front, so you do not need to reconfirm\n  the price.\n- Other values: the task is queued or generating. Wait 10 seconds, query again, and briefly tell the user\n  progress.\n\n## Step 7: Download and Deliver\n\nDownload `video_url` to `$WORKDIR/result.mp4` according to \"Displaying the Artifact\", provide the local\npath + original URL, and remind the user: the remote link points to temporary storage and will be cleaned;\nthe local file is also under the system temporary directory and may be reclaimed by the system. The user\nshould save it to their own directory as soon as possible.\n\nIt is normal for the finished video to differ significantly from the reference images (this mode is\n\"reference\", not \"reproduction\"). If the user is dissatisfied, first suggest **rewriting the prompt to make\nthe reference relationship more specific**, rather than immediately switching models and retrying.\n\n## Error Handling\n\nFor login, connection, and service-binding issues, see `references/auth.md` (**when not logged in, the\nentire MCP namespace will not appear**; do not misdiagnose it as the plugin not installed, and do not switch\nto another brand's MCP). For common error codes and remedies, see `references/errors.md`; for credits and\nbilling rules, see `references/credits.md`; for each tool's returned field structures, see\n`references/workflow.md`.\n"
}

SHA-256 of public snapshot: 8bf9f9dec550d661ec6dc449dd897e300f67c5cbed873516a4247bcab4cebfe8