System Dashboard
Auto-refreshes every 10s
{{ dashActiveJobs }}
Active Jobs
{{ dashScripts }}
Scripts
{{ dashOutputs }}
Videos
{{ dashQueue }}
Queued
{{ dashVideoQueue }} pack
·
{{ dashRenderQueue }} render
· {{ dashTtsQueue }} TTS
TTS Queue
| {{ tts.status || 'pending' }} | {{ tts.input?.substring(0, 40) || tts.character || '...' }}{{ (tts.input?.length || 0) > 40 ? '...' : '' }} | {{ tts.character || '' }} |
Active Jobs
No active jobs
{{ job.type }}
{{ job.statusLabel }}
{{ job.target }}
{{ job.phase }}
{{ job.id.slice(0,16) }}…
{{ line.slice(0,100) }}
Recent Scripts
No scripts
| Name | Lines | Status |
|---|---|---|
| {{ s.name }} | {{ s.line_count }} | {{ s.status }} |
Recent Outputs
No outputs
| Name | Size | YT |
|---|---|---|
| {{ o.name }} | {{ fmtSize(o.size) }} | ✓ — |
Channels
No channels
| Channel | Status |
|---|---|
| {{ ch.name }} | ready auth missing |
Queue Items
| ID | Type | Status | Message |
|---|---|---|---|
| {{ q.id.slice(0,8) }}… | {{ q.type }} | {{ q.status }} | {{ q.message }} |
Scripts
No scripts.
{{ s.name }}
Select or create a script.
{{ editorError }}
saving…
✓ saved
save failed
Script Pipeline
Track scripts from generation to video output
Generated
{{ pipelineGenerated.length }}
No scripts generated
{{ s.name }}
{{ s.topic }}
Rendering
{{ pipelineRendering.length }}
Nothing rendering
{{ s.name }}
{{ s.last_log.slice(0,80) }}
job {{ s.job_id.slice(0,8) }}…
Completed
{{ pipelineCompleted.length }}
No completed videos
{{ s.name }}
YouTube ✓
Needs Work
{{ pipelineNeedsWork.length }}
All good!
{{ s.name }}
Generate Script with AI
{{ genDone ? 'Generation log (done)' : 'Live output…' }}
{{ line }}
Generation failed (exit {{ genExitCode }})
Result — {{ genSegments.length }} segments
(edit, then save)
{{ genSavedMsg }}
Generate Video
Live output
{{ line }}
✓ Rendered successfully
✗ Render failed (exit {{ vidExitCode }})
Outputs
No outputs yet.
{{ o.name }}
YT ✓
not uploaded
Select a video.
Manifest ({{ currentOutput.manifest.lines?.length }} lines, {{ fmtDur(currentOutput.manifest.total_duration) }})
| # | Character | Text | Start | Dur |
|---|---|---|---|---|
| {{ line.index+1 }} | {{ line.character }} | {{ line.text }} | {{ line.start?.toFixed(1) }}s | {{ line.duration?.toFixed(1) }}s |
YouTube
{{ currentOutput.manifest.youtube.title }}
{{ currentOutput.manifest.youtube.url }} ↗
{{ currentOutput.manifest.youtube.analytics.views }}
views
{{ currentOutput.manifest.youtube.analytics.average_view_percentage?.toFixed(1) }}%
avg view %
{{ currentOutput.manifest.youtube.analytics.likes }}
likes
{{ currentOutput.manifest.youtube.analytics.comments }}
comments
YouTube Channels
No channels configured.
| Channel | Niche | Privacy | Auth | |
|---|---|---|---|---|
{{ ch.name }} |
{{ ch.niche }} | {{ ch.default_privacy }} | ready needs auth missing secret | {{ expandedChannel===ch.slug ? '▲' : '▼' }} |
|
Authenticate via CLI:
python scripts/channel_manager.py auth {{ ch.slug }}
|
||||
Upload to YouTube
{{ line }}
✓ Upload complete
✗ Upload failed
Analytics
Single Video
Fleet
{{ line }}
{{ anData.views }}
views
{{ anData.average_view_percentage?.toFixed(1) }}%
avg view %
{{ anData.likes }}
likes
{{ fmtDur(anData.average_view_duration_seconds) }}
avg watch time
Retention by line
| # | Character | Text | Start | Watch% | Drop |
|---|---|---|---|---|---|
| {{ line.index+1 }} | {{ line.character }} | {{ line.text }} | {{ line.start?.toFixed(1) }}s | {{ line.watch_ratio != null ? (line.watch_ratio*100).toFixed(0)+'%' : '—' }} | {{ line.drop != null ? (line.drop*100).toFixed(1)+'%' : '—' }} |
{{ fleetText }}
{{ fleetError }}