{"owner":"huggingface","repo":"speech-to-speech","hasSkills":true,"totalSkillsCount":2,"totalTokensCount":2929,"categories":["root-instruction","project-spec"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","demo/DESIGN.md"],"skills":{"AGENTS.md":"# Repository Instructions\n\n- Never include `codex` in branch names or pull request titles.\n- Never merge a pull request into `main` unless the user explicitly asks the agent to perform the merge and then confirms when asked immediately before the merge. Requests to review, fix, prepare, finish, or get a pull request ready do not count as merge authorization. Once the pull request is ready, report its status and ask for confirmation; merge only after a clear follow-up confirmation.\n- For existing/open pull requests, do not amend, squash, rebase-rewrite, or force-push follow-up changes. Make new commits and push normally unless explicitly asked to rewrite history.\n- Keep release pull requests focused on version metadata and release documentation.\n- Do not commit local build artifacts such as `dist/`, `build/`, or generated wheel/sdist files.\n\n## Publishing to PyPI\n\nPyPI publishing is handled by GitHub Actions in `.github/workflows/publish.yml`. The workflow runs on pushed tags that match `v*`, builds the package with `uv build`, checks the artifacts with `twine check --strict`, and publishes through the configured `pypi` environment.\n\nTo prepare a release:\n\n1. Confirm the intended version is not already published on PyPI.\n2. Bump `version` in `pyproject.toml`.\n3. Bump `__version__` in `src/speech_to_speech/__init__.py`.\n4. Open and merge a pull request with only the release preparation changes.\n\nTo publish after the release PR is merged:\n\n1. Update `main` locally: `git checkout main && git pull origin main`.\n2. Create an annotated tag for the version: `git tag -a vX.Y.Z -m \"Release vX.Y.Z\"`.\n3. Push the tag: `git push origin vX.Y.Z`.\n4. Watch the `Publish` GitHub Actions workflow complete successfully.\n5. Verify the new version appears at `https://pypi.org/project/speech-to-speech/`.\n\nOnly upload manually if the GitHub Actions workflow is unavailable and the maintainers have explicitly chosen that fallback.\n","demo/DESIGN.md":"# Design language\n\nThe reference for keeping this app visually coherent as it grows. Read it before\ntouching `style.css`, `index.html`, or any DOM-building code in `main.js`. Every\nrule here is already live in the codebase — this file explains the *why* so changes\nextend the system instead of drifting from it.\n\n---\n\n## The thesis: color belongs to the voice\n\nThis is a voice app. The one thing in the room that should have color is the thing\nthat is talking. So:\n\n- **The orb** carries saturated color. It glows, and the glow's hue changes with\n  conversational state.\n- **Everything else is monochrome** — a precise cool-grey dark canvas. Surfaces,\n  borders, buttons, panels, the transcript: all greyscale.\n- The **only** exceptions are tiny *role echoes* (a one-word mono label, a small\n  icon) that borrow the orb's state hue so the transcript reads in the same color\n  language the orb speaks. They are accents the size of a word, never fills.\n- **Brand logos keep their own color.** The Hugging Face mark (`#ffd21e`) and the\n  Cerebras mark (`#f15a29`) render in their brand colors in the identity credits and\n  the about panel — a deliberate, owner-approved exception. It applies to those two\n  logos only; do not generalize it to other chrome.\n\nIf you find yourself adding a tinted background, a colored border, or a bright\nbutton anywhere outside the orb, stop — that color almost certainly belongs to the\norb instead, or shouldn't exist.\n\n---\n\n## Color tokens\n\nAll defined in `:root` in `style.css`. Use the variables, never raw hex in rules.\n\n### Canvas (the monochrome world)\n| Token | Value | Use |\n|---|---|---|\n| `--bg` | `#0a0b10` | Page background (a cool near-black) |\n| `--bg-elev` | `#13151c` | Raised surfaces: bubbles, panels, icon buttons |\n| `--bg-elev-2` | `#1b1e29` | Surfaces on surfaces: history bodies, inputs |\n| `--border` | `rgba(255,255,255,.08)` | Default hairline |\n| `--border-strong` | `rgba(255,255,255,.16)` | Emphasised hairline |\n| `--text` | `#f5f6fa` | Primary text; also the *primary button* fill |\n| `--text-dim` | `rgba(245,246,250,.65)` | Secondary text |\n| `--text-faint` | `rgba(245,246,250,.42)` | Captions, labels, footer |\n\n### Voice (the only saturated hues)\nThese are the orb's state colors. They appear on the orb, and as small role echoes\nin the transcript — nowhere else.\n\n| Token | Value | Meaning |\n|---|---|---|\n| `--accent` / `--speaking` | `#8b7dff` violet | Assistant speaking |\n| `--accent-2` / `--listening` | `#22d3ee` cyan | You / listening |\n| `--processing` | `#f59e0b` amber | Thinking / tool call |\n| `--error` | `#ff6a75` | Error |\n| `--success` | `#34d399` | Ready / connected |\n\n### Role echoes (semantic aliases — use these in chat code)\n| Token | Maps to | Where it shows |\n|---|---|---|\n| `--voice-user` | cyan | `YOU` label + user bubble accents |\n| `--voice-assistant` | violet | `ASSISTANT` label + assistant accents |\n| `--voice-tool` | amber | `TOOL CALL` label, wrench icon |\n\n**Why this mapping:** it mirrors the orb exactly — when *you* speak the orb is cyan\n(`state-listening`), when the *assistant* speaks it's violet (`state-ai-speaking`),\nwhen it's working it's amber (`state-processing`). The transcript is a quiet replay\nof the orb's color story.\n\n### Orb state → glow (`.circle.state-*` → `--glow`)\n| State | Glow |\n|---|---|\n| `signed-out` | violet `#8b7dff` |\n| `authenticated` / `ready` | green `#34d399` |\n| `connecting` / `connected` / `starting` | yellow `#facc15` |\n| `listening` / `user-speaking` | cyan (`--listening`) |\n| `processing` | amber (`--processing`) |\n| `ai-speaking` | violet (`--speaking`) |\n| `error` | red (`--error`) |\n\nAdding a new state? Give it a `--glow`, and if it surfaces in the transcript, add a\nmatching `--voice-*` alias rather than a one-off color.\n\n---\n\n## Typography\n\nTwo faces, two jobs. Never reach for a third.\n\n- **Inter** — body and UI. Wordmark, buttons, inputs, panel titles, prose, history\n  message bodies. The workhorse; it should feel neutral and get out of the way.\n- **Geist Mono** (`--font-mono`) — the **machine voice**. Reserved for text the\n  *system* emits or identifiers it reports, never for human prose.\n\n### When mono is correct\nMono signals \"this is the machine talking or naming itself.\" Use it for:\n- the orb's status caption (`.circle-caption`)\n- role eyebrows (`YOU` / `ASSISTANT` / `TOOL CALL`)\n- tool-call names and argument JSON\n- the `·WebSocket` transport tag, bitrate readouts, connection identifiers\n- the empty-state label\n\nMono text is set uppercase with `letter-spacing: ~0.1–0.14em` and weight `500`, so it\nreads as a typed status line, not a headline. Body copy, button labels, and\nexplanatory `small` text stay **Inter** — putting prose in mono breaks the metaphor.\n\nThe font is loaded in `index.html`; the stack falls back to system mono gracefully if\nthe CDN is blocked.\n\n---\n\n## Layout\n\n- **One continuous canvas.** No dividers under the topbar or above the footer, no\n  panel chrome competing with content. The topbar and footer float over the stage.\n  Keep it that way — a new section earns a hairline (`--border`) only if it genuinely\n  needs separating.\n- **The orb is the hero and the center of gravity.** It sits dead-center on the\n  stage. Controls flank it (mic / stop), captions sit beneath. Don't crowd it.\n- **Hairlines, not boxes.** Separation comes from `1px` borders at 8–16% white and\n  from spacing, not from heavy fills or shadows. Shadows are soft and low\n  (`0 4px 18px rgba(0,0,0,.32)`), used only to lift floating elements (bubbles,\n  panels, modal).\n- **Radii:** `--radius-sm: 8px` (buttons, inputs, chips), `--radius-md: 14px`\n  (bubbles, message bodies, modal), `--radius-lg: 22px` (reserved). Pick by element\n  size; don't invent new values.\n- **Two reading surfaces for the transcript:** ephemeral bubbles top-right (desktop\n  only) that log and fade, and a slide-in history panel for review. On phones the\n  bubble stream is dropped and the panel goes full-screen — the panel is the single\n  source of truth there.\n\n---\n\n## Components\n\n- **Buttons.** Default (`.btn`) is a neutral elevated surface. The *primary* button\n  is **near-white on dark** (`--text` fill, `--bg` text) — the highest-contrast thing\n  on the page that *isn't* the orb. There is no colored button; emphasis comes from\n  contrast, not hue.\n- **Icon buttons** (`.icon-btn`) are `36px`, elevated surface, dim icon that brightens\n  on hover. Side controls (`.side-btn`) are circular, collapse to zero size until the\n  session is live (by width on desktop, by height in the mobile column).\n- **Chat bubbles & history messages** share one neutral surface. They are\n  distinguished by **side** (you = left, assistant = right) plus the **mono role\n  label** in the role-echo hue — not by tinted fills. Tool entries use the wrench icon\n  + mono + amber, on the same neutral surface.\n- **Badge** (new-message dot) is monochrome white — a signal, not a color accent.\n- **Focus** is visible and neutral: inputs focus to `--text-dim`; the orb uses a\n  `--glow`-colored outline (it's the orb, so color is allowed).\n\n---\n\n## Motion\n\n- **The orb is audio-reactive, not timer-driven.** Mic RMS (`--audio-level`) and the\n  assistant output level (`--ai-audio-level`) drive scale/opacity at display rate, so\n  every syllable moves it. This is the signature animation — keep new motion\n  subordinate to it.\n- **Quiet by default.** Breathing/glow throbs are slow (1.4–2.4s) and low-contrast.\n  Resist adding scattered micro-animations; an orchestrated moment beats many small\n  ones, and excess motion reads as AI-generated.\n- **First paint is frozen.** `body.booting` disables all transitions until the first\n  frame commits (stripped after one rAF in `main.js`). Anything new that would\n  otherwise animate-in on load must respect this.\n- Honor `prefers-reduced-motion` for any motion you add.\n\n---\n\n## Writing / copy voice\n\n- Sentence case, plain verbs, no filler. Tuned and quiet — match the minimal canvas.\n- Name things by what the user controls, not by the system's internals. A button says\n  exactly what it does, and keeps the same word through the flow.\n- **Empty states invite action** (\"Tap the orb and start talking\"), they don't just\n  set a mood.\n- **Errors state what happened and how to recover**, in the interface's voice — they\n  don't apologize and are never vague.\n- Mono labels are terse identifiers (`YOU`, `TOOL CALL`); prose stays in Inter.\n\n---\n\n## Responsive floor (non-negotiable)\n\nEvery change ships meeting these:\n- Works down to a `360px`-wide phone. The `@media (max-width: 600px)` block already\n  handles the phone layout — extend it, don't fight it.\n- Visible keyboard focus on every interactive element.\n- `prefers-reduced-motion` respected.\n- Tap targets ≥ `44px`; `touch-action: manipulation` on anything tappable.\n\n---\n\n## Before you ship — the mirror check\n\n1. Is every saturated color either on the orb or a word-sized role echo? If a fill or\n   border is colored, remove that accessory.\n2. Is mono used only for machine/system text, and Inter for everything human?\n3. Does any new state have both a `--glow` and (if it appears in chat) a `--voice-*`\n   alias?\n4. Are separations hairlines + spacing, not boxes and heavy shadows?\n5. Did you add motion? Is it quieter than the orb and reduced-motion-safe?\n6. Remove one accessory. The minimal look survives on precision, not addition.\n"},"files":{"AGENTS.md":"# Repository Instructions\n\n- Never include `codex` in branch names or pull request titles.\n- Never merge a pull request into `main` unless the user explicitly asks the agent to perform the merge and then confirms when asked immediately before the merge. Requests to review, fix, prepare, finish, or get a pull request ready do not count as merge authorization. Once the pull request is ready, report its status and ask for confirmation; merge only after a clear follow-up confirmation.\n- For existing/open pull requests, do not amend, squash, rebase-rewrite, or force-push follow-up changes. Make new commits and push normally unless explicitly asked to rewrite history.\n- Keep release pull requests focused on version metadata and release documentation.\n- Do not commit local build artifacts such as `dist/`, `build/`, or generated wheel/sdist files.\n\n## Publishing to PyPI\n\nPyPI publishing is handled by GitHub Actions in `.github/workflows/publish.yml`. The workflow runs on pushed tags that match `v*`, builds the package with `uv build`, checks the artifacts with `twine check --strict`, and publishes through the configured `pypi` environment.\n\nTo prepare a release:\n\n1. Confirm the intended version is not already published on PyPI.\n2. Bump `version` in `pyproject.toml`.\n3. Bump `__version__` in `src/speech_to_speech/__init__.py`.\n4. Open and merge a pull request with only the release preparation changes.\n\nTo publish after the release PR is merged:\n\n1. Update `main` locally: `git checkout main && git pull origin main`.\n2. Create an annotated tag for the version: `git tag -a vX.Y.Z -m \"Release vX.Y.Z\"`.\n3. Push the tag: `git push origin vX.Y.Z`.\n4. Watch the `Publish` GitHub Actions workflow complete successfully.\n5. Verify the new version appears at `https://pypi.org/project/speech-to-speech/`.\n\nOnly upload manually if the GitHub Actions workflow is unavailable and the maintainers have explicitly chosen that fallback.\n","demo/DESIGN.md":"# Design language\n\nThe reference for keeping this app visually coherent as it grows. Read it before\ntouching `style.css`, `index.html`, or any DOM-building code in `main.js`. Every\nrule here is already live in the codebase — this file explains the *why* so changes\nextend the system instead of drifting from it.\n\n---\n\n## The thesis: color belongs to the voice\n\nThis is a voice app. The one thing in the room that should have color is the thing\nthat is talking. So:\n\n- **The orb** carries saturated color. It glows, and the glow's hue changes with\n  conversational state.\n- **Everything else is monochrome** — a precise cool-grey dark canvas. Surfaces,\n  borders, buttons, panels, the transcript: all greyscale.\n- The **only** exceptions are tiny *role echoes* (a one-word mono label, a small\n  icon) that borrow the orb's state hue so the transcript reads in the same color\n  language the orb speaks. They are accents the size of a word, never fills.\n- **Brand logos keep their own color.** The Hugging Face mark (`#ffd21e`) and the\n  Cerebras mark (`#f15a29`) render in their brand colors in the identity credits and\n  the about panel — a deliberate, owner-approved exception. It applies to those two\n  logos only; do not generalize it to other chrome.\n\nIf you find yourself adding a tinted background, a colored border, or a bright\nbutton anywhere outside the orb, stop — that color almost certainly belongs to the\norb instead, or shouldn't exist.\n\n---\n\n## Color tokens\n\nAll defined in `:root` in `style.css`. Use the variables, never raw hex in rules.\n\n### Canvas (the monochrome world)\n| Token | Value | Use |\n|---|---|---|\n| `--bg` | `#0a0b10` | Page background (a cool near-black) |\n| `--bg-elev` | `#13151c` | Raised surfaces: bubbles, panels, icon buttons |\n| `--bg-elev-2` | `#1b1e29` | Surfaces on surfaces: history bodies, inputs |\n| `--border` | `rgba(255,255,255,.08)` | Default hairline |\n| `--border-strong` | `rgba(255,255,255,.16)` | Emphasised hairline |\n| `--text` | `#f5f6fa` | Primary text; also the *primary button* fill |\n| `--text-dim` | `rgba(245,246,250,.65)` | Secondary text |\n| `--text-faint` | `rgba(245,246,250,.42)` | Captions, labels, footer |\n\n### Voice (the only saturated hues)\nThese are the orb's state colors. They appear on the orb, and as small role echoes\nin the transcript — nowhere else.\n\n| Token | Value | Meaning |\n|---|---|---|\n| `--accent` / `--speaking` | `#8b7dff` violet | Assistant speaking |\n| `--accent-2` / `--listening` | `#22d3ee` cyan | You / listening |\n| `--processing` | `#f59e0b` amber | Thinking / tool call |\n| `--error` | `#ff6a75` | Error |\n| `--success` | `#34d399` | Ready / connected |\n\n### Role echoes (semantic aliases — use these in chat code)\n| Token | Maps to | Where it shows |\n|---|---|---|\n| `--voice-user` | cyan | `YOU` label + user bubble accents |\n| `--voice-assistant` | violet | `ASSISTANT` label + assistant accents |\n| `--voice-tool` | amber | `TOOL CALL` label, wrench icon |\n\n**Why this mapping:** it mirrors the orb exactly — when *you* speak the orb is cyan\n(`state-listening`), when the *assistant* speaks it's violet (`state-ai-speaking`),\nwhen it's working it's amber (`state-processing`). The transcript is a quiet replay\nof the orb's color story.\n\n### Orb state → glow (`.circle.state-*` → `--glow`)\n| State | Glow |\n|---|---|\n| `signed-out` | violet `#8b7dff` |\n| `authenticated` / `ready` | green `#34d399` |\n| `connecting` / `connected` / `starting` | yellow `#facc15` |\n| `listening` / `user-speaking` | cyan (`--listening`) |\n| `processing` | amber (`--processing`) |\n| `ai-speaking` | violet (`--speaking`) |\n| `error` | red (`--error`) |\n\nAdding a new state? Give it a `--glow`, and if it surfaces in the transcript, add a\nmatching `--voice-*` alias rather than a one-off color.\n\n---\n\n## Typography\n\nTwo faces, two jobs. Never reach for a third.\n\n- **Inter** — body and UI. Wordmark, buttons, inputs, panel titles, prose, history\n  message bodies. The workhorse; it should feel neutral and get out of the way.\n- **Geist Mono** (`--font-mono`) — the **machine voice**. Reserved for text the\n  *system* emits or identifiers it reports, never for human prose.\n\n### When mono is correct\nMono signals \"this is the machine talking or naming itself.\" Use it for:\n- the orb's status caption (`.circle-caption`)\n- role eyebrows (`YOU` / `ASSISTANT` / `TOOL CALL`)\n- tool-call names and argument JSON\n- the `·WebSocket` transport tag, bitrate readouts, connection identifiers\n- the empty-state label\n\nMono text is set uppercase with `letter-spacing: ~0.1–0.14em` and weight `500`, so it\nreads as a typed status line, not a headline. Body copy, button labels, and\nexplanatory `small` text stay **Inter** — putting prose in mono breaks the metaphor.\n\nThe font is loaded in `index.html`; the stack falls back to system mono gracefully if\nthe CDN is blocked.\n\n---\n\n## Layout\n\n- **One continuous canvas.** No dividers under the topbar or above the footer, no\n  panel chrome competing with content. The topbar and footer float over the stage.\n  Keep it that way — a new section earns a hairline (`--border`) only if it genuinely\n  needs separating.\n- **The orb is the hero and the center of gravity.** It sits dead-center on the\n  stage. Controls flank it (mic / stop), captions sit beneath. Don't crowd it.\n- **Hairlines, not boxes.** Separation comes from `1px` borders at 8–16% white and\n  from spacing, not from heavy fills or shadows. Shadows are soft and low\n  (`0 4px 18px rgba(0,0,0,.32)`), used only to lift floating elements (bubbles,\n  panels, modal).\n- **Radii:** `--radius-sm: 8px` (buttons, inputs, chips), `--radius-md: 14px`\n  (bubbles, message bodies, modal), `--radius-lg: 22px` (reserved). Pick by element\n  size; don't invent new values.\n- **Two reading surfaces for the transcript:** ephemeral bubbles top-right (desktop\n  only) that log and fade, and a slide-in history panel for review. On phones the\n  bubble stream is dropped and the panel goes full-screen — the panel is the single\n  source of truth there.\n\n---\n\n## Components\n\n- **Buttons.** Default (`.btn`) is a neutral elevated surface. The *primary* button\n  is **near-white on dark** (`--text` fill, `--bg` text) — the highest-contrast thing\n  on the page that *isn't* the orb. There is no colored button; emphasis comes from\n  contrast, not hue.\n- **Icon buttons** (`.icon-btn`) are `36px`, elevated surface, dim icon that brightens\n  on hover. Side controls (`.side-btn`) are circular, collapse to zero size until the\n  session is live (by width on desktop, by height in the mobile column).\n- **Chat bubbles & history messages** share one neutral surface. They are\n  distinguished by **side** (you = left, assistant = right) plus the **mono role\n  label** in the role-echo hue — not by tinted fills. Tool entries use the wrench icon\n  + mono + amber, on the same neutral surface.\n- **Badge** (new-message dot) is monochrome white — a signal, not a color accent.\n- **Focus** is visible and neutral: inputs focus to `--text-dim`; the orb uses a\n  `--glow`-colored outline (it's the orb, so color is allowed).\n\n---\n\n## Motion\n\n- **The orb is audio-reactive, not timer-driven.** Mic RMS (`--audio-level`) and the\n  assistant output level (`--ai-audio-level`) drive scale/opacity at display rate, so\n  every syllable moves it. This is the signature animation — keep new motion\n  subordinate to it.\n- **Quiet by default.** Breathing/glow throbs are slow (1.4–2.4s) and low-contrast.\n  Resist adding scattered micro-animations; an orchestrated moment beats many small\n  ones, and excess motion reads as AI-generated.\n- **First paint is frozen.** `body.booting` disables all transitions until the first\n  frame commits (stripped after one rAF in `main.js`). Anything new that would\n  otherwise animate-in on load must respect this.\n- Honor `prefers-reduced-motion` for any motion you add.\n\n---\n\n## Writing / copy voice\n\n- Sentence case, plain verbs, no filler. Tuned and quiet — match the minimal canvas.\n- Name things by what the user controls, not by the system's internals. A button says\n  exactly what it does, and keeps the same word through the flow.\n- **Empty states invite action** (\"Tap the orb and start talking\"), they don't just\n  set a mood.\n- **Errors state what happened and how to recover**, in the interface's voice — they\n  don't apologize and are never vague.\n- Mono labels are terse identifiers (`YOU`, `TOOL CALL`); prose stays in Inter.\n\n---\n\n## Responsive floor (non-negotiable)\n\nEvery change ships meeting these:\n- Works down to a `360px`-wide phone. The `@media (max-width: 600px)` block already\n  handles the phone layout — extend it, don't fight it.\n- Visible keyboard focus on every interactive element.\n- `prefers-reduced-motion` respected.\n- Tap targets ≥ `44px`; `touch-action: manipulation` on anything tappable.\n\n---\n\n## Before you ship — the mirror check\n\n1. Is every saturated color either on the orb or a word-sized role echo? If a fill or\n   border is colored, remove that accessory.\n2. Is mono used only for machine/system text, and Inter for everything human?\n3. Does any new state have both a `--glow` and (if it appears in chat) a `--voice-*`\n   alias?\n4. Are separations hairlines + spacing, not boxes and heavy shadows?\n5. Did you add motion? Is it quieter than the orb and reduced-motion-safe?\n6. Remove one accessory. The minimal look survives on precision, not addition.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/huggingface/speech-to-speech/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# Repository Instructions\n\n- Never include `codex` in branch names or pull request titles.\n- Never merge a pull request into `main` unless the user explicitly asks the agent to perform the merge and then confirms when asked immediately before the merge. Requests to review, fix, prepare, finish, or get a pull request ready do not count as merge authorization. Once the pull request is ready, report its status and ask for confirmation; merge only after a clear follow-up confirmation.\n- For existing/open pull requests, do not amend, squash, rebase-rewrite, or force-push follow-up changes. Make new commits and push normally unless explicitly asked to rewrite history.\n- Keep release pull requests focused on version metadata and release documentation.\n- Do not commit local build artifacts such as `dist/`, `build/`, or generated wheel/sdist files.\n\n## Publishing to PyPI\n\nPyPI publishing is handled by GitHub Actions in `.github/workflows/publish.yml`. The workflow runs on pushed tags that match `v*`, builds the package with `uv build`, checks the artifacts with `twine check --strict`, and publishes through the configured `pypi` environment.\n\nTo prepare a release:\n\n1. Confirm the intended version is not already published on PyPI.\n2. Bump `version` in `pyproject.toml`.\n3. Bump `__version__` in `src/speech_to_speech/__init__.py`.\n4. Open and merge a pull request with only the release preparation changes.\n\nTo publish after the release PR is merged:\n\n1. Update `main` locally: `git checkout main && git pull origin main`.\n2. Create an annotated tag for the version: `git tag -a vX.Y.Z -m \"Release vX.Y.Z\"`.\n3. Push the tag: `git push origin vX.Y.Z`.\n4. Watch the `Publish` GitHub Actions workflow complete successfully.\n5. Verify the new version appears at `https://pypi.org/project/speech-to-speech/`.\n\nOnly upload manually if the GitHub Actions workflow is unavailable and the maintainers have explicitly chosen that fallback.\n","isInternal":false,"tokens":430,"sizeBytes":1939},{"name":"DESIGN.md","path":"demo/DESIGN.md","rawUrl":"https://raw.githubusercontent.com/huggingface/speech-to-speech/HEAD/demo/DESIGN.md","title":"demo - UI Design System & Style Tokens","category":"project-spec","format":"markdown","content":"# Design language\n\nThe reference for keeping this app visually coherent as it grows. Read it before\ntouching `style.css`, `index.html`, or any DOM-building code in `main.js`. Every\nrule here is already live in the codebase — this file explains the *why* so changes\nextend the system instead of drifting from it.\n\n---\n\n## The thesis: color belongs to the voice\n\nThis is a voice app. The one thing in the room that should have color is the thing\nthat is talking. So:\n\n- **The orb** carries saturated color. It glows, and the glow's hue changes with\n  conversational state.\n- **Everything else is monochrome** — a precise cool-grey dark canvas. Surfaces,\n  borders, buttons, panels, the transcript: all greyscale.\n- The **only** exceptions are tiny *role echoes* (a one-word mono label, a small\n  icon) that borrow the orb's state hue so the transcript reads in the same color\n  language the orb speaks. They are accents the size of a word, never fills.\n- **Brand logos keep their own color.** The Hugging Face mark (`#ffd21e`) and the\n  Cerebras mark (`#f15a29`) render in their brand colors in the identity credits and\n  the about panel — a deliberate, owner-approved exception. It applies to those two\n  logos only; do not generalize it to other chrome.\n\nIf you find yourself adding a tinted background, a colored border, or a bright\nbutton anywhere outside the orb, stop — that color almost certainly belongs to the\norb instead, or shouldn't exist.\n\n---\n\n## Color tokens\n\nAll defined in `:root` in `style.css`. Use the variables, never raw hex in rules.\n\n### Canvas (the monochrome world)\n| Token | Value | Use |\n|---|---|---|\n| `--bg` | `#0a0b10` | Page background (a cool near-black) |\n| `--bg-elev` | `#13151c` | Raised surfaces: bubbles, panels, icon buttons |\n| `--bg-elev-2` | `#1b1e29` | Surfaces on surfaces: history bodies, inputs |\n| `--border` | `rgba(255,255,255,.08)` | Default hairline |\n| `--border-strong` | `rgba(255,255,255,.16)` | Emphasised hairline |\n| `--text` | `#f5f6fa` | Primary text; also the *primary button* fill |\n| `--text-dim` | `rgba(245,246,250,.65)` | Secondary text |\n| `--text-faint` | `rgba(245,246,250,.42)` | Captions, labels, footer |\n\n### Voice (the only saturated hues)\nThese are the orb's state colors. They appear on the orb, and as small role echoes\nin the transcript — nowhere else.\n\n| Token | Value | Meaning |\n|---|---|---|\n| `--accent` / `--speaking` | `#8b7dff` violet | Assistant speaking |\n| `--accent-2` / `--listening` | `#22d3ee` cyan | You / listening |\n| `--processing` | `#f59e0b` amber | Thinking / tool call |\n| `--error` | `#ff6a75` | Error |\n| `--success` | `#34d399` | Ready / connected |\n\n### Role echoes (semantic aliases — use these in chat code)\n| Token | Maps to | Where it shows |\n|---|---|---|\n| `--voice-user` | cyan | `YOU` label + user bubble accents |\n| `--voice-assistant` | violet | `ASSISTANT` label + assistant accents |\n| `--voice-tool` | amber | `TOOL CALL` label, wrench icon |\n\n**Why this mapping:** it mirrors the orb exactly — when *you* speak the orb is cyan\n(`state-listening`), when the *assistant* speaks it's violet (`state-ai-speaking`),\nwhen it's working it's amber (`state-processing`). The transcript is a quiet replay\nof the orb's color story.\n\n### Orb state → glow (`.circle.state-*` → `--glow`)\n| State | Glow |\n|---|---|\n| `signed-out` | violet `#8b7dff` |\n| `authenticated` / `ready` | green `#34d399` |\n| `connecting` / `connected` / `starting` | yellow `#facc15` |\n| `listening` / `user-speaking` | cyan (`--listening`) |\n| `processing` | amber (`--processing`) |\n| `ai-speaking` | violet (`--speaking`) |\n| `error` | red (`--error`) |\n\nAdding a new state? Give it a `--glow`, and if it surfaces in the transcript, add a\nmatching `--voice-*` alias rather than a one-off color.\n\n---\n\n## Typography\n\nTwo faces, two jobs. Never reach for a third.\n\n- **Inter** — body and UI. Wordmark, buttons, inputs, panel titles, prose, history\n  message bodies. The workhorse; it should feel neutral and get out of the way.\n- **Geist Mono** (`--font-mono`) — the **machine voice**. Reserved for text the\n  *system* emits or identifiers it reports, never for human prose.\n\n### When mono is correct\nMono signals \"this is the machine talking or naming itself.\" Use it for:\n- the orb's status caption (`.circle-caption`)\n- role eyebrows (`YOU` / `ASSISTANT` / `TOOL CALL`)\n- tool-call names and argument JSON\n- the `·WebSocket` transport tag, bitrate readouts, connection identifiers\n- the empty-state label\n\nMono text is set uppercase with `letter-spacing: ~0.1–0.14em` and weight `500`, so it\nreads as a typed status line, not a headline. Body copy, button labels, and\nexplanatory `small` text stay **Inter** — putting prose in mono breaks the metaphor.\n\nThe font is loaded in `index.html`; the stack falls back to system mono gracefully if\nthe CDN is blocked.\n\n---\n\n## Layout\n\n- **One continuous canvas.** No dividers under the topbar or above the footer, no\n  panel chrome competing with content. The topbar and footer float over the stage.\n  Keep it that way — a new section earns a hairline (`--border`) only if it genuinely\n  needs separating.\n- **The orb is the hero and the center of gravity.** It sits dead-center on the\n  stage. Controls flank it (mic / stop), captions sit beneath. Don't crowd it.\n- **Hairlines, not boxes.** Separation comes from `1px` borders at 8–16% white and\n  from spacing, not from heavy fills or shadows. Shadows are soft and low\n  (`0 4px 18px rgba(0,0,0,.32)`), used only to lift floating elements (bubbles,\n  panels, modal).\n- **Radii:** `--radius-sm: 8px` (buttons, inputs, chips), `--radius-md: 14px`\n  (bubbles, message bodies, modal), `--radius-lg: 22px` (reserved). Pick by element\n  size; don't invent new values.\n- **Two reading surfaces for the transcript:** ephemeral bubbles top-right (desktop\n  only) that log and fade, and a slide-in history panel for review. On phones the\n  bubble stream is dropped and the panel goes full-screen — the panel is the single\n  source of truth there.\n\n---\n\n## Components\n\n- **Buttons.** Default (`.btn`) is a neutral elevated surface. The *primary* button\n  is **near-white on dark** (`--text` fill, `--bg` text) — the highest-contrast thing\n  on the page that *isn't* the orb. There is no colored button; emphasis comes from\n  contrast, not hue.\n- **Icon buttons** (`.icon-btn`) are `36px`, elevated surface, dim icon that brightens\n  on hover. Side controls (`.side-btn`) are circular, collapse to zero size until the\n  session is live (by width on desktop, by height in the mobile column).\n- **Chat bubbles & history messages** share one neutral surface. They are\n  distinguished by **side** (you = left, assistant = right) plus the **mono role\n  label** in the role-echo hue — not by tinted fills. Tool entries use the wrench icon\n  + mono + amber, on the same neutral surface.\n- **Badge** (new-message dot) is monochrome white — a signal, not a color accent.\n- **Focus** is visible and neutral: inputs focus to `--text-dim`; the orb uses a\n  `--glow`-colored outline (it's the orb, so color is allowed).\n\n---\n\n## Motion\n\n- **The orb is audio-reactive, not timer-driven.** Mic RMS (`--audio-level`) and the\n  assistant output level (`--ai-audio-level`) drive scale/opacity at display rate, so\n  every syllable moves it. This is the signature animation — keep new motion\n  subordinate to it.\n- **Quiet by default.** Breathing/glow throbs are slow (1.4–2.4s) and low-contrast.\n  Resist adding scattered micro-animations; an orchestrated moment beats many small\n  ones, and excess motion reads as AI-generated.\n- **First paint is frozen.** `body.booting` disables all transitions until the first\n  frame commits (stripped after one rAF in `main.js`). Anything new that would\n  otherwise animate-in on load must respect this.\n- Honor `prefers-reduced-motion` for any motion you add.\n\n---\n\n## Writing / copy voice\n\n- Sentence case, plain verbs, no filler. Tuned and quiet — match the minimal canvas.\n- Name things by what the user controls, not by the system's internals. A button says\n  exactly what it does, and keeps the same word through the flow.\n- **Empty states invite action** (\"Tap the orb and start talking\"), they don't just\n  set a mood.\n- **Errors state what happened and how to recover**, in the interface's voice — they\n  don't apologize and are never vague.\n- Mono labels are terse identifiers (`YOU`, `TOOL CALL`); prose stays in Inter.\n\n---\n\n## Responsive floor (non-negotiable)\n\nEvery change ships meeting these:\n- Works down to a `360px`-wide phone. The `@media (max-width: 600px)` block already\n  handles the phone layout — extend it, don't fight it.\n- Visible keyboard focus on every interactive element.\n- `prefers-reduced-motion` respected.\n- Tap targets ≥ `44px`; `touch-action: manipulation` on anything tappable.\n\n---\n\n## Before you ship — the mirror check\n\n1. Is every saturated color either on the orb or a word-sized role echo? If a fill or\n   border is colored, remove that accessory.\n2. Is mono used only for machine/system text, and Inter for everything human?\n3. Does any new state have both a `--glow` and (if it appears in chat) a `--voice-*`\n   alias?\n4. Are separations hairlines + spacing, not boxes and heavy shadows?\n5. Did you add motion? Is it quieter than the orb and reduced-motion-safe?\n6. Remove one accessory. The minimal look survives on precision, not addition.\n","isInternal":false,"tokens":2499,"sizeBytes":9430}],"systemPromptSnippet":"<yakaai_skills repo=\"huggingface/speech-to-speech\">\n<!-- File: AGENTS.md (Tokens: ~430 | Category: root-instruction) -->\n# Repository Instructions\n\n- Never include `codex` in branch names or pull request titles.\n- Never merge a pull request into `main` unless the user explicitly asks the agent to perform the merge and then confirms when asked immediately before the merge. Requests to review, fix, prepare, finish, or get a pull request ready do not count as merge authorization. Once the pull request is ready, report its status and ask for confirmation; merge only after a clear follow-up confirmation.\n- For existing/open pull requests, do not amend, squash, rebase-rewrite, or force-push follow-up changes. Make new commits and push normally unless explicitly asked to rewrite history.\n- Keep release pull requests focused on version metadata and release documentation.\n- Do not commit local build artifacts such as `dist/`, `build/`, or generated wheel/sdist files.\n\n## Publishing to PyPI\n\nPyPI publishing is handled by GitHub Actions in `.github/workflows/publish.yml`. The workflow runs on pushed tags that match `v*`, builds the package with `uv build`, checks the artifacts with `twine check --strict`, and publishes through the configured `pypi` environment.\n\nTo prepare a release:\n\n1. Confirm the intended version is not already published on PyPI.\n2. Bump `version` in `pyproject.toml`.\n3. Bump `__version__` in `src/speech_to_speech/__init__.py`.\n4. Open and merge a pull request with only the release preparation changes.\n\nTo publish after the release PR is merged:\n\n1. Update `main` locally: `git checkout main && git pull origin main`.\n2. Create an annotated tag for the version: `git tag -a vX.Y.Z -m \"Release vX.Y.Z\"`.\n3. Push the tag: `git push origin vX.Y.Z`.\n4. Watch the `Publish` GitHub Actions workflow complete successfully.\n5. Verify the new version appears at `https://pypi.org/project/speech-to-speech/`.\n\nOnly upload manually if the GitHub Actions workflow is unavailable and the maintainers have explicitly chosen that fallback.\n\n<!-- File: demo/DESIGN.md (Tokens: ~2499 | Category: project-spec) -->\n# Design language\n\nThe reference for keeping this app visually coherent as it grows. Read it before\ntouching `style.css`, `index.html`, or any DOM-building code in `main.js`. Every\nrule here is already live in the codebase — this file explains the *why* so changes\nextend the system instead of drifting from it.\n\n---\n\n## The thesis: color belongs to the voice\n\nThis is a voice app. The one thing in the room that should have color is the thing\nthat is talking. So:\n\n- **The orb** carries saturated color. It glows, and the glow's hue changes with\n  conversational state.\n- **Everything else is monochrome** — a precise cool-grey dark canvas. Surfaces,\n  borders, buttons, panels, the transcript: all greyscale.\n- The **only** exceptions are tiny *role echoes* (a one-word mono label, a small\n  icon) that borrow the orb's state hue so the transcript reads in the same color\n  language the orb speaks. They are accents the size of a word, never fills.\n- **Brand logos keep their own color.** The Hugging Face mark (`#ffd21e`) and the\n  Cerebras mark (`#f15a29`) render in their brand colors in the identity credits and\n  the about panel — a deliberate, owner-approved exception. It applies to those two\n  logos only; do not generalize it to other chrome.\n\nIf you find yourself adding a tinted background, a colored border, or a bright\nbutton anywhere outside the orb, stop — that color almost certainly belongs to the\norb instead, or shouldn't exist.\n\n---\n\n## Color tokens\n\nAll defined in `:root` in `style.css`. Use the variables, never raw hex in rules.\n\n### Canvas (the monochrome world)\n| Token | Value | Use |\n|---|---|---|\n| `--bg` | `#0a0b10` | Page background (a cool near-black) |\n| `--bg-elev` | `#13151c` | Raised surfaces: bubbles, panels, icon buttons |\n| `--bg-elev-2` | `#1b1e29` | Surfaces on surfaces: history bodies, inputs |\n| `--border` | `rgba(255,255,255,.08)` | Default hairline |\n| `--border-strong` | `rgba(255,255,255,.16)` | Emphasised hairline |\n| `--text` | `#f5f6fa` | Primary text; also the *primary button* fill |\n| `--text-dim` | `rgba(245,246,250,.65)` | Secondary text |\n| `--text-faint` | `rgba(245,246,250,.42)` | Captions, labels, footer |\n\n### Voice (the only saturated hues)\nThese are the orb's state colors. They appear on the orb, and as small role echoes\nin the transcript — nowhere else.\n\n| Token | Value | Meaning |\n|---|---|---|\n| `--accent` / `--speaking` | `#8b7dff` violet | Assistant speaking |\n| `--accent-2` / `--listening` | `#22d3ee` cyan | You / listening |\n| `--processing` | `#f59e0b` amber | Thinking / tool call |\n| `--error` | `#ff6a75` | Error |\n| `--success` | `#34d399` | Ready / connected |\n\n### Role echoes (semantic aliases — use these in chat code)\n| Token | Maps to | Where it shows |\n|---|---|---|\n| `--voice-user` | cyan | `YOU` label + user bubble accents |\n| `--voice-assistant` | violet | `ASSISTANT` label + assistant accents |\n| `--voice-tool` | amber | `TOOL CALL` label, wrench icon |\n\n**Why this mapping:** it mirrors the orb exactly — when *you* speak the orb is cyan\n(`state-listening`), when the *assistant* speaks it's violet (`state-ai-speaking`),\nwhen it's working it's amber (`state-processing`). The transcript is a quiet replay\nof the orb's color story.\n\n### Orb state → glow (`.circle.state-*` → `--glow`)\n| State | Glow |\n|---|---|\n| `signed-out` | violet `#8b7dff` |\n| `authenticated` / `ready` | green `#34d399` |\n| `connecting` / `connected` / `starting` | yellow `#facc15` |\n| `listening` / `user-speaking` | cyan (`--listening`) |\n| `processing` | amber (`--processing`) |\n| `ai-speaking` | violet (`--speaking`) |\n| `error` | red (`--error`) |\n\nAdding a new state? Give it a `--glow`, and if it surfaces in the transcript, add a\nmatching `--voice-*` alias rather than a one-off color.\n\n---\n\n## Typography\n\nTwo faces, two jobs. Never reach for a third.\n\n- **Inter** — body and UI. Wordmark, buttons, inputs, panel titles, prose, history\n  message bodies. The workhorse; it should feel neutral and get out of the way.\n- **Geist Mono** (`--font-mono`) — the **machine voice**. Reserved for text the\n  *system* emits or identifiers it reports, never for human prose.\n\n### When mono is correct\nMono signals \"this is the machine talking or naming itself.\" Use it for:\n- the orb's status caption (`.circle-caption`)\n- role eyebrows (`YOU` / `ASSISTANT` / `TOOL CALL`)\n- tool-call names and argument JSON\n- the `·WebSocket` transport tag, bitrate readouts, connection identifiers\n- the empty-state label\n\nMono text is set uppercase with `letter-spacing: ~0.1–0.14em` and weight `500`, so it\nreads as a typed status line, not a headline. Body copy, button labels, and\nexplanatory `small` text stay **Inter** — putting prose in mono breaks the metaphor.\n\nThe font is loaded in `index.html`; the stack falls back to system mono gracefully if\nthe CDN is blocked.\n\n---\n\n## Layout\n\n- **One continuous canvas.** No dividers under the topbar or above the footer, no\n  panel chrome competing with content. The topbar and footer float over the stage.\n  Keep it that way — a new section earns a hairline (`--border`) only if it genuinely\n  needs separating.\n- **The orb is the hero and the center of gravity.** It sits dead-center on the\n  stage. Controls flank it (mic / stop), captions sit beneath. Don't crowd it.\n- **Hairlines, not boxes.** Separation comes from `1px` borders at 8–16% white and\n  from spacing, not from heavy fills or shadows. Shadows are soft and low\n  (`0 4px 18px rgba(0,0,0,.32)`), used only to lift floating elements (bubbles,\n  panels, modal).\n- **Radii:** `--radius-sm: 8px` (buttons, inputs, chips), `--radius-md: 14px`\n  (bubbles, message bodies, modal), `--radius-lg: 22px` (reserved). Pick by element\n  size; don't invent new values.\n- **Two reading surfaces for the transcript:** ephemeral bubbles top-right (desktop\n  only) that log and fade, and a slide-in history panel for review. On phones the\n  bubble stream is dropped and the panel goes full-screen — the panel is the single\n  source of truth there.\n\n---\n\n## Components\n\n- **Buttons.** Default (`.btn`) is a neutral elevated surface. The *primary* button\n  is **near-white on dark** (`--text` fill, `--bg` text) — the highest-contrast thing\n  on the page that *isn't* the orb. There is no colored button; emphasis comes from\n  contrast, not hue.\n- **Icon buttons** (`.icon-btn`) are `36px`, elevated surface, dim icon that brightens\n  on hover. Side controls (`.side-btn`) are circular, collapse to zero size until the\n  session is live (by width on desktop, by height in the mobile column).\n- **Chat bubbles & history messages** share one neutral surface. They are\n  distinguished by **side** (you = left, assistant = right) plus the **mono role\n  label** in the role-echo hue — not by tinted fills. Tool entries use the wrench icon\n  + mono + amber, on the same neutral surface.\n- **Badge** (new-message dot) is monochrome white — a signal, not a color accent.\n- **Focus** is visible and neutral: inputs focus to `--text-dim`; the orb uses a\n  `--glow`-colored outline (it's the orb, so color is allowed).\n\n---\n\n## Motion\n\n- **The orb is audio-reactive, not timer-driven.** Mic RMS (`--audio-level`) and the\n  assistant output level (`--ai-audio-level`) drive scale/opacity at display rate, so\n  every syllable moves it. This is the signature animation — keep new motion\n  subordinate to it.\n- **Quiet by default.** Breathing/glow throbs are slow (1.4–2.4s) and low-contrast.\n  Resist adding scattered micro-animations; an orchestrated moment beats many small\n  ones, and excess motion reads as AI-generated.\n- **First paint is frozen.** `body.booting` disables all transitions until the first\n  frame commits (stripped after one rAF in `main.js`). Anything new that would\n  otherwise animate-in on load must respect this.\n- Honor `prefers-reduced-motion` for any motion you add.\n\n---\n\n## Writing / copy voice\n\n- Sentence case, plain verbs, no filler. Tuned and quiet — match the minimal canvas.\n- Name things by what the user controls, not by the system's internals. A button says\n  exactly what it does, and keeps the same word through the flow.\n- **Empty states invite action** (\"Tap the orb and start talking\"), they don't just\n  set a mood.\n- **Errors state what happened and how to recover**, in the interface's voice — they\n  don't apologize and are never vague.\n- Mono labels are terse identifiers (`YOU`, `TOOL CALL`); prose stays in Inter.\n\n---\n\n## Responsive floor (non-negotiable)\n\nEvery change ships meeting these:\n- Works down to a `360px`-wide phone. The `@media (max-width: 600px)` block already\n  handles the phone layout — extend it, don't fight it.\n- Visible keyboard focus on every interactive element.\n- `prefers-reduced-motion` respected.\n- Tap targets ≥ `44px`; `touch-action: manipulation` on anything tappable.\n\n---\n\n## Before you ship — the mirror check\n\n1. Is every saturated color either on the orb or a word-sized role echo? If a fill or\n   border is colored, remove that accessory.\n2. Is mono used only for machine/system text, and Inter for everything human?\n3. Does any new state have both a `--glow` and (if it appears in chat) a `--voice-*`\n   alias?\n4. Are separations hairlines + spacing, not boxes and heavy shadows?\n5. Did you add motion? Is it quieter than the orb and reduced-motion-safe?\n6. Remove one accessory. The minimal look survives on precision, not addition.\n</yakaai_skills>"}