一键导入
ars-build
Build episode source from the approved planning artifacts under .ars/episodes/<epId>/.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Build episode source from the approved planning artifacts under .ars/episodes/<epId>/.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Run a single-episode coherence checklist after Studio review edits and before prepare/publish; diagnose or patch thesis drift, step seams, stale arguments, visual rhythm, and publish readiness.
Apply Studio intents back into the episode source and validate the result.
Generate 3 YouTube metadata candidates (title/description/tags) grounded in episode context, let the user pick one, then mark the artifact ready.
Usage guide for generating MiniMax TTS audio and subtitles for an episode.
Validate repo bootstrap readiness, ARS config, providers, and environment readiness with npx ars doctor.
Create a new episode scaffold for a series with npx ars episode create.
| name | ars:build |
| description | Build episode source from the approved planning artifacts under .ars/episodes/<epId>/. |
| argument-hint | <epId> |
| model | claude-sonnet-4-6 |
| effort | high |
Use .ars/episodes/<epId>/plan.md as the implementation contract.
References:
references/card-primitives.md for BaseSlide, WindowSlide, and ScrollSlide props API.references/card-selection.md for cross-card selection heuristics (built-in cards, SVG vs markdown, Mermaid vs generated SVG, common misuses).Behavior:
SERIES_GUIDE.md at the repo root before doing anything else. It is the canonical voice / visual / pacing brief for this series and overrides any default in this SKILL when it specifies something concrete.STYLING.md (or other *.md style guide like VOICE.md / persona.md) exists at repo root, also read it. New series consolidate everything into SERIES_GUIDE.md, so these companion files are read-but-not-required./ars:build should operate on <epId> within that active series..ars/episodes/<epId>/plan.md before editing.plan.md as a narrative + visual intent contract, not as a pre-filled ep.ts dump. If the plan gives a primary card direction plus approved alternates, prefer the primary choice and only use an alternate when implementation constraints justify it.## References and ## Reminders from the plan during implementation so sourced claims, unresolved assets, and cautions do not get lost.todo.json./ars:plan instead of guessing.When this SKILL gives a number (step duration, beat budget, card density) and SERIES_GUIDE.md (or its companion files) gives a different number, the series guide always wins. The defaults in this file exist only for series whose guide is silent on that dimension. Do not "average" the two — pick the series rule.
Apply the same precedence to qualitative rules: banned phrases, card preferences, opening-line rituals, signature sign-offs, contrast examples. If the series guide has them, follow them verbatim; this SKILL provides general scaffolding only.
Update workstate at each phase boundary so the Studio Build view can reflect progress. The stage value must be exactly <phase>:<epId> — the Studio GET /__ars/build-status endpoint parses it directly.
npx ars workstate set --stage "building:<epId>" # when Phase 1 starts
npx ars workstate set --stage "validating:<epId>" # right before Completion validate
npx ars workstate set --stage "ready-for-review:<epId>" # after validate passes
# On any irrecoverable failure:
npx ars workstate set --stage "failed:<epId>"
workstate set infers the episode context from <phase>:<epId>. When switching from one episode to another outside the normal build transition, make the handoff explicit with npx ars workstate switch <epId> --stage <stage> before editing, validating, generating audio, reviewing, preparing, or publishing the new episode.
Before writing ep.ts, read the ## New card table in .ars/episodes/<epId>/plan.md.
If the table contains real entries, build each card inline using the rules below — do NOT ask the user to run /ars:new-card separately.
Before choosing built-in cards for non-new-card steps, also read references/card-selection.md for cross-card heuristics. If SERIES_GUIDE.md defines its own card preferences (e.g. markdown > image > mermaid), the series ordering wins over the defaults in that reference. Only use custom card names when ars card list shows they exist for the active series.
If the approved plan names markdown but the row's Visual / Goal is really a before-after, prompt-to-result, input-output, relationship mock, or abstract concept diagram, you may refine the implementation to image with a generated SVG asset. This is a card-selection refinement, not a narrative change. Keep the beat's meaning identical and update the plan's Card / Notes if the change is material.
For each new-card row:
src/episodes/<series>/series-config.ts for theme seed / channel name.ars card list first. If an existing card already covers the need, skip creation and update the plan reference. If creating, verify the differentiation check from references/custom-card-guide.md.BaseSlide — fullscreen content, no chrome (default for most cards)WindowSlide — content inside a mac/terminal/browser window frameScrollSlide — WindowSlide with auto-scrolling (logs, code)src/episodes/<series>/cards/<card-name>/spec.ts:
import { z } from "zod";
import type { CardSpec } from "../../../../engine/cards/types";
import { <CardName>Component } from "./component";
export const cardSpec = {
type: "<card-name>",
title: "<Human Label>",
description: "<one-line description>",
schema: z.object({ /* fields */ }),
defaults: { /* sensible defaults */ } satisfies Partial<<CardName>Data>,
component: <CardName>Component,
agentHints: {
whenToUse: "<when to pick this card>",
notForUseCases: "<what this card is NOT for>",
exampleData: { /* minimal working data */ },
},
} satisfies CardSpec<<CardName>Data>;
src/episodes/<series>/cards/<card-name>/component.tsx:
BaseSlide, WindowSlide, ScrollSlideuseTheme() for all colors — never hardcode hex values<text> for chart labels, ticks, legends, or axis titles, snap x / y to integer pixels, especially for centered text, and prefer textRendering="geometricPrecision" to avoid shimmer in Remotion output./node_modules/.bin/tsc --noEmit after each card to catch type errors immediately. Never use npx tsc — it may install a fake tsc package instead of TypeScript.## New card / Card Suggestion entries to match reality.Visual assets shape narration, not the other way around. Resolve every image / thumbnail / browser-screenshot asset the plan implies before drafting ep.ts, so narration can describe what's actually on screen.
For each image / thumbnail / browser-screenshot asset the plan calls for, classify the beat first: is it claim-bearing evidence (the actual artifact must be shown — real UI screenshot, published chart, primary-source document, real-world photo) or is it a conceptual / hero / brand visual (the idea matters, not photographic fidelity)?
Preserve the plan's Card choice. Do not convert a markdown, mermaid, or other non-image row into an image card just because SVG generation is available. Only change the card type when implementation proves the planned card cannot express the beat; if you do, update plan.md and explain the reason in your completion note.
Conceptual / hero / brand visuals — default path for image beats:
public/episodes/<series>/<asset-name>.svg and use the image card. Use the series palette, fonts from series-config.ts, and 1920x1080 (or shell-appropriate) canvas. Make it contentful: labels, shapes, arrows, icons, callouts, branded composition that clarifies the beat in one frame.
markdown) instead of making a text poster.Claim-bearing evidence beats — only when the actual artifact must be shown:
## References for a matching URL. If found, download it to public/episodes/<series>/<asset-name>.<ext> using curl -sSL -o .... Prefer local paths over URLs — URLs rot and Remotion render is offline.public/episodes/<series>/<asset-name>.png.Last resort — placeholder:
PLACEHOLDER_<descriptive-name>.<ext> filename to use later. Mark the step now in your session todos so you remember to set the caption field during Phase 3. Conceptual beats should never reach this step — generate the SVG instead.Record the resolved asset paths (or placeholder names) so Phase 3 can wire them into ep.ts directly.
Placeholder policy:
PLACEHOLDER_ src is a warning, not a success. If the step is the Hero visual (per plan.md ## Topic), it is a blocker — do not complete build silently.caption field on the card explaining what asset is needed, so review knows what to provide. Example: caption: "NEEDS: before/after composite — ugly engineer UI vs Claude Design output".After all custom cards are built (Phase 1) and assets are prepared (Phase 2):
src/episodes/<active-series>/<epId>.ts.PLACEHOLDER_ name with a clear caption).## Structure rows as review sections, not a one-to-one final step list. Expand each section into as many concrete ep.ts steps as needed for a natural video.Series rule first. If
SERIES_GUIDE.md(or its companion files) defines a step duration cap, beat budget, split rule, or card density, use it. The numbers below are fallbacks only for series whose guide is silent on that dimension.
The build should preserve the approved target length and content depth. Do not compress a long plan into one narrated step per Structure row.
## Topic → Target length. If it names a concrete target such as 25 分鐘, use that as a sizing signal for the script.SERIES_GUIDE.md pacing rules for step size when present. As a fallback for normal narrated long-form content, estimate 30-60 seconds per narrated step, with about 45 seconds as the default mental model. This is sizing guidance, not a rigid split rule. Short visual punches can be shorter; dense explanations can run longer when the narration stays natural, but split them if multiple ideas are competing inside one step.durationInSeconds; duration is only a timing placeholder and subtitles/audio will override it later.25 分鐘 but only 5 tiny rows and no source depth), call that out and ask whether the target should shrink or the plan should expand.npx ars episode stats <epId> and compare declared/estimated duration against the target as a sanity check. If the output is much shorter than the plan implied, mention that explicitly and either expand the script or ask the user whether the shorter cut is intentional. Validation passing only means the file is structurally valid; it does not mean the episode has the intended depth.Before validate, do a writing pass against SERIES_GUIDE.md (and any companion style files). This is a self-review pass, not a CI gate — skip cleanly when the guide doesn't list a given dimension.
ep.ts narration fields for each one. For every hit, rewrite using the guide's replacement direction (or a natural rewrite if none provided).視頻, 質量, 缺省, 信息, 數據庫, etc. — and convert to Taiwan equivalents.step.data text fields (for example content, cardTitle, title, points, cta, ctaButtons, or chart labels) against the same step's narration. If the card text is more than ~50% verbatim narration, rewrite the card into key phrases / numbers / anchors. The card is the visual hook; the narration carries the story.If you make rewrites in this phase, re-read the affected steps once more before moving to Completion.
validating:<epId> before running validate.npx ars episode validate <epId> after writing ep.ts. Fix any validation errors before marking build done.npx ars episode stats <epId> and apply the Build density guidance above. Use it as a script-depth sanity check, not a mechanical gate.workstate.json, pending build-trigger intents, and the episode source file mtime.ep.ts for any PLACEHOLDER_ src values and report them in the chat handoff with the relevant caption text. Placeholders are review warnings, not a separate persisted build state.ready-for-review:<epId>failed:<epId>/ars:review <epId> after validation passes.