Skip to content
Back to skills

Save Transcript

ASecurity

Recovers the COMPLETE transcript of a meeting recording (Microsoft Stream, SharePoint) from its URL, and delivers a clean .txt with provenance, ready to share. Triggers on 'save-transcript', 'baja el transcript', 'saca el transcript de esta junta', 'transcript de <URL>'. For raw audio with no rendered transcript use transcribe.

  • 17 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 2, 2026
ai-agentspythongogit

Works with

  • cli

Security analysis

A100/100

Scanned September 20, 2026

npx -y skills add CarlosCaPe/octorato --skill save-transcript --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Save Transcript?

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

Security grade badge for Save Transcript
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/carloscape-save-transcript/badge)](https://www.skillsdirectory.com/skills/carloscape-save-transcript)

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
---
name: save-transcript
description: "Recovers the COMPLETE transcript of a meeting recording (Microsoft Stream, SharePoint) from its URL, and delivers a clean .txt with provenance, ready to share. Triggers on 'save-transcript', 'baja el transcript', 'saca el transcript de esta junta', 'transcript de <URL>'. For raw audio with no rendered transcript use transcribe."
---

# save-transcript

El operador pasa un nombre y una URL de grabacion. La salida es un `.txt` con encabezado
de procedencia, cobertura declarada y advertencias de transcripcion, verificado sin huecos.

**No confundir con `transcribe`**, que corre reconocimiento de voz sobre audio. Aqui el
transcript YA EXISTE, lo genero la plataforma, y el trabajo es rescatarlo completo cuando
la UI de descarga lo niega.

## Entrada minima

```
save-transcript <slug o nombre de la junta> <URL de la grabacion>
```

De la URL solo importa el `id`. Todo lo demas (`referrer`, `referrerScenario`, tokens de
vista) es ruido de navegacion: dos URLs con distinto `referrer` y el mismo `id` son la
misma grabacion. Verificalo antes de recapturar algo que ya tienes.

## Regla de oro: cobertura declarada, no conteo de cues

El fallo silencioso de este trabajo es entregar un transcript truncado que se ve completo.
"417 cues" suena a mucho y puede cubrir 22 de 32 minutos.

**La unica evidencia valida** es leer `video.duration` del reproductor y comprobar que no
haya minutos sin cue en todo el rango. Un conteo de cues no es cobertura, y afirmar
completitud sin ese chequeo es exactamente la clase de error que el operador va a cazar.

## Flujo

### 1. Primera pasada, cosecha por scroll

Corre el harvester normal de la plataforma. En grabaciones cortas alcanza. En grabaciones
largas se detiene: el panel es una lista virtualizada que recicla celdas y regresa el
scroll al tope, tipicamente alrededor del 60 a 80 por ciento de la altura. Lo reconoces
porque el contador de cues se congela mientras el offset rebota entre posiciones anteriores.

### 2. Segunda pasada, rescate por seek

Cuando la primera se estanca, **maneja el video, no la lista**. Poner
`video.currentTime` hace que el panel auto-scrollee al playhead y renderice esa region:

```js
await frame.evaluate((s) => { document.querySelector('video').currentTime = s; }, minuto * 60);
await page.waitForTimeout(2600);            // deja que el panel siga al playhead y pinte
const rendered = await extraeCuesRenderizados(frame);
```

Lee `video.duration` primero y camina una escalera de paradas cada 2 minutos desde poco
antes del estancamiento hasta el final. Detente cuando una parada no aporte cues nuevos.

### 3. Fusion de pasadas

El mismo cue se renderiza en mas de una forma: bloque multilinea (hablante, luego
`MM minutes SS seconds`, luego `MM:SS`, luego encabezado repetido, luego texto), bloque
de solo encabezado sin texto, y forma aplanada de una linea con el tiempo inline. Parsea
las tres, indexa por `(timestamp, hablante)` y **conserva la variante de texto mas larga**,
porque algunos renderizados truncan. Indexar por el string crudo produce duplicados casi
identicos y aun asi pierde el texto completo.

### 4. Verificacion de cobertura

```python
have = {segundos // 60 for segundos, _, _ in rows}
gaps  = [m for m in range(0, int(duracion // 60) + 1) if m not in have]
```

`gaps` vacio es la evidencia. Si no lo esta, dilo en el encabezado en vez de callarlo.

### 5. Barrido de datos sensibles antes de entregar

Obligatorio cuando el destino es un canal, un correo o una pagina. Patrones minimos:
identificadores de 6 o mas digitos, formato de seguro social, fechas de nacimiento,
identificadores profesionales de 10 digitos, correos, telefonos, y nombre propio precedido
por palabras como paciente o miembro. Los ejemplos hipoteticos que la gente inventa en
juntas ("digamos que el doctor se llama X") no son datos reales; distinguelos leyendo el
contexto, no solo el patron.

Si algo aparece, no lo entregues: reportalo al operador y espera decision.

### 6. Formato de salida

Un `.txt`, saltos de linea CRLF para que los visores de Windows y las previsualizaciones
de chat lo rendericen bien, ancho de linea a 93 columnas con sangria de continuacion, y
nombre de archivo descriptivo que se lea solo en una lista de adjuntos.

El encabezado lleva cinco cosas, y ninguna es opcional:

```
<TITULO DE LA JUNTA>
Meeting transcript, <fecha>

Recording length      <mm:ss leido del reproductor>
Transcript coverage   <inicio> to <fin>, <n> cues, no gaps
Speakers              <en orden de volumen de intervencion>

HOW THIS WAS PRODUCED
<como se capturo, incluida la parte incomoda: que la UI de descarga lo niega
 y que la cola se recupero manejando el video>

<que nada se edito, resumio ni reordeno>

<los errores de transcripcion de la plataforma, con ejemplos reales del documento>

<que el artefacto autoritativo es el export nativo, y esto es copia de trabajo>
```

**La linea de errores de transcripcion es la que salva al lector.** Estas plataformas
destrozan nombres propios y siglas de forma consistente dentro de un mismo documento. Si
no lo adviertes, alguien va a creer que existe un cliente llamado como la sigla mal
transcrita. Extrae los ejemplos del documento real, no de una lista generica.

## Anti-patrones

| Anti-patron | Por que falla |
|---|---|
| Reportar cues como cobertura | Suena completo y no lo es. Solo el chequeo de minutos vacios contra la duracion real es evidencia. |
| Insistir con mas scroll | El reset vive dentro del control de la plataforma. Mas eventos de scroll no lo mueven. |
| Recapturar por un `referrer` distinto | Misma grabacion. Compara el `id`, no la URL completa. |
| Entregar sin barrido de datos sensibles | El transcript va a un canal. Una vez enviado no se recoge. |
| Omitir la advertencia de errores de transcripcion | El lector toma una sigla mal transcrita por un dato. |
| Presentarlo como el transcript oficial | Es texto rescatado del DOM. El oficial es el export nativo, y hay que decirlo. |
| Saltos de linea LF en un txt para Windows | Se ve como una sola linea gigante en el visor por defecto. |

## Cierre: el transcript no es el entregable

Un transcript entregado y nada mas obliga al humano a leer 20 minutos de texto para saber
si algo cambio. Cierra siempre diciendo **que se decidio y que contradice** lo que estaba
escrito antes, citando timestamp y hablante. Ese es el valor; el archivo es el respaldo.
Mismo principio que `capture-ends-with-triage`.

## Relacionado

`stream-transcript-dom-scrape` es el mecanismo de captura por plataforma, incluida la
tecnica de seek y sus recibos. `transcribe` es para audio sin transcript previo.
`capture-ends-with-triage` es la razon del cierre de arriba. `phi-aware-rag-ingestion`
recibe el texto cuando va a un indice.

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.