@@ -638,85 +638,166 @@ import '../styles/global.css';
638638
639639<script >
640640 // ── Terminal typewriter ──────────────────────────────────────
641- const LINES = [
641+ // Sequences are shuffled on every page load so returning visitors
642+ // are likely to see a different order.
643+ type Line = { p: string; t: string; c: string };
644+ const SEQUENCES: Line[][] = [
642645 // ── Auth check ────────────────────────────────
643- { p: '❯ ', t: 'dg whoami', c: '' },
644- { p: '', t: '✓ Authenticated', c: '#13ef95' },
645- { p: '', t: ' Profile: default', c: '#949498' },
646- { p: '', t: ' API Key: sk-3a8f****c91b (keyring)', c: '#7a7a7e' },
647- { p: '', t: ' Project ID: a1b2c3d4-5e6f-7890-abcd', c: '#7a7a7e' },
648- { p: '', t: '', c: '' },
646+ [
647+ { p: '❯ ', t: 'dg whoami', c: '' },
648+ { p: '', t: '✓ Authenticated', c: '#13ef95' },
649+ { p: '', t: ' Profile: default', c: '#949498' },
650+ { p: '', t: ' API Key: sk-3a8f****c91b (keyring)', c: '#7a7a7e' },
651+ { p: '', t: ' Project ID: a1b2c3d4-5e6f-7890-abcd', c: '#7a7a7e' },
652+ { p: '', t: '', c: '' },
653+ ],
649654 // ── Projects ──────────────────────────────────
650- { p: '❯ ', t: 'dg projects --list', c: '' },
651- { p: '', t: 'Found 2 project(s):', c: '#13ef95' },
652- { p: '', t: ' • my-deepgram-project a1b2c3d4-5e6f-7890', c: '#949498' },
653- { p: '', t: ' • staging-env b2c3d4e5-6f78-90ab', c: '#7a7a7e' },
654- { p: '', t: '', c: '' },
655+ [
656+ { p: '❯ ', t: 'dg projects --list', c: '' },
657+ { p: '', t: 'Found 2 project(s):', c: '#13ef95' },
658+ { p: '', t: ' • my-deepgram-project a1b2c3d4-5e6f-7890', c: '#949498' },
659+ { p: '', t: ' • staging-env b2c3d4e5-6f78-90ab', c: '#7a7a7e' },
660+ { p: '', t: '', c: '' },
661+ ],
655662 // ── File transcription with diarization ───────
656- { p: '❯ ', t: 'dg transcribe keynote.mp3 --diarize --model nova-3', c: '' },
657- { p: '', t: '✓ Transcribing · nova-3', c: '#13ef95' },
658- { p: '', t: 'Welcome to our annual product keynote. This year', c: '#949498' },
659- { p: '', t: 'we ship the fastest model yet.', c: '#7a7a7e' },
660- { p: '', t: '', c: '' },
663+ [
664+ { p: '❯ ', t: 'dg listen keynote.mp3 --diarize --model nova-3', c: '' },
665+ { p: '', t: '✓ Transcribing · nova-3', c: '#13ef95' },
666+ { p: '', t: 'Welcome to our annual product keynote. This year', c: '#949498' },
667+ { p: '', t: 'we ship the fastest model yet.', c: '#7a7a7e' },
668+ { p: '', t: '', c: '' },
669+ ],
661670 // ── URL transcription ─────────────────────────
662- { p: '❯ ', t: 'dg transcribe https://cdn.example.com/podcast.mp3', c: '' },
663- { p: '', t: 'Fetching remote audio…', c: '#949498' },
664- { p: '', t: '"This week on Developer Stories: the future of speech AI."', c: '#edede2' },
665- { p: '', t: '', c: '' },
671+ [
672+ { p: '❯ ', t: 'dg listen https://cdn.example.com/podcast.mp3', c: '' },
673+ { p: '', t: 'Fetching remote audio…', c: '#949498' },
674+ { p: '', t: '"This week on Developer Stories: the future of speech AI."', c: '#edede2' },
675+ { p: '', t: '', c: '' },
676+ ],
666677 // ── JSON pipeline ─────────────────────────────
667- { p: '❯ ', t: "dg transcribe standup.mp3 -o json | jq '.results.channels[0].alternatives[0].transcript'", c: '' },
668- { p: '', t: '"Blocked on auth; need a review on PR 847 by EOD."', c: '#edede2' },
669- { p: '', t: '', c: '' },
678+ [
679+ { p: '❯ ', t: "dg listen standup.mp3 -o json | jq '.results.channels[0].alternatives[0].transcript'", c: '' },
680+ { p: '', t: '"Blocked on auth; need a review on PR 847 by EOD."', c: '#edede2' },
681+ { p: '', t: '', c: '' },
682+ ],
670683 // ── Text intelligence ─────────────────────────
671- { p: '❯ ', t: 'dg read earnings.txt --sentiment --summarize --topics', c: '' },
672- { p: '', t: 'Analyzing text...', c: '#949498' },
673- { p: '', t: 'Summary: Revenue beat forecasts by 23%; guidance raised.', c: '#edede2' },
674- { p: '', t: 'Sentiment: positive (0.96)', c: '#13ef95' },
675- { p: '', t: 'Topics: • earnings (98%) • revenue growth (91%)', c: '#7a7a7e' },
676- { p: '', t: '', c: '' },
684+ [
685+ { p: '❯ ', t: 'dg read earnings.txt --sentiment --summarize --topics', c: '' },
686+ { p: '', t: 'Analyzing text...', c: '#949498' },
687+ { p: '', t: 'Summary: Revenue beat forecasts by 23%; guidance raised.', c: '#edede2' },
688+ { p: '', t: 'Sentiment: positive (0.96)', c: '#13ef95' },
689+ { p: '', t: 'Topics: • earnings (98%) • revenue growth (91%)', c: '#7a7a7e' },
690+ { p: '', t: '', c: '' },
691+ ],
677692 // ── TTS → pipe to player ──────────────────────
678- { p: '❯ ', t: 'dg speak "Hello from Deepgram" | ffplay -nodisp -autoexit -', c: '' },
679- { p: '', t: '✓ Synthesizing · aura-2-asteria-en', c: '#13ef95' },
680- { p: '', t: '▶ Streaming 3.2s of audio…', c: '#949498' },
681- { p: '', t: '', c: '' },
693+ [
694+ { p: '❯ ', t: 'dg speak "Hello from Deepgram" | ffplay -nodisp -autoexit -', c: '' },
695+ { p: '', t: '✓ Synthesizing · aura-2-asteria-en', c: '#13ef95' },
696+ { p: '', t: '▶ Streaming 3.2s of audio…', c: '#949498' },
697+ { p: '', t: '', c: '' },
698+ ],
682699 // ── Live mic transcription ────────────────────
683- { p: '❯ ', t: 'dg listen --mic --model nova-3 --interim', c: '' },
684- { p: '', t: '✓ Listening on Built-in Microphone…', c: '#13ef95' },
685- { p: '', t: '"The quick brown fox jumps over the lazy dog."', c: '#edede2' },
686- { p: '', t: '', c: '' },
700+ [
701+ { p: '❯ ', t: 'dg listen --mic --model nova-3 --interim', c: '' },
702+ { p: '', t: '✓ Listening on Built-in Microphone…', c: '#13ef95' },
703+ { p: '', t: '"The quick brown fox jumps over the lazy dog."', c: '#edede2' },
704+ { p: '', t: '', c: '' },
705+ ],
706+ // ── WebVTT captions from file ─────────────────
707+ [
708+ { p: '❯ ', t: 'dg listen keynote.mp3 --webvtt --save-to keynote.vtt', c: '' },
709+ { p: '', t: 'WEBVTT', c: '#13ef95' },
710+ { p: '', t: '', c: '' },
711+ { p: '', t: '00:00:00.080 --> 00:00:03.220', c: '#949498' },
712+ { p: '', t: 'Welcome to our annual product keynote.', c: '#edede2' },
713+ { p: '', t: '', c: '' },
714+ ],
715+ // ── SRT with diarization ──────────────────────
716+ [
717+ { p: '❯ ', t: 'dg listen interview.mp3 --srt --diarize', c: '' },
718+ { p: '', t: '1', c: '#7a7a7e' },
719+ { p: '', t: '00:00:00,080 --> 00:00:05,320', c: '#949498' },
720+ { p: '', t: '[speaker 0]', c: '#13ef95' },
721+ { p: '', t: 'Thanks for joining us today.', c: '#edede2' },
722+ { p: '', t: '', c: '' },
723+ ],
724+ // ── Live mic WebVTT captions ──────────────────
725+ [
726+ { p: '❯ ', t: 'dg listen --mic --webvtt', c: '' },
727+ { p: '', t: '✓ Listening on Built-in Microphone…', c: '#13ef95' },
728+ { p: '', t: 'WEBVTT', c: '#949498' },
729+ { p: '', t: '', c: '' },
730+ { p: '', t: '00:00:00.240 --> 00:00:03.180', c: '#7a7a7e' },
731+ { p: '', t: 'The quick brown fox jumps over the lazy dog.', c: '#edede2' },
732+ { p: '', t: '', c: '' },
733+ ],
734+ // ── ffmpeg pipe → SRT ─────────────────────────
735+ [
736+ { p: '❯ ', t: 'ffmpeg -i video.mp4 -f s16le -ar 16000 -ac 1 - | dg listen --encoding linear16 --srt', c: '' },
737+ { p: '', t: '✓ Streaming stdin · nova-3', c: '#13ef95' },
738+ { p: '', t: '1', c: '#7a7a7e' },
739+ { p: '', t: '00:00:00,420 --> 00:00:04,180', c: '#949498' },
740+ { p: '', t: 'Welcome to this week\'s engineering all-hands.', c: '#edede2' },
741+ { p: '', t: '', c: '' },
742+ ],
687743 // ── Explore models ────────────────────────────
688- { p: '❯ ', t: 'dg models --type stt', c: '' },
689- { p: '', t: ' nova-3 STT en 2024-01-24', c: '#edede2' },
690- { p: '', t: ' nova-2 STT en 2024-01-09', c: '#949498' },
691- { p: '', t: ' enhanced STT en 2022-05-09', c: '#7a7a7e' },
692- { p: '', t: ' 24 model(s) found', c: '#7a7a7e' },
693- { p: '', t: '', c: '' },
744+ [
745+ { p: '❯ ', t: 'dg models --type stt', c: '' },
746+ { p: '', t: ' nova-3 STT en 2024-01-24', c: '#edede2' },
747+ { p: '', t: ' nova-2 STT en 2024-01-09', c: '#949498' },
748+ { p: '', t: ' enhanced STT en 2022-05-09', c: '#7a7a7e' },
749+ { p: '', t: ' 24 model(s) found', c: '#7a7a7e' },
750+ { p: '', t: '', c: '' },
751+ ],
694752 // ── Key management (dry run) ──────────────────
695- { p: '❯ ', t: "dg keys --create --comment 'ci-pipeline' --dry-run", c: '' },
696- { p: '', t: 'Dry run — no changes made', c: '#949498' },
697- { p: '', t: " Would create key: comment='ci-pipeline' scopes=member", c: '#7a7a7e' },
698- { p: '', t: '', c: '' },
753+ [
754+ { p: '❯ ', t: "dg keys --create --comment 'ci-pipeline' --dry-run", c: '' },
755+ { p: '', t: 'Dry run — no changes made', c: '#949498' },
756+ { p: '', t: " Would create key: comment='ci-pipeline' scopes=member", c: '#7a7a7e' },
757+ { p: '', t: '', c: '' },
758+ ],
699759 // ── Usage stats ───────────────────────────────
700- { p: '❯ ', t: 'dg usage --last-month', c: '' },
701- { p: '', t: 'Usage Summary (2026-02-01 to 2026-02-28):', c: '#13ef95' },
702- { p: '', t: ' Total Requests: 1,247', c: '#949498' },
703- { p: '', t: ' Total Duration: 42.30 hours', c: '#7a7a7e' },
704- { p: '', t: '', c: '' },
760+ [
761+ { p: '❯ ', t: 'dg usage --last-month', c: '' },
762+ { p: '', t: 'Usage Summary (2026-02-01 to 2026-02-28):', c: '#13ef95' },
763+ { p: '', t: ' Total Requests: 1,247', c: '#949498' },
764+ { p: '', t: ' Total Duration: 42.30 hours', c: '#7a7a7e' },
765+ { p: '', t: '', c: '' },
766+ ],
705767 // ── Debug: failed requests ────────────────────
706- { p: '❯ ', t: 'dg requests --status failed --endpoint listen', c: '' },
707- { p: '', t: ' /v1/listen streaming failed 2026-03-28 a3f8c1d2…', c: '#949498' },
708- { p: '', t: ' 1 request(s) shown', c: '#7a7a7e' },
709- { p: '', t: '', c: '' },
768+ [
769+ { p: '❯ ', t: 'dg requests --status failed --endpoint listen', c: '' },
770+ { p: '', t: ' /v1/listen streaming failed 2026-03-28 a3f8c1d2…', c: '#949498' },
771+ { p: '', t: ' 1 request(s) shown', c: '#7a7a7e' },
772+ { p: '', t: '', c: '' },
773+ ],
710774 // ── Raw API call ──────────────────────────────
711- { p: '❯ ', t: "dg api /v1/projects --jq '.projects[0].name'", c: '' },
712- { p: '', t: '"my-deepgram-project"', c: '#edede2' },
713- { p: '', t: '', c: '' },
775+ [
776+ { p: '❯ ', t: "dg api /v1/projects --jq '.projects[0].name'", c: '' },
777+ { p: '', t: '"my-deepgram-project"', c: '#edede2' },
778+ { p: '', t: '', c: '' },
779+ ],
714780 // ── MCP server for AI editors ─────────────────
715- { p: '❯ ', t: 'dg mcp --transport sse --port 8000', c: '' },
716- { p: '', t: 'Starting MCP proxy (sse) on 127.0.0.1:8000…', c: '#13ef95' },
717- { p: '', t: ' Add to your AI editor: http://127.0.0.1:8000/sse', c: '#949498' },
781+ [
782+ { p: '❯ ', t: 'dg mcp --transport sse --port 8000', c: '' },
783+ { p: '', t: 'Starting MCP proxy (sse) on 127.0.0.1:8000…', c: '#13ef95' },
784+ { p: '', t: ' Add to your AI editor: http://127.0.0.1:8000/sse', c: '#949498' },
785+ { p: '', t: '', c: '' },
786+ ],
718787 ];
719788
789+ // Fisher-Yates shuffle — runs once on page load
790+ for (let i = SEQUENCES.length - 1; i > 0; i--) {
791+ const j = Math.floor(Math.random() * (i + 1));
792+ [SEQUENCES[i], SEQUENCES[j]] = [SEQUENCES[j], SEQUENCES[i]];
793+ }
794+
795+ // Flatten sequences into the line-by-line array the typewriter consumes.
796+ // Drop any trailing blank lines from the final sequence so the loop
797+ // resets cleanly without an extra pause.
798+ const LINES: Line[] = SEQUENCES.flat();
799+ while (LINES.length > 0 && LINES[LINES.length - 1].t === '') LINES.pop();
800+
720801 const out = document.getElementById('terminal-output');
721802 let li = 0, ci = 0, cur: HTMLElement | null = null;
722803
0 commit comments