@screenci/screenci
Create, show, and guide with ScreenCI videos in an already-initialized project by editing `.video.ts` files and running the Screenci workflow.
| name | screenci |
| description | Create, show, and guide with ScreenCI videos in an already-initialized project by editing `.screenci.ts` files and running the Screenci workflow. |
| allowed-tools | Bash(screenci:*), Bash(npx:*), Bash(npm:*) |
ScreenCI Video and Guide Skill
Use this skill when the task is about ScreenCI video recording in an existing project: creating a video, showing a flow as a video, or editing .screenci.ts / screenci.config.ts files.
Routing:
- If the user gives a URL for video context, use the
playwright-cliskill first to discover the real page flow, stable selectors, and cookie/consent steps before editing the script. - If the user gives source code for the target page, browser exploration is usually not needed first.
- If the request is only about application/source-code changes (not recording), do not use this skill.
Quick Start
The project is already initialized. Add or edit scripts in recordings/. If you are creating new videos, remove the starter recordings/example.screenci.ts.
# verify repeatedly until green
npx screenci test
# run a subset with normal Playwright filters
npx screenci test recordings/signup.screenci.ts --grep "fills billing details"
# once tests pass, record the free live preview and print the web editor link
# (one-shot: it syncs queued browser edits into the scripts, records, and exits)
npx screenci preview "Video title"
# pull queued browser edits into the scripts at any time
# (test, export, and preview also do this automatically on start)
npx screenci sync
# only export when the finished videos are wanted
npx screenci export
test forwards normal playwright test arguments and still injects the resolved screenci.config.ts. --config/-c and --verbose/-v are reserved for the ScreenCI CLI, not forwarded to Playwright.
What ScreenCI Adds
ScreenCI uses Playwright-style .screenci.ts files plus recording helpers:
video()declares one output video per test.hide()cuts setup and loading sections from the final recording.autoZoom()follows navigation and click-driven flows with smooth camera motion. Use it for movement between targets.zoomTo()/resetZoom()hold a fixed frame for forms and steady editing sections.video.narration({ ... })is mandatory (see below).
import { video, voices } from 'screenci'
// Voice is a render option (how narration is spoken), not part of the narration spec.
video.renderOptions({ narration: { voice: { name: voices.Ava } } }).narration({
en: {
intro:
'This video shows how to update your billing details and save the changes.',
explainForm:
'We start on the billing page and update the company name, email, and tax ID.',
saving: 'Now we save the changes and wait for the confirmation message.',
nextPage:
'Next, we open the invoices section to confirm the new billing details are in use.',
},
})('Update billing details', async ({ page, narration }) => {
await narration.intro()
await narration.explainForm()
await narration.saving.start()
await page.getByRole('button', { name: 'Save changes' }).click()
await narration.saving.end()
await narration.nextPage()
await page.getByRole('link', { name: 'Invoices' }).click()
})
Narration
- Declare
video.narration({ ... })on every video and speak throughout the demo. Pass a flatcue -> textobject (shared across languages) or one keyed by language (en,es, ...). - The opening line must state the video's purpose, then continue with the walkthrough.
- Trigger cues from the
narrationfixture:await narration.key()runs the full line before moving on. Useawait narration.key.start()when narration should overlap the next action, andawait narration.key.end()to close that cue later, especially before visible navigation or route changes. - Use inline speech tags when needed:
[pronounce: ...],[short pause],[medium pause],[long pause]. Always guide pronunciation for URLs and domains, e.g.screenci.com [pronounce: screen see eye dot com].
Required Conventions
Every video MUST follow these:
- Narration on every video, no exceptions. Videos without narration are not acceptable.
- Open with the video's purpose before the step-by-step.
- Start on the requested page. The visible video begins on the page the user asked for.
- Hide initial setup. Wrap page load, auth, navigation to the start page, loading spinners, and cookie-banner dismissal in
hide(). After the initial navigation, find and click any cookie consent accept button inside that hidden block. - Navigate visibly with clicks after hidden setup, not
page.goto(). - Prefer mouse-driven selection after typing into search boxes, comboboxes, autocomplete, or command menus: click the visible result rather than
press('Enter')when a clickable target exists. - Prefer native Playwright APIs over
page.evaluate()when a locator method already covers the interaction (e.g.locator.blur()). - Prefer default action options. For
autoZoom()and locator actions (click,fill,pressSequentially,check,selectOption, ...), start with ScreenCI's defaults. Do not add a separateclick()beforefill()/pressSequentially()just to focus, and do not addzoom/click/position/timing overrides unless the user asks or the flow clearly needs it.
Zooming
Prefer stable manual zoom for edit-heavy sections; use autoZoom() for movement between targets, and let each autoZoom() block finish before a navigation or page change (start a new block on the next page). Keep autoZoom() usage sparse: justify each block by movement between targets, not simple text entry.
// Forms and steady editing: fixed frame.
await zoomTo(page.getByRole('form', { name: /profile settings/i }))
await page.getByLabel('Name').fill('Jane Doe')
await page.getByRole('checkbox', { name: 'Email notifications' }).check()
await page.getByRole('button', { name: 'Save changes' }).click()
await resetZoom()
// Navigation and click-driven flows: follow the movement.
await autoZoom(async () => {
await page.getByRole('link', { name: 'Reports' }).click()
await page.getByRole('button', { name: 'Open filters' }).click()
await page.getByRole('option', { name: 'Last 30 days' }).click()
await page.getByRole('button', { name: 'Apply' }).click()
})
Connecting to an Account (optional)
test and preview need no account: without a SCREENCI_SECRET, preview records and previews under a local, anonymous trial session (preview-only, no renders). Signing up in the web editor claims the trial and upgrades the running preview session automatically. Mention this and keep going.
export requires an account with an active paid subscription. To connect an existing organization, get SCREENCI_SECRET into screenci/.env (it does not block authoring, testing, or anonymous editing):
- Pass it to init:
npm init screenci@latest <SCREENCI_SECRET> -- --yeswrites it intoscreenci/.env. - Secrets page: ask the user to copy
SCREENCI_SECRETfrom their secrets page intoscreenci/.env. The org secret is shared across projects. Keep building and testing while they do it; onlypreview(with an account) andexportneed it.
The secret is the only credential to configure. The CLI mints this machine's personal editor token from it automatically (saved to screenci/.env as SCREENCI_EDIT_TOKEN; a claimed trial writes both too). Do not ask the user to create an editor token by hand. Do not add a separate upgrade upsell after export; report the result URL unless the user asks about plans.
Preview and Export Workflow
- Add or edit
.screenci.tsfiles inrecordings/(removeexample.screenci.tsif creating new videos). - Run
npx screenci testuntil it passes. Fix selectors/flow/narration and rerun until green. - Once tests pass, run
npx screenci preview "<title>"yourself. Do not export first. It is one-shot: it syncs any queued browser edits into the script, records the video's live preview if stale (free, no render), prints the web editor link, and exits.previewworks without an account: with noSCREENCI_SECRETit runs under a free anonymous trial session. Browser edits made while no machine is connected queue server-side and land in the script on the nextscreenci sync,test, orpreview(exportnever applies edits; in CI,preview --no-syncalso skips the edit sync so the checkout stays read-only). - Report the editor link
previewprinted so the user can review and refine the video in the browser. Browser edits queue server-side and land in the script on the nextscreencicommand, so there is no need to keep a session running. - Run
npx screenci exportonly when the user wants the finished videos. Exporting requires an account with an active paid subscription: without one,exportrefuses and prints a sign-up link (the anonymous trial is preview-only). With one, it records what changed, renders, waits, and downloads into./exports/. ScreenCI writes.screenci/<video-name>/recording.mp4anddata.jsonper re-recorded video. - After
export, report the URL it printed (starts with the app's domain, e.g.https://app.screenci.com/export/...) so the user can open it.
screenci init (or npm init screenci) scaffolds a new project and fails on purpose if one already exists (screenci/ already exists). That is expected: keep working with the existing project, do not delete it to re-init.
Specific Tasks
- Exporting videos references/export.md
</content> </invoke>
Loading...
Select a file to preview
Analyzing security...
Checking scan reports and verification data.
Bill of Materials
Everything this skill can do — files, network, commands, and more.