SkillsSkill for Claude

Demo moment library from sales demos

Give Claude a handful of recorded product demos and the modules new reps should learn, and it returns a demo moment library: for each module, the recordings and minutes where a rep has that page on the shared screen and stops to explain what it solves, with the page title read from a frame, the rep's words from the transcript, a link into your recording platform at that minute, and an empty column for you to mark what is good for training. Claude shortlists demos from CRM stages and meeting titles, cuts each recording to the demo part, prices the indexing against your Vivu plan, indexes the cuts in a private Vivu project, runs one search per module and checks every hit before it becomes a row. Reps rarely say the module's name, so which page they were explaining is only on the screen share, while pages clicked past on the way to others and modules only named out loud are left out.

Maintained by Vivu. Updated 2026-09-30.

Download

sales-demo-moment-library.zip

11 KB. Unzips to sales-demo-moment-library/SKILL.md. Upload the zip as it is in the Claude app, or unzip it into your skills folder for Claude Code.

SHA-256 696ee9d0e31d73aded6934512417fc395338ec588b633df545714beb66990ed9

At a glance

What the Demo moment library from sales demos skill does, where it runs, what it needs, and when it asks
Looks forMoments where a module's page stays on the shared screen while the rep explains what it solves, which a transcript cannot place because reps rarely name the module. Every hit is checked against the source video before it reaches the library: a half second sheet of frames must show the page staying rather than clicked past, the transcript must show the rep explaining it, and the page title is read from a full frame, not from Vivu's description.
Runs onClaude Code on your computer (terminal or the Code tab of Claude Desktop): it needs a shell with ffmpeg and the demo recordings and transcripts as local files. No residential IP is needed because nothing is downloaded from YouTube, and nothing is scheduled. Creating the Notion page uses the Notion connector.
Needs
  • The Vivu connector with write access, to create a private project, open its upload page and search
  • A shell with ffmpeg and ffprobe, to cut the demo part, measure minutes and extract frames of the screen share
  • The demo recordings as local mp4 files, because cuts and frames come from them and Vivu has no export tool
  • A timestamped transcript per recording, because the explanation check and quotes come from it; without one, rows stay candidates
  • The link pattern of your recording platform, so the library links to your own copy at the minute
  • A browser that can open the Vivu upload page, since the connector has no direct upload tool
  • The Notion connector, only if you want the library as a Notion page
Your Vivu planIndexing uses Vivu index minutes for the cut demo parts only, and each module uses one precise search, 5 credits each, plus a rewording when the first page is not clean. The skill measures the minutes with ffprobe, reads your allowance with vivu_get_usage and shows the cost before anything is uploaded. A few demo parts fit the Premium plan ($30 a month, 180 index minutes); the Free plan with 20 index minutes a month covers about one.
Asks you firstIt asks you to confirm the demos were recorded with customer notice and may be used for internal training, and that your company allows uploading them to a third party service, then asks before cutting (modules, queries and shortlist, and each demo's start and end), before uploading (minutes and credit estimate against your plan), before writing the full library (sample rows and field mapping), and before creating the Notion page (the parent page and the full rendered page).

The skill does its video work through the Vivu connector. If the connector is not in your Claude yet, add it first; the skill checks that it is connected before it does anything else.

Before you run it

  • Use only calls recorded under your company's policy, with customers told they are recorded and internal training allowed.
  • Telling a real stay from a page clicked past is a weak Vivu capability, tested only on synthetic demos; every hit is checked on a half second sheet of frames, and the transcript must show an explanation.
  • A module with no row does not prove no rep explained it; the skill reruns a broader search for thin modules and says what it found.
  • The reason text and video summaries are paraphrases, so quotes come from the transcript and page titles from full frames.
  • Frames showing customer names or data are flagged and kept out of the training page.
  • Creating the Notion page acts as you; it is shown in full and created only after you approve it.
  • Claude in Chrome uploads at most 10 MB per call; larger recordings are added in the Vivu web app, never split or recompressed.
  • Recordings stay in your Vivu project until you delete them, and the project is created private because the default is visible to the whole organization.
  • The library finds moments; it never scores reps or ranks demos, and does no face or voice recognition.

Start it

Once the skill is installed, ask for the task in your own words. Naming the skill is the most reliable way to have Claude use it. For example:

Here are five recorded product demos in DEMOS_FOLDER with their transcripts. For our report builder, permissions, integrations and alert rules pages, find where reps stop on the page and explain it, and build me a demo moment library for new rep onboarding.

In Claude Code you can also type /sales-demo-moment-library. Claude asks for anything the request leaves out, most important first.

What is inside

  1. When to use
  2. Working principles
  3. What you need before starting
  4. Inputs to collect
  5. Files and state
  6. Step 1: Check the Vivu connector and the setup
  7. Step 2: Confirm consent, list the modules and shortlist the demos
  8. Step 3: Cut each recording to the demo part
  9. Step 4: Price the indexing and get approval
  10. Step 5: Upload and index
  11. Step 6: Search each module and check every hit
  12. Step 7: Assemble demolibrary.csv and confirm the sample
  13. Step 8: Create the Notion page (optional)
  14. Compliance
  15. Known failure modes

The full skill

This is sales-demo-moment-library/SKILL.md from the download, as Claude reads it: the frontmatter first, then the instructions.

---
name: sales-demo-moment-library
description: "Build a module by module clip library from recorded sales demos with Vivu: find where reps stay on each product page and explain it, check each moment, write a Notion page. Use for rep onboarding."
---

Demo moment library from recorded sales demos

This skill takes a handful of recorded product demos (meeting recordings with a screen share, exported as mp4) and the list of product modules a sales enablement lead wants new reps to learn, and returns a demo moment library: for each module, the recordings and minutes where a rep has that module's page up on the shared screen and stops to explain what problem it solves, with the page title read from a frame, the rep's words from the transcript, a link into the team's own recording platform at that minute, and an empty column for the enablement lead to mark what is good for training. Claude shortlists the demos from CRM stages and meeting titles, cuts each recording down to the demo part, prices the indexing against the user's Vivu plan, indexes the cut demos in a private Vivu project, runs one search per module, checks every hit against frames and the transcript, and writes demo_library.csv. With the user's approval it then creates the library as a Notion page.

The value is in what only the screen share shows. Reps say "let me stop here" or "this part matters for your security review" and rarely say the module's name, so which page they were explaining exists only on the screen, not in the transcript. The transcript has the opposite blind spot: a rep who says "we also have alert rules, but I'll skip that" names a module that was never opened. The screen alone is not enough either, because reps click past pages on the way to others. So Vivu finds where each module's page stays on screen, a sheet of frames shows how long it stayed, and the transcript shows whether the rep explained it; a moment reaches the library only when all three agree.

When to use

Use when a sales enablement lead, sales trainer or revenue ops person says "build a clip library of our demo moments by module for new reps", "where in our recorded demos do reps explain the permissions screen", "find the minute in each demo where the report builder gets walked through", or "turn these demo recordings into a training page by feature". For one question about one recording ("when did she open the integrations page?"), search Vivu directly. For finding what customers asked for in calls, use a feature ask evidence skill instead. This skill does not score reps, rank demos or pick a "best demo"; the enablement lead decides what is good for training.

Working principles

  1. Report measured numbers, not estimates. When a number is an estimate, say so.
  2. Vivu's results are candidates. A moment becomes a library row only after the frames show the module's page staying on screen and the transcript shows the rep explaining it. Rejected candidates are counted and kept in rejected.csv with the reason.
  3. Stop and tell the user when a required capability or file is missing (no transcript, no ffmpeg, no write access in Vivu, no Notion connector). Do not guess around it.
  4. Ask the user before anything that is expensive to redo or that acts on their behalf: the shortlist and the indexing cost before upload, the sample rows before the full library, and the Notion page before it is created.
  5. Find moments; never judge people. The library does not rate reps, and good_for_training is filled in by a person.

What you need before starting

Check each item at the start of the run and tell the user plainly what is missing.

Requirement Why How to check
Vivu connector with write access create a private project, open its upload page, search vivu_get_account shows can_create_projects: true (tool names may carry a server prefix). A write call failing with "has not granted vivu.write" means the connection is read only; the user reconnects Vivu and allows write access
A shell with ffmpeg and ffprobe on the machine that holds the recordings cut the demo part, measure minutes, extract frames of the screen share ffmpeg -version and ffprobe -version
The demo recordings as local mp4 files (downloaded from Zoom, Google Meet, Teams or a call recording tool) frames and cuts come from the local files; Vivu has no export tool ls DEMOS_FOLDER
A transcript per recording with timestamps (the meeting tool's VTT or SRT export, or the output of a local speech to text tool) the explanation check and the quotes come from it, never from Vivu's reason text ls DEMOS_FOLDER for one .vtt or .srt per recording; tell the user which have none
The link pattern of the team's recording platform, for example https://PLATFORM/RECORDING_ID?t=SECONDS the library links to the team's own copy at the minute; Vivu result links expire ask the user for one working example link
A browser that can open the Vivu upload page the connector has no direct upload tool the user opens the link, or Claude in Chrome is connected
Notion connector, only if the library should become a Notion page Step 8 search Notion for the parent page the user names

The skill needs a shell and local files, so it runs in Claude Code on the user's computer (terminal or the Code tab of Claude Desktop). It downloads nothing from YouTube, so no residential IP is needed, and nothing is scheduled.

Inputs to collect

Ask for anything missing, most important first.

  1. The modules, four to six, each with a key, the page title as it appears in the product, and two or three controls visible on that page (for example report_builder: "Report builder", a list of data fields, a bar chart preview, an "Add filter" button). Required.
  2. The folder with the recordings (DEMOS_FOLDER). Required. If there are many, ask for the CRM stage and meeting title of each so Step 2 can shortlist.
  3. Which recordings to index. Default: Claude proposes four to six demo stage meetings whose titles mention a product demo.
  4. Where the demo part starts and ends in each recording. Default: Claude proposes it from the transcript (the first and last time the rep shares and talks about the product) and the user confirms.
  5. The recording platform link pattern. Default: no links; the library shows file name and time.
  6. Whether the library goes to Notion, and under which parent page. Default: no, demo_library.csv only.
  7. The Vivu project name. Default: "Demo library PRODUCT", private, where PRODUCT is the product name.

Files and state

Keep everything in one working folder next to the recordings:

demo-library/
  modules.json      module key, page title, visible controls, query
  demos.csv         shortlisted recordings: file, meeting title, CRM stage, demo start and end, minutes, transcript file
  cut/              copies of each recording cut to the demo part (Step 3), the files that get uploaded
  results/          raw search results, one JSON file per module and wording
  frames/           sheets and full frames used for each check
  demo_library.csv  verified rows
  rejected.csv      candidates that failed a check, with the reason
  state.json        uploaded files and video ids, searches run with job ids, every hit with its verdict, rows written, Notion page created

state.json is updated after every step. A rerun reads it first: files already uploaded are not uploaded again, searches already run are not rerun, checked hits keep their verdicts, and the Notion page is never created twice, so an interrupted run resumes where it stopped.

Step 1: Check the Vivu connector and the setup

Goal: every row of What you need is confirmed before anything is cut or uploaded.

  1. Call vivu_get_account. If the tool is missing, tell the user to add the Vivu connector in Claude (https://mcp.vivu.ai/mcp) and stop. If can_create_projects is not true, or a write call later fails with "has not granted vivu.write", ask the user to reconnect Vivu with write access and stop until they have.
  2. Run ffmpeg -version and ffprobe -version. List DEMOS_FOLDER and note which recordings have a transcript file.
  3. If Notion is wanted, search Notion for the parent page the user named.
  4. Create the working folders; ffmpeg does not create an output folder:
mkdir -p demo-library/cut demo-library/results demo-library/frames

Run every later command from inside demo-library/ (cd demo-library), so cut/, frames/ and results/ resolve to the folders just created.

Done when vivu_get_account shows can_create_projects: true, ffmpeg and ffprobe print versions, and the working folders exist.

Goal: modules.json and demos.csv, with the user's confirmation that these recordings may be used.

  1. Ask Compliance items 1 and 2 before anything else in this step. Leave out any recording that fails them.
  2. Write one query per module from its page title and visible controls, using this shape:
Field Query template Mode maximum_results
MODULE_KEY the presenter stays on the "PAGE_TITLE" page of the shared screen for a while (CONTROLS), not a page that is only clicked past for a second or two on the way to another page precise 10

PAGE_TITLE is the title exactly as the product shows it; CONTROLS are two or three things visible on that page, in plain words. Write what is on the page, not what the rep says: reps rarely name the module, and naming it in the query invites hits where the module is only mentioned. The "stays ... not clicked past" clause matters: without it, every brief pass through the page comes back too. All searches are precise because the library needs time ranges; a fast search only returns whole files, and the demos are already shortlisted. maximum_results 10 is more than the stays one module gets in four to six demos, and it is the ceiling on what comes back: a list that stops at exactly 10 means the cap was hit, so raise it and rerun that module. 3. Shortlist from text first. Read the meeting titles and CRM stages and pick four to six demo stage meetings. A whole call archive cannot be indexed on any plan, and discovery calls rarely share the product. Write demos.csv. 4. Show the modules, the queries and the shortlist, and wait for a yes.

In our test run the recordings were made for the test, so the consent question and shortlisting from CRM stages and meeting titles were not exercised in our test run; the modules and queries were written as above.

Done when the user has confirmed consent and approved modules.json and demos.csv.

Step 3: Cut each recording to the demo part

Goal: one file per recording that holds only the demo, in cut/, so index minutes are spent only on the part that can hold a module walkthrough.

  1. Find the demo part in the transcript: from the rep's first "let me share my screen" or equivalent to the last product talk before pricing or next steps. Show the proposed start and end per recording and let the user adjust.
  2. Cut without re-encoding (RECORDING_FILE is the path to the original recording in DEMOS_FOLDER; DEMO_START and DEMO_END are in seconds; CUT_FILE is the original file name without .mp4, so rows match back):
ffmpeg -v error -ss DEMO_START -to DEMO_END -i RECORDING_FILE -c copy cut/CUT_FILE.mp4

A stream copy starts at the nearest keyframe, so the cut can begin a few seconds early; that is fine for search. Keep DEMO_START in demos.csv: every time Vivu returns is relative to the cut file, and library times and links need DEMO_START added back to point into the full recording.

Step 3 was not exercised in our test run: the test recordings held only the demo, so nothing was cut and no offset was added.

Done when cut/ holds one file per shortlisted recording and demos.csv records each DEMO_START.

Step 4: Price the indexing and get approval

Goal: the user sees the cost before anything is uploaded.

  1. Measure each cut file and sum the minutes:
ffprobe -v error -show_entries format=duration -of csv=p=0 cut/CUT_FILE.mp4
  1. Call vivu_get_usage for the plan and what remains this month.
  2. Estimate search credits: one precise search per module, plus one rewording per module in case the first page is not clean. A precise search uses 5 credits in total. Label the total as an estimate.
  3. Show one table and wait for approval:
This run Remaining on the plan
Index minutes measured sum from vivu_get_usage
Search credits estimate from vivu_get_usage

For reference, the Free plan has 20 index minutes a month and 50 search credits a month; Premium is $30 a month with 180 index minutes and 500 search credits. As an estimate, five demo parts of about 18 minutes fill half of Premium and do not fit Free, where one demo part is about the limit. If the shortlist does not fit, offer these levers in order: shorten the cuts to the product walkthrough only, drop demos whose titles or notes suggest they skip the modules, split the work across months, and only then a larger plan. Never drop a recording the user asked for without saying so.

In our test run the account was an admin account whose vivu_get_usage shows no remaining allowance, so the comparison against a real plan and the approval were not exercised in our test run.

Done when the user has approved the minutes and the credit estimate.

Step 5: Upload and index

Goal: every cut file is ready in a private Vivu project.

  1. Call vivu_list_projects and reuse the project named in the inputs if it exists. Otherwise call vivu_create_project with that name and visibility "private". Demo recordings show customer names and voices; the default visibility is the whole organization.
  2. Call vivu_open_upload_page with the project ID right before the upload. The link expires in 180 seconds and is a sign in link, so never paste it into a message or file. Give it to the user to open in their own browser and choose the files in cut/, or attach them with a browser tool that can upload local files. Claude in Chrome accepts at most 10 MB per upload call, and an 18 minute screen share is usually larger; the user adds those in the Vivu web app. Never split or recompress a recording to fit.
  3. Poll vivu_list_videos about every 30 seconds until every file shows ready. Match each video back to demos.csv by file name; Vivu turns spaces and punctuation in names into "_", so compare names with those characters replaced. Record the video IDs in state.json.

In our test run the files went up through a script, not through a user's browser or Claude in Chrome; that upload path was not exercised in our test run.

Done when vivu_list_videos shows every file in demos.csv as ready.

Step 6: Search each module and check every hit

Goal: for each module, a list of checked stays with rejected candidates counted.

Run each module's query with vivu_search_videos (project_id, query, mode "precise", maximum_results 10). It returns a job ID. Call vivu_get_search_results until complete is true; each status call can wait up to 45 seconds, so a pending search is not a stalled one. Save each completed result as results/MODULE_KEY.json. Show the result page link in the live reply only; it expires after four hours, so it never goes into the library, Notion or any file.

Vivu returns a time range that contains the page, not the exact seconds, and the reason text is a paraphrase. Finding a page by its title and controls has held up in tests; telling a real stay from a page clicked past is a weak capability, tested only on synthetic demos with clean pages, so the sheet in check 1 decides, never the search alone. Check every hit in this order:

  1. Did the page stay? Make a sheet of one frame every half second across the window (START is start_ms / 1000, DURATION is (end_ms - start_ms) / 1000; the 8x6 grid holds 24 seconds, so for a longer window raise the second number):
ffmpeg -v error -ss START -t DURATION -i cut/CUT_FILE.mp4 -vf "fps=2,scale=320:-2,tile=8x6" -frames:v 1 frames/MODULE_KEY_HIT_sheet.png

HIT is h plus the hit's number within the module (h1, h2, ...). Keep the quotes around the filter. Count the cells that show the module's page; each cell is half a second. Windows start and end a little outside the stay, so the first and last cells often show the neighboring pages. Reject the hit as PASS_THROUGH when the page is up for less than about 8 seconds (16 cells), and write the stay's first and last second from the sheet into state.json. 2. Did the rep explain it? Read the transcript lines between the stay's first and last second. The hit is real only if the rep says what the module is for or what problem it solves. Reject it as NO_EXPLANATION when nobody talks, or the talk is about something else ("sorry, wrong page", pricing, small talk). When a recording has no transcript, keep the hit as a candidate: read vivu_get_video_summary with include_segments, start_ms and end_ms around the stay as a second signal only, mark the quote NOT VERIFIED, and tell the user to listen to that stretch. 3. Read the page title from a full frame in the middle of the explanation (SECONDS), not from the reason text and not from the window's first frame, which usually still shows the previous page:

ffmpeg -v error -ss SECONDS -i cut/CUT_FILE.mp4 -frames:v 1 -q:v 3 frames/MODULE_KEY_HIT_read.png

If the title is not the module's, reject the hit. If the frame shows a customer's company name, a real account or real customer data, keep the row but set flag CUSTOMER_DATA_VISIBLE so it stays out of the training page. 4. Rejected hits stay in results/ and go into rejected.csv with the reason; they are counted, not dropped silently. 5. A module with fewer rows than the user expected does not prove no rep explained it. Rerun that module once with the page wording below, which describes only the page and so returns every appearance of it including brief passes, and put each new hit through checks 1 to 3. Tell the user how many stays the second pass added.

Check 5 was not exercised in our test run: the page wording ran before the stay wording on every module, and the one stay the stay wording missed was not added back to the library.

These wordings ran in our test, for five modules of one admin console; adapt the title and controls to the user's product and keep the shape:

Field Query Mode maximum_results
report_builder the presenter stays on the "Report builder" page of the shared screen for a while (a list of data fields, a bar chart preview and an "Add filter" button), not a page that is only clicked past for a second or two on the way to another page precise 10
roles_permissions the presenter stays on the "Roles and permissions" page of the shared screen for a while (a grid of roles against permissions with checkboxes and a "Save changes" button), not a page that is only clicked past for a second or two on the way to another page precise 10
integrations the presenter stays on the "Integrations" page of the shared screen for a while (a grid of app cards, each with a "Connect" button), not a page that is only clicked past for a second or two on the way to another page precise 10
alert_rules the presenter stays on the "Alert rules" page of the shared screen for a while (a list of rules with on/off toggle switches and threshold values), not a page that is only clicked past for a second or two on the way to another page precise 10
audit_log the presenter stays on the "Audit log" page of the shared screen for a while (a table of timestamps, users and actions with an "Export log" button), not a page that is only clicked past for a second or two on the way to another page precise 10
MODULE_KEY, second pass only the "PAGE_TITLE" page open on the shared screen: CONTROLS precise 10

Why this chain: the module query finds where the page is on screen, the half second sheet turns the window into a measured stay and rejects pages that were clicked past, and the transcript flips from what was shown to what was said, so a stay without an explanation never becomes a row. There is no speech search, because reps explain modules without naming them.

Worked example from our test run

In our test run we used 4 synthetic demo recordings, 5.14 minutes in total, made for the test: one admin console with a home page and five module pages that share the same layout, navigation and colors. Three recordings had a synthetic rep voice; in each, the rep stayed on three module pages and explained what they solve without ever saying the module's name, clicked past two other module pages, and named one more module while the home page was on screen. The fourth recording was a silent control with the same kind of stays and passes and no voice at all. Before searching we wrote down every stay, pass and mention: 12 stays in total. From the upload to all 4 recordings ready took 2.1 minutes.

The first wording, with only the page title and visible controls, found every stay but could not tell a stay from a pass: across the five modules it returned 20 moments, 12 real and 8 false, and all 8 false ones were pages clicked past. After 1 rewording on the same corpus (the wording in the table above), the five queries returned 11 moments: 11 real, 0 false and 1 missed. The miss was a full stay on the Integrations page that the first wording had returned. The integrations query returned 2 moments, 2 real, with 1 missed; the report_builder query 3 moments, 3 real; the roles_permissions, alert_rules and audit_log queries 2 moments each, all real. None of the mentions made on the home page came back in either wording. The median window per module was 21 to 22 seconds, a little wider than the stay on both sides, so the sheet, not the window, gives the start and end.

In the three narrated recordings the rep's words also marked stays and passes (a pause line on some stays, an apology on some passes), so speech could have carried the signal there. On the silent recording, where nothing is said, the stay wording still returned all 3 stays and none of the 2 pages clicked past, so telling a stay from a pass came from the screen, not from the narration. The half second sheets showed every stay clearly, and the full frame read the right title every time. The transcript check rejected every hit on the silent recording as NO_EXPLANATION, so the library kept the stays found in the three narrated recordings. The transcripts were the fixture's script with its measured timing, not a meeting tool export or speech to text output; real demos with cursor movement, scrolling, pop ups, a rep talking over a page they are leaving, customer data on screen, and pages from similar products were not exercised in our test run.

Done when every hit of every module has a verdict in state.json and the user has seen the real and rejected counts per module.

Step 7: Assemble demo_library.csv and confirm the sample

Goal: one table the enablement lead can sort by module and turn into training.

  1. Build one row per verified stay. Use the stay's first and last second from the sheet, plus DEMO_START from demos.csv, for the times in the full recording:
module,recording_file,start_mmss,end_mmss,page_title_read_from_frame,frame_path,explanation_quote,quote_source,internal_link,good_for_training,flag,status
Report builder,RECORDING_FILE,00:08,00:26,Report builder,frames/report_builder_h1_read.png,"Here they pick exactly what they want to see, and they get the answer themselves in about a minute.",meeting transcript,https://PLATFORM/RECORDING_ID?t=8,,,verified
  1. Field mapping:
Field Source If unavailable
module the module name from modules.json none
recording_file the original file name from demos.csv none
start_mmss, end_mmss first and last cell of the stay on the sheet, plus DEMO_START the Vivu window, marked UNCERTAIN
page_title_read_from_frame read from the full frame UNCERTAIN
frame_path the frame the title was read from none
explanation_quote the transcript lines inside the stay, word for word, shortened to one or two sentences NOT VERIFIED
quote_source meeting transcript or local speech to text none
internal_link the user's link pattern with SECONDS = start in the full recording blank
good_for_training left empty for the enablement lead blank
flag CUSTOMER_DATA_VISIBLE when a frame shows customer data blank
status verified candidate when the transcript is missing
  1. Show two or three sample rows and the mapping and wait for a yes before writing the full table. Say which parts are inferred: whether a sentence "explains the module" is Claude's reading of the transcript; if it is wrong, a row may show a rep who only described the screen, which the enablement lead catches when filling good_for_training.
  2. Write demo_library.csv and rejected.csv, and give the user the counts: rows per module and per recording, candidates rejected per module and why. When a module has no row, say so plainly; do not fill it with a pass or a mention.

In our test run the library and rejected.csv were built from the checked hits; the user's approval of the sample rows was not exercised in our test run.

Done when demo_library.csv exists with one row per verified stay and the user has approved the sample rows.

Step 8: Create the Notion page (optional)

Goal: the library sits in the team's wiki as one page, grouped by module.

  1. Only if the user asked for it in the inputs. Render the page: a short intro, then one heading per module with a table of recording, start, end, what the rep says, internal link and an empty good for training column. Leave out rows flagged CUSTOMER_DATA_VISIBLE. Use the recording platform link or the file name and time, never a Vivu result page link (it expires after four hours).
  2. Creating a Notion page acts as the user. Name the parent page, show the full rendered page, and wait for an explicit yes. Record the created page in state.json so a rerun never creates it twice.

Step 8 was not exercised in our test run: the page was rendered to a file and the Notion connector was never called.

Done when the approved page exists under the named parent and is recorded in state.json, or the user chose demo_library.csv only.

Compliance

  1. Use only calls recorded under the company's recording policy, where the customer was told the call is recorded and internal training is an allowed use. Ask before Step 2 and leave out any recording that does not meet this.
  2. Recordings of customers are personal data. Ask before Step 5 whether the company allows uploading them to a third party service, and create the Vivu project as private. The recordings stay in the user's Vivu project until the user deletes them; the skill never calls vivu_delete_video or vivu_delete_project unless the user asks, and confirms first.
  3. Frames that show a customer's name, account or data are flagged CUSTOMER_DATA_VISIBLE and kept out of the training page.
  4. The library finds moments. It never scores reps, ranks demos or names a "best demo"; good_for_training is a person's call.
  5. No face, voice or identity recognition. Vivu only finds when a page is on screen; it does not cut or edit video, and any clip is cut by the user from their own files.

Known failure modes

Symptom Cause Fix
(observed) pages the rep only clicked past come back as hits; the first wording in our test run returned 8 false of 20, every one a pass through a page a query that describes only the page finds every appearance of it, however brief use the stay wording from Step 2, and reject any hit whose sheet shows the page only briefly (the Step 6 threshold)
(observed) a stay the first wording found is missing after the rewording; the integrations query in our test run returned 2 real and 1 missed the stricter wording also drops some real stays when a module has fewer rows than expected, rerun the page wording for that module and check each new hit the same way
(observed) a page stays on screen but nobody explains it; every hit on the silent test recording was a real stay with no words in the window the rep is silent, or talking about something else, while a page is up the transcript check rejects it as NO_EXPLANATION
(observed) the video summary says a module was shown when it was only named: "Briefly navigates through alert rules and displays the system audit log tracking user actions." summary segments mix what was said with what was on screen use segments only as a second signal; the sheet decides what was on screen
(observed) the window's first frame shows the previous page windows start and end a little outside the stay read the title from a full frame in the middle of the explanation, and take start and end from the sheet
a rep names a module without opening it and a transcript search would count it the transcript holds the words, not the screen this skill searches the screen; never add a row from the transcript alone
the reason text describes controls or data that are not on the page the reason is a paraphrase, not a reading of the frame read the title and data from the full frame only
a module comes back empty an empty result does not prove no rep explained it; the page may look different from the query check the page title and controls against a frame of that page, reword once, run the page wording, and tell the user
a list stops at exactly maximum_results the cap cut the list short raise maximum_results and rerun that module
library times point a few minutes early in the full recording times were taken from the cut file without DEMO_START add DEMO_START from demos.csv to every time and link
"has not granted vivu.write" Vivu connected read only the user reconnects Vivu with write access
upload page asks to sign in or shows an error the one time upload link expires after 180 seconds request a new link right before opening it
a file is rejected by the browser upload tool Claude in Chrome takes at most 10 MB per upload call the user adds that file in the Vivu web app; never split or recompress it
a result's file name does not match demos.csv Vivu replaced spaces or punctuation in the name compare names with those characters replaced by "_"

Connect Vivu, then add the skill.

The skill runs through the Vivu connector. Add it to Claude from the connector directory, then install the skill.