Skip to content
Back to skills

260930 Split Cli Examples

ASecurity

```text $ vid2 example ls name, title, duration, needs, whether a workspace exists $ vid2 example show opus-astra-paper manifest: summary, techniques, needs, steps, output, README path $ cd "$(vid2 example new opus-astra-paper)" copy sources into $VID2_HOME/examples/opus-astra-paper, print the path $ vid2 example new vid2-intro --dir ./intro copy into ./intro instead $ vid2 example path opus-astra-paper workspace path (no side effects); --source prints the package

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 29, 2026
ai-agentsgobashnodespringgit

Works with

  • cli

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 6 files and shows the line behind each finding

Scanned September 29, 2026

npx -y skills add lidge-ai/vid2-gen --skill 260930_split_cli_examples --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 260930 Split Cli Examples?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 260930 Split Cli Examples
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lidge-ai-260930-split-cli-examples/badge)](https://www.skillsdirectory.com/skills/lidge-ai-260930-split-cli-examples)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# 030 wp4: examples on demand — `vid2 example` and the vid2-examples skill

## Target behaviour

```text
$ vid2 example ls                    name, title, duration, needs, whether a workspace exists
$ vid2 example show opus-astra-paper manifest: summary, techniques, needs, steps, output, README path
$ cd "$(vid2 example new opus-astra-paper)"   copy sources into $VID2_HOME/examples/opus-astra-paper, print the path
$ vid2 example new vid2-intro --dir ./intro   copy into ./intro instead
$ vid2 example path opus-astra-paper          workspace path (no side effects); --source prints the packaged folder
```

`new` keeps `examples/workspace.mjs` semantics: repository sources overwrite their workspace copies; `media/`, `out/`,
`.work/` and `*.vid2cap/` in the workspace are kept. In text mode `new` and `path` print only the path so `cd "$(...)"` works.

## Files

| Path | Change |
|---|---|
| `examples/<name>/example.json` | NEW for opus-astra-paper, claude-codex-dawn, ima2-launch, vid2-intro, vid2-launch, generated-video |
| `src/examples/manifest.ts` | NEW: zod `strictObject` schema + `readManifest(dir)` |
| `src/examples/catalog.ts` | NEW: `examplesRoot()` = `packageRoot()/examples`; `listExamples()` = folders with a manifest, sorted |
| `src/examples/workspace.ts` | NEW: `WORKSPACE_ONLY`, `workspaceRoot()`, `workspaceFor(name)`, `syncWorkspace(name, dest?)` moved from `examples/workspace.mjs:13-30` |
| `src/examples/index.ts` | NEW barrel |
| `examples/workspace.mjs` | MODIFY: thin wrapper importing `../src/examples/index.ts` (precedent `scripts/skills-lint.mjs:5`); CLI flags unchanged |
| `src/cli/commands/example.ts` | NEW: parent spec `example` (group author) with subcommands ls, show, new, path |
| `src/cli/registry.ts` | MODIFY: register `example` |
| `src/cli/output.ts` | MODIFY: text mode prints `data.path` alone for `example new` / `example path` |
| `package.json` `files` | MODIFY: add `"examples"`, `"!examples/*/media"`, `"!examples/*/out"`, `"!examples/*/.work"`, `"!examples/*/*.vid2cap"`, `"!examples/opencodex-*"`, `"!**/.DS_Store"` |
| `examples/*/README.md`, `examples/README.md` | MODIFY: first line of each build block becomes `cd "$(vid2 example new <name>)"`; README index gains a column for `vid2 example show`; repository users keep `node examples/workspace.mjs` (mentioned once in examples/README.md) |
| `skills/vid2-examples/SKILL.md` | NEW skill (below) |
| `skills/vid2/SKILL.md` | MODIFY: route "make a video like X / start from an example" to vid2-examples |
| `skills-manifest.json` | regenerated by `npm run build` (`scripts/skills-manifest.mjs`) |
| `.claude-plugin/plugin.json` | MODIFY (in 040): add `./skills/vid2-examples` |
| `tests/e2e/examples.test.ts` | MODIFY: manifest/README consistency tests (below) |
| `tests/e2e/pack.test.ts` | MODIFY: tarball ships every manifest, no excluded paths, example bytes ≤ 600 KB; the packed install runs `vid2 example ls` and `vid2 example new` |
| `structure/INDEX.md`, `AGENTS.md` | MODIFY: owner row for `src/examples/` |
| `structure/skills.md` | MODIFY: list vid2-examples |

## Manifest (src/examples/manifest.ts)

```ts
export const ExampleManifest = z.strictObject({
  name: z.string().regex(/^[a-z0-9-]+$/),          // must equal the folder name
  title: z.string().min(1),
  summary: z.string().min(1),                       // one sentence: what the film is
  durationS: z.number().positive().optional(),
  size: z.string().regex(/^\d+x\d+$/).optional(),   // "1920x1080"
  techniques: z.array(z.string().min(1)).min(1),    // "stage nodes", "springs", "web capture", ...
  goodFor: z.array(z.string().min(1)).min(1),       // requests this example answers: "paper cutout short", ...
  needs: z.array(z.strictObject({ tool: z.string(), optional: z.boolean().optional(), note: z.string().optional() })),
  edit: z.array(z.strictObject({ file: z.string(), what: z.string() })).min(1),   // where to change content for a new film
  steps: z.array(z.strictObject({ run: z.string().min(1), note: z.string().optional() })).min(1),
  output: z.string().min(1),                        // final video path relative to the workspace
});
```

`steps[].run` are the README's build-block lines after the `cd` line, verbatim and in order, without trailing `# comments`.
Example (opus-astra-paper, from its README build block):

```json
{ "name": "opus-astra-paper", "title": "Opus & Astra — a paper-cutout short", "durationS": 26, "size": "1920x1080",
  "summary": "A 26 s paper-cutout short built only from JS stage nodes, with a music-box cue.",
  "techniques": ["stage nodes", "spring pops", "squash and stretch", "procedural paper texture", "bar-aligned scenes"],
  "goodFor": ["paper cutout or craft-style short", "character animation without images", "cute mascot story"],
  "needs": [{ "tool": "ffmpeg" }, { "tool": "music2-gen", "optional": true, "note": "for the cue; drop the audio block without it" }],
  "edit": [{ "file": "build-timeline.mjs", "what": "characters, scenes and timings" }, { "file": "music/gen-song.mjs", "what": "the cue" }],
  "steps": [{ "run": "node make-paper.mjs media/paper.png" }, { "run": "node music/gen-song.mjs music/opus-astra.song.json" },
    { "run": "music2 render music/opus-astra.song.json -o media/music.wav" }, { "run": "node build-timeline.mjs" },
    { "run": "vid2 validate timeline.json" }, { "run": "vid2 preview timeline.json --at 1s,5s,12s,22s --out out/preview" },
    { "run": "vid2 render timeline.json --profile proxy -o out/proxy.mp4" }, { "run": "vid2 render timeline.json -o out/opus-astra-paper.mp4" },
    { "run": "vid2 qa out/opus-astra-paper.mp4 --timeline timeline.json --expect-audio --out out/qa" }],
  "output": "out/opus-astra-paper.mp4" }
```

## Command (src/cli/commands/example.ts)

| Sub | Args / options | data |
|---|---|---|
| `ls` | none | `{ examples: [{name,title,summary,durationS,needs,workspace,ready}] , templates: listTemplates() }` |
| `show <name>` | none | manifest + `source`, `readme`, `workspace`, `ready` |
| `new <name>` | `--dir <path>` | `{ name, path, source, files, steps }`; artifacts `[path]` |
| `path <name>` | `--source` | `{ name, path }` |

Unknown name → `E_INPUT unknown example`, `details.examples`, `fix: "run vid2 example ls"`.

## Skill (skills/vid2-examples/SKILL.md)

Frontmatter description names the triggers ("make a video like", "example", "paper cutout", "launch film", "puppet", "keynote",
"start from a template"). Body: (1) a table mapping request shapes to an example or `vid2 init` template, using each
manifest's `goodFor`; (2) the fast route: `vid2 example show <name>` → `cd "$(vid2 example new <name>)"` → run the steps up to
the proxy render → edit the manifest's `edit` files for the new content → proxy, QA, final; (3) fallbacks: no music2 → drop the
audio block or use `vid2 audio synth`; no ima2 → `--placeholders` or the offline twin; missing logos/fonts in
claude-codex-dawn → substitute files at the paths its README names; (4) reuse notes per technique pointing at the example file
that implements it (key collector and seeded `rnd()` in opus-astra-paper, puppet helpers in claude-codex-dawn/puppets.mjs,
bar-synced cuts in ima2-launch, typed command and rolling number in vid2-intro). Every `vid2 X Y` mention passes the 020 lint.

## Tests

`tests/e2e/examples.test.ts` additions: every folder under `examples/` except `hello.json` has a valid manifest whose `name`
equals the folder; every `steps[].run` appears, in order, in the README's bash fence; every `vid2 ...` step resolves through
`resolveCommand`; every example has a row in `examples/README.md` and in `skills/vid2-examples/SKILL.md`; `main(["example",
"new", name, "--dir", tmp])` copies the sources and skips a pre-seeded `media/keep.txt` (activation of the WORKSPACE_ONLY filter:
seed `tmp/media/keep.txt` and `tmp/out/x.mp4`, sync, assert both still exist and the README was copied).

`tests/e2e/pack.test.ts`: an ungated check runs `npm pack --dry-run --json --ignore-scripts` and asserts every
`examples/*/example.json` is listed, nothing under `media/`, `out/`, `.work/`, `*.vid2cap/` or `.DS_Store` is, and example
bytes ≤ 600 KB (activation: create `examples/opus-astra-paper/media/probe.bin` for the duration of the test and assert it is
absent from the list). The gated packed-install test adds `vid2 example ls --json` and `vid2 example new vid2-intro --dir <tmp>`.

## Verifiers

`node --test tests/e2e/examples.test.ts`, `VID2_PACK_TEST=1 node --test tests/e2e/pack.test.ts`, `npm run skills:check`,
`npm run build` (regenerates skills-manifest.json), `npm test`, `npm run privacy:scan`.

## Architect dispositions

D9 accepted, plus `goodFor` and `edit` so the skill can map requests to examples and say which file to change. D10 accepted.
D11 amended: `new` prints the workspace path (so `cd "$(vid2 example new x)"` replaces `node examples/workspace.mjs x`),
`--dir` instead of a positional directory; `path` prints the workspace path, `--source` the packaged folder. D12 accepted.
D13 accepted. Open assumption 3: packaged READMEs move to `vid2 example new`; examples/README.md keeps one line for repository
users. Assumption 5: `scripts/privacy-scan.mjs` already scans tracked files, which include `examples/` (re-checked in B).

## Reflection folds (Feynman: ALIGNED with gaps, 2026-09-30)

These rules supersede the sections above where they differ.

- R4 (gap 4). Success `command` strings are `"example ls"`, `"example show"`, `"example new"`, `"example path"`. `path --source`
  returns the folder in `data.path`, so `output.ts` special-cases `example new` and `example path` on `data.path` alone.
- R5 (gap 5). examples.test.ts asserts each example README's build block starts with `cd "$(vid2 example new <name>)"`.
- R6 (gap 6). The pack exclusion test does not touch the checkout. It copies `package.json` and `examples/` into a temp directory,
  seeds `examples/opus-astra-paper/{media/probe.bin,out/x.mp4,.work/y}` and `.DS_Store` there, runs
  `npm pack --dry-run --json --ignore-scripts` in the temp directory and asserts the seeded files are absent and every manifest is
  present. A second assertion on the real repository compares `git ls-files examples` (minus `examples/workspace.mjs` if
  excluded, and `hello.json`) with the packed list. That guards tracked files that an `examples/*/.gitignore` would otherwise
  drop, such as `ima2-launch/timeline.json`, `generated-video/timeline.json` and `vid2-launch/code-page/demo-timeline.json`. If
  npm drops them, B adds explicit `files` entries for them.
- R7 (gap 7). Checked: `scripts/privacy-scan.mjs` `refs()` reads `git ls-tree -r -z HEAD` (or `rev-list --objects <range>`), so
  every tracked file, including `examples/`, is scanned.
- R8 (gap 8). Links from example READMEs to repository docs (`../../structure/*.md`) become
  `https://github.com/lidge-ai/vid2-gen/blob/main/structure/*.md`, because the package and the workspace do not contain
  `structure/`.

## Audit folds (Goodall round 1, 2026-09-30) — supersede the sections above

- A4. `syncWorkspace(name, dest?, opts?: { sourceRoot?: string })`. The filter test builds a fixture source
  (`<tmp>/src/demo/{README.md,example.json,media/a,out/b,.work/c,x.vid2cap/d,.DS_Store}`), syncs it and asserts only README.md
  and example.json arrive; a second sync into a destination seeded with `media/keep` asserts it survives.
- A5 + A6 (replace R6). `package.json` `files` adds `"!examples/workspace.mjs"` too: the wrapper imports `src/`, which is not
  packed. The pack comparison uses `git ls-files examples` minus `**/.gitignore` (npm never packs nested .gitignore files) and
  minus `examples/workspace.mjs`; `examples/hello.json` stays on both sides. The seeded-exclusion check runs in a temp copy as R6
  describes.
- A9. `src/skill/install.test.ts` (lines 14, 15, 32, 46, 50) and `src/skill/manifest.test.ts:15` hardcode 6 skills; both derive
  the count from the `skills/` directories instead.
- A11. `steps[]` = every line of every bash fence in the README, in order, with `cd ...` lines and trailing `# comments`
  removed; blank lines skipped. `generated-video/README.md` gains `cd "$(vid2 example new generated-video)"`. R5 checks the first
  line of the first bash fence.
- A12. `example ls` rows are `{name, title, summary, durationS, needs, workspace, ready}`: `workspace` is the workspace path and
  `ready` is true when that directory exists. `show` returns the same two fields.
- A15 (round 2 Medium blocker). vid2-launch no longer reads the repository: its build block becomes
  `cd "$(vid2 example new vid2-launch)"`, `vid2 init feature-demo .work/feature-demo --force`, then
  `vid2 capture web --serve .work/feature-demo/site --steps app.steps.json --size 1280x720 --scale 1.5 --out app`; the `REPO`
  line and the `$REPO/templates/...` path go away in the block and in the table. `vid2 init` ships `templates/feature-demo/site/`
  in the package, so the step works from an npm install. R5 then holds for all six READMEs.

## wp4 P re-verification (2026-09-30, after wp3 D at 9daefb2)

- `example` is built with `parentCommand` from `src/cli/tree.ts` (020 A1); its four subcommands are leaf `CommandSpec`s with
  `group` on the parent (`author`), a `value` name for every string option and at least one example each, which
  `src/cli/help.test.ts` test 1 already enforces for every registered path.
- Adding `example` also updates: `structure/cli-contract.md` parent list, `ROOT_EXAMPLES` in `src/cli/globals.ts` (re-add
  `vid2 example ls`), README command table (`init`, `example` row) and the CHANGELOG Unreleased section.
- Skill-count tests: `src/skill/install.test.ts:14,15,46,50` (`installed.length`, `changedCount > 6`, link-mode `changedCount 6`)
  and `src/skill/manifest.test.ts:15` derive the count from `readdirSync(SKILLS_ROOT)` directories.
- The existing workspace test (`tests/e2e/examples.test.ts` "workspace.mjs copies sources ...") keeps running against the thin
  wrapper and still covers destination preservation; A4's fixture-source test is added next to it.
- No design decision changes, so no architect call; the plan is re-audited by the A reviewer.

Files in this skill

  • 000_plan.md3.8 KB
  • 010_repo_split.md7.4 KB
  • 020_cli_help_tree.md15.8 KB
  • 030_example_command_skill.md13.8 KB
  • 040_release.md6.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.