Video EditingCAUTION
A framework for building agentic apps
Overview
A framework for building agentic apps
d31edd75948aOBSERVED · 2026-10-14What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: video-editing
description: >-
Non-destructive video editing in Clips — the editsJson model, trim / split /
cut / speed / blur, transcript-based editing, and ffmpeg.wasm export. Use
when building the editor UI, adding a new edit operation, or wiring the
export pipeline.
---
# Video Editing
## When to use
Reach for this skill any time you modify how recordings are edited: new edit operations, the timeline UI, transcript-driven cuts ("remove the ums"), the preview overlay, or the export flow. Editing **must** be non-destructive — the recording blob is immutable after upload.
## Data model touched
- **`recordings.edits_json`** — a JSON column with the edit document. Shape:
```json
{
"version": 1,
"trims": [
{ "startMs": 0, "endMs": 3200, "excluded": true },
{ "startMs": 12000, "endMs": 12000, "excluded": false }
],
"blurs": [],
"thumbnail": null
}
```
- **`recordings.chapters_json`** — JSON array of `{ startMs, title }`.
- **`application_state.editor-draft`** — in-progress editor state the user is previewing (recording id, playhead, preview playback speed, zoom, and edits JSON). Persisted edit operations still write directly to `edits_json` through actions.
## Rules
1. **Non-destructive.** Never re-encode on edit. The original webm/mp4 stays intact at `recordings.video_url`. Edits only change the JSON.
2. **Single source of truth.** The player renders edits at playback time — read `edits_json`, compute the virtual timeline, and skip excluded ranges via `HTMLVideoElement.currentTime` seeks. Do not fork the edit model for the editor vs the player.
3. **Export is explicit.** The user must click Export to render a new file. That call goes through `export-video` and kicks off ffmpeg.wasm (or server-side ffmpeg if the recording is long).
4. **Use edit actions.** Agents must use the recording actions below instead of writing `edits_json` directly.
## Timestamp-based editing actions
Timestamp arguments are integer milliseconds on the original video timeline,
even when earlier edits have shortened playback. Convert clock timestamps to
milliseconds before calling an action; for example, `1:23` is `83000` ms.
| Action | Required arguments | Effect |
| --- | --- | --- |
| `trim-recording` | `recordingId`, `startMs`, `endMs` | Excludes the range from playback. `endMs` must be greater than `startMs`; overlapping or adjacent excluded ranges are merged. |
| `split-recording` | `recordingId`, `atMs` | Adds a zero-width split marker for the editor UI. It does not physically split or rewrite the video and does not change playback. |
## Transcript-based editing
Users love editing by text — click a filler word in the transcript, remove it. The editor uses `recording_transcripts.segments_json` to map words to `{ startMs, endMs }` ranges; clicking a segment creates a `cut` edit for that range.
"Remove the filler words" is **not** solved inline — it delegates to the agent. See the `ai-video-tools` skill. The agent analyzes the transcript, proposes a list of cuts, writes them to `editor-draft` for review, and the user one-click approves.
## Export
```ts
// actions/export-video.ts
export default defineAction({
schema: z.object({ id: z.string(), format: z.enum(["mp4", "webm"]).default("mp4") }),
run: async ({ id, format }) => {
await assertAccess("recording", id, "editor");
const rec = await getRecordingOrThrow(id);
const edits = JSON.parse(rec.editsJson || "{}");
// Short clips (< 2 min) render client-side via ffmpeg.wasm.
// Longer ones are queued for server-side ffmpeg.
return { exportId: enqueueExport({ recordingId: id, edits, format }) };
},
});
```
For **short recordings**, load ffmpeg.wasm in a web worker, feed it the source blob + the edit list, and return the rendered file. For **long recordings**, enqueue a background job and have the UI poll `export-status` every 2s.
## Player integration
The player is the canonical renderer for edits. Given `edits_json`, compute a `VirtualTimeline`:
```ts
interface VirtualTimeline {
// Maps virtual ms -> source ms, skipping cuts/trims.
toSource(virtualMs: number): number;
// Total virtual duration after edits applied.
durationMs: number;
// Ranges to skip on playback: the player listens for timeupdate and seeks past them.
excludedRanges: { startMs: number; endMs: number }[];
}
```
Never call `video.currentTime` with a raw segment index — always go through `toSource`.
## Rules
- The edit UI writes to `editor-draft` on every change, and only writes to `edits_json` on Save (so Cmd+Z is cheap and the DB stays clean).
- Never mutate `edits_json` from `db-exec`; use the recording actions above. Use `clear-edits` to reset edits.
- Speed edits compound (`1.5 × 2 = 3x`) — validate the result is in `[0.25, 4]`.
- Blur coordinates are in **source resolution**, not display pixels. Always normalize against `recordings.width` / `recordings.height`.
## Related skills
- `ai-video-tools` — filler-word removal and chapter generation propose edits via the agent.
- `real-time-sync` — when the agent writes `edits_json`, the player must reflect it; `edits_json` is part of the `recordings` row which is already on the sync list.
- `video-sharing` — exports honor the share's `enableDownloads` flag.
- `storing-data` — why edits live in a JSON column rather than a separate table.
---
## Editor implementation reference
### Concrete `editsJson` shape (editor team)
The editor writes and reads this exact shape. Any new edit operation MUST
preserve this shape so the player, editor, and export pipeline stay in sync.
```ts
interface EditsJson {
version: 1;
// Ripple-style trim ranges. `excluded:true` ranges are skipped during
// playback and collapsed during export. `excluded:false` entries where
// `startMs === endMs` are SPLIT MARKERS used by the editor UI — they
// never affect playback.
trims: Array<{ startMs: number; endMs: number; excluded: boolean }>;
blursTrust audit
CAUTIONgrade B · trust 89/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (5)
.agents/skills/an
.agents/skills/content-product-development
.agents/skills/design-exploration
.agents/skills/turn-into-app
.agents/skills/visual-edit
Gates applied: no_behavioural_pass.
d31edd75948afull audit observations/trust-audit/skill/builderio__video-editing.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-14 | d31edd75948a | CAUTION | B | 89 | first audit |
Questions
What does the Video Editing skill do?
A framework for building agentic apps
Is Video Editing safe to install?
With care. The audit graded it B (89/100) and found 5 things worth knowing before you trust this skill, listed below with the exact line each was found on.
What can Video Editing access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (d31edd75948a), read on 2026-10-14. The repository is watched, and a new audit runs when it changes — this is the first audit.
Add this badge to your README
Shows this page's audit result and links back to it. It updates when the audit does.
[](https://modelsatlas.com/skills/builderio/video-editing/)
Not your listing, or something out of date? Claim or update your listing.