Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a2ddf4c
Split gui.py and kokoro_engine.py into kokoro_gui/ package
CoffeeMethod Aug 22, 2026
a85b4a9
New: kokoro_gui/engines/
CoffeeMethod Aug 22, 2026
4e10177
New: Dummy engine backend
CoffeeMethod Aug 22, 2026
78ea26f
kokoro_gui/engine/caching.py
CoffeeMethod Aug 22, 2026
171bc15
What was built
CoffeeMethod Aug 22, 2026
9c4c424
The Tk (CustomTkinter) frontend has been fully removed; the app is no…
CoffeeMethod Aug 22, 2026
85d8ce0
What I changed (generation_dock.py, app.py):
CoffeeMethod Aug 22, 2026
0e7ed66
New Audio8 TTS engine (kokoro_gui/engines/audio8_tts.py) — a real, no…
CoffeeMethod Aug 22, 2026
2379120
fixed some errors
CoffeeMethod Aug 23, 2026
ec07292
cacheing
CoffeeMethod Aug 23, 2026
6aabef5
What changed (audio8_tts.py)
CoffeeMethod Aug 23, 2026
ebf5f22
What's new
CoffeeMethod Aug 23, 2026
e53fda4
docs/index.html — 311 lines touched. The big structural change: share…
CoffeeMethod Aug 23, 2026
3532c63
The hour-reset bug: both the elapsed-time and ETA displays formatted …
CoffeeMethod Aug 23, 2026
11723f0
Updated Config to have a better GUI layout.
CoffeeMethod Aug 23, 2026
8dd71f2
updated README.md
CoffeeMethod Aug 23, 2026
caf6405
I fixed the four items in the audit's "Suggested fix order" — the one…
CoffeeMethod Aug 23, 2026
1da9bbc
Added Vosk ASR model and dotenv for path storage
CoffeeMethod Aug 24, 2026
36557e2
fixed PyCharm specific test error.
CoffeeMethod Aug 24, 2026
0452bf4
config_qt.json
CoffeeMethod Aug 24, 2026
8ba63f0
First phase UI overhaul.
CoffeeMethod Aug 24, 2026
587389f
phaze 2 of UI overhaul
CoffeeMethod Aug 24, 2026
8a858c8
phase three of user interface enhancements
CoffeeMethod Aug 24, 2026
194a780
Ph4ze 4 Of U1
CoffeeMethod Aug 24, 2026
e5bbaa2
Step 5 of UI improvement
CoffeeMethod Aug 24, 2026
a30e9ca
DAW-for-text UI redesign: document model, transcript sync, timeline
CoffeeMethod Aug 24, 2026
a1c3fd2
updated readme and docs
CoffeeMethod Aug 24, 2026
6e71294
1. Data model rewrite — models.py, undo.py, serialization.py
CoffeeMethod Aug 27, 2026
c21545d
1. Data model rewrite — models.py, undo.py, serialization.py
CoffeeMethod Aug 27, 2026
ef7db19
Merge remote-tracking branch 'origin/split-Qt6-UI' into split-Qt6-UI
CoffeeMethod Aug 27, 2026
627b6d9
moved settings, possible pipeline init bug
CoffeeMethod Aug 30, 2026
1c4b3dd
UI shell redesign: 2x2 dock grid, seconds timeline, transport, export
CoffeeMethod Sep 12, 2026
cce27df
FX, volume, pitch, normalize and trim are now a read-time stage over …
CoffeeMethod Sep 13, 2026
46b1528
What changed
CoffeeMethod Sep 13, 2026
3781191
Segment keys: one function for the dirty check, the engine and the fi…
CoffeeMethod Sep 13, 2026
ceb4905
.tbaw project bundles
CoffeeMethod Sep 13, 2026
7f2f439
updated docs
CoffeeMethod Sep 13, 2026
740a499
Theme (theme.py). Dark is the default; both palettes are three surfac…
CoffeeMethod Sep 13, 2026
7dff8bc
Prep for 4.0.0-beta.1
CoffeeMethod Sep 13, 2026
8421f31
update pypdf
CoffeeMethod Sep 13, 2026
b1b3d66
Contain bundle audio paths to the project dir; fix the Linux CI leg
CoffeeMethod Sep 13, 2026
627729f
Stop every test Transport at teardown
CoffeeMethod Sep 13, 2026
8064c3f
Close the last two CodeQL path alerts
CoffeeMethod Sep 13, 2026
de97d36
Pin pedalboard to 0.9.23; run CI under -X faulthandler
CoffeeMethod Sep 13, 2026
4186b4e
Updated CI
CoffeeMethod Sep 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copy this file to .env and fill in the values you need. .env itself is
# gitignored - never commit it.

# Folder of an unzipped Vosk speech-recognition model (download one from
# https://alphacephei.com/vosk/models, e.g. vosk-model-small-en-us-0.15),
# used by the Voice Reference dock's "Vosk" auto-transcription engine
# (kokoro_gui/engine/asr.py). Leave unset if you're only using the default
# Audio8-ASR-0.1B engine. You can also set/edit this from the dock itself
# (Browse/Save/Reload next to the Vosk model field) instead of by hand.
VOSK_MODEL_PATH=
16 changes: 16 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Normalize line endings: LF in the repo and on checkout, on every OS.
* text=auto eol=lf

# Windows launcher needs CRLF for cmd.exe.
*.bat text eol=crlf

# Binary assets, never touched by the text filters.
*.png binary
*.jpg binary
*.gif binary
*.wav binary
*.flac binary
*.mp3 binary
*.ogg binary
*.pt binary
*.tbaw binary
80 changes: 80 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Bug report
description: Something crashed, sounded wrong, or didn't do what the docs say.
labels: [bug]
body:
- type: markdown
attributes:
value: |
Installation questions and "how do I" belong in Discussions. This form is for things that are broken.
- type: input
id: version
attributes:
label: KokoroGUI version
description: The "New in" heading at the top of the README, or `kokoro_gui/__init__.py`'s `APP_VERSION`.
placeholder: "4.0.0"
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating system
options:
- Windows
- Linux
- macOS
validations:
required: true
- type: input
id: python
attributes:
label: Python version
placeholder: "3.11.9 (python --version)"
validations:
required: true
- type: dropdown
id: engine
attributes:
label: Engine (Options > Engine)
options:
- Kokoro
- Audio8
- Dummy
- Not engine-related
validations:
required: true
- type: input
id: device
attributes:
label: Device
description: Options > Device, plus the GPU if any.
placeholder: "cuda, RTX 3060 / cpu"
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: What you clicked or typed, in order. If a specific text triggers it, paste the text (or the smallest part that still does).
placeholder: |
1. New project, paste "[Narrator]: Hello."
2. Generate
3. ...
validations:
required: true
- type: textarea
id: expected
attributes:
label: What you expected, and what happened instead
validations:
required: true
- type: textarea
id: traceback
attributes:
label: Traceback or log
description: The terminal output from `python main.py`, if any. Pasted as text, not a screenshot.
render: text
- type: checkboxes
id: checks
attributes:
label: Checks
options:
- label: I ran `pip install -r requirements.txt` on this version before reporting.
- label: The `.tbaw` or text that triggers this is something I can share if asked.
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Questions and help
url: https://github.com/CoffeeMethod/KokoroGUI/discussions
about: Install trouble, "how do I", model and hardware questions.
- name: Security issue
url: https://github.com/CoffeeMethod/KokoroGUI/security/advisories/new
about: Report privately. See SECURITY.md.
29 changes: 29 additions & 0 deletions .github/ISSUE_TEMPLATE/feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Feature request
description: Something the app should do that it doesn't.
labels: [enhancement]
body:
- type: textarea
id: problem
attributes:
label: What are you trying to do?
description: The task, not the button. "Make a two-voice audiobook from an EPUB with chapter breaks" tells us more than "add a chapter button".
validations:
required: true
- type: textarea
id: today
attributes:
label: How do you do it today?
description: The workaround, or "can't".
- type: textarea
id: proposal
attributes:
label: What would you like instead?
description: Optional. If you have a specific design in mind, describe it; if not, the first two answers are enough.
- type: dropdown
id: engine
attributes:
label: Engine, if it matters
options:
- Any
- Kokoro
- Audio8
17 changes: 17 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## What

<!-- One or two sentences. What changes for a user, or for a developer if it's internal. -->

## Why

<!-- The bug or gap. Link the issue if there is one. -->

## How to check it

<!-- What you ran or clicked. `pytest` output counts; a screenshot for anything visual. -->

## Checklist

- [ ] `pytest` passes locally (the fast suite; CI runs it on Windows and Linux)
- [ ] New settings are threaded through `_assemble_config` and `tests/gui_qt/test_qt_config_assembly.py`
- [ ] README's Features list and "New in" section updated if a user can see the change
58 changes: 38 additions & 20 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@ on:
branches: [main]
pull_request:

# The token only ever reads the checkout; nothing here pushes or comments.
permissions:
contents: read

# A new push to the same branch/PR cancels the run it supersedes.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
# Playback goes through playback.py (sounddevice/PortAudio) instead of
# the Windows-only `winsound` module, so kokoro_engine.py/gui.py no
# longer force Windows-only. ubuntu-latest additionally needs:
# - libportaudio2 (system PortAudio lib `sounddevice` dlopens)
# - Xvfb (the GUI suite builds real Tk windows - tests/conftest.py's
# `tts_app` fixture - which needs a display on headless Linux)
# CI runs the engine, DAW model and audio suites only. tests/gui_qt/
# (real QtTTSApp widgets, docks, screenshots) is skipped here and run
# locally with a plain `pytest`; it was the flaky half of every failed
# run. Nothing collected below imports PySide6.QtGui or QtWidgets
# (tests/test_mixer_transport.py needs QtCore only), so the Linux leg
# needs no Qt runtime libraries and no QT_QPA_PLATFORM. It still needs
# libportaudio2, the system PortAudio library `sounddevice` dlopens.
# macos-latest is left out for now (unverified) - see ROADMAP.md's
# "CI expansion" item.
strategy:
Expand All @@ -26,26 +36,34 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.11"
# torch alone is several hundred MB; keyed on both requirements files.
cache: pip
cache-dependency-path: |
requirements.txt
requirements-test.txt

- name: Install PortAudio + Xvfb (Linux)
- name: Install PortAudio (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libportaudio2 xvfb
run: |
sudo apt-get update
sudo apt-get install -y libportaudio2

- name: Install dependencies
run: |
pip install -r requirements.txt
pip install -r requirements-test.txt

- name: Run fast test suite (Linux)
if: runner.os == 'Linux'
run: xvfb-run -a pytest
# Runs the mocked-pipeline suite only (pytest.ini already sets
# `-m "not integration"` by default). No eSpeak NG or model
# download needed. The real-synthesis integration suite
- name: Run non-GUI test suite
# -X faulthandler from interpreter start: pytest's own faulthandler
# only switches on at pytest_configure, after tests/conftest.py
# (and torch, pedalboard with it) has already been imported, so a
# native crash during those imports printed nothing.
# --ignore=tests/gui_qt leaves the Qt suite out (its conftest builds
# the whole app). -p no:pytest-qt keeps the pytest-qt plugin from
# importing QtGui/QtWidgets at configure time, which it does even
# when no test uses qtbot.
run: python -X faulthandler -m pytest --ignore=tests/gui_qt -p no:pytest-qt
# pytest.ini already deselects `integration` and `slow`. No eSpeak
# NG or model download needed. The real-synthesis integration suite
# (`pytest -m integration tests/integration`) is intentionally
# left out of CI - it's slow and pulls model weights. Wrapped in
# xvfb-run so the Tk-based GUI tests have a display to attach to.

- name: Run fast test suite (Windows)
if: runner.os != 'Linux'
run: pytest
# left out of CI - it's slow and pulls model weights.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,14 @@ cython_debug/
/ROADMAP.md
/CLAUDE.md
/tests/output/
/custom_voices/
/cache/
/presets/
/Claude/PLAN_qt_and_engine_abstraction.md
/generation_stats.json
/SECURITY_AUDIT.md
/Claude/
/.claude/
document.json
document.tbaw
config_qt.json
66 changes: 66 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Contributing

Bug reports and pull requests are welcome. Questions go in Discussions, security reports through
the Security tab (see [SECURITY.md](SECURITY.md)).

## Setup

```bash
git clone https://github.com/CoffeeMethod/KokoroGUI.git
cd KokoroGUI
python -m venv .venv && . .venv/Scripts/activate # or .venv/bin/activate
pip install -r requirements.txt -r requirements-test.txt
python main.py
```

Python 3.11 or newer. eSpeak NG is only needed to actually synthesize with Kokoro; the fast test
suite runs without it.

## Tests

```bash
pytest
```

That's the fast suite: the Kokoro pipeline is mocked, playback is mocked, no model download, runs
in well under a minute. The Qt tests run headless (`tests/gui_qt/conftest.py` sets
`QT_QPA_PLATFORM=offscreen`), so no display is needed. CI runs the suite on `windows-latest` and
`ubuntu-latest` without `tests/gui_qt/` (`pytest --ignore=tests/gui_qt -p no:pytest-qt`), so the
GUI tests only run on your machine. Run plain `pytest` before you push.

Two conventions the suite enforces, both from `tests/conftest.py`:

- Test configs come from the `make_config` fixture and have `caching: False`. Only
`tests/test_caching.py` turns caching on; `tests/test_meta_caching_policy.py` fails the run if
another file does.
- Tests never touch the real `custom_voices/` or `cache/` directories or a real audio device. Use
the `isolated_dirs`, `engine` and `fake_pipeline` fixtures rather than patching around them.

GUI tests build a real `QtTTSApp` through the `qt_app` fixture in `tests/gui_qt/conftest.py`,
with the engine replaced by `StubEngine`. Save and Open run on a thread; call
`qt_app.wait_for_project_io()` before asserting on the result.

The integration suite (`pytest -m integration tests/integration -s`) does real synthesis and is
opt-in. It isn't run in CI.

## Pull requests

- Branch from `main`, one change per PR.
- `pytest` green locally before you push (that includes `tests/gui_qt/`, which CI skips). CI has
to pass on both OSes to merge.
- A new setting is threaded through `QtTTSApp._assemble_config` and covered in
`tests/gui_qt/test_qt_config_assembly.py`.
- If a user can see the change, update the README: the Features list, and a bullet under the
current "New in" heading.
- No formatter or linter is configured. Match the style of the file you're in.

## Layout

- `kokoro_engine.py` and `kokoro_gui/engine/` are the synthesis core (mixins per feature area).
- `kokoro_gui/engines/` is the backend interface and the three registered backends (Kokoro,
Audio8, Dummy). Nothing there imports the document model.
- `kokoro_gui/daw/` is the document model: text, clips, tracks, characters, arrangement, dirty
tracking, undo.
- `kokoro_gui/audio/` is the transport, mixer and read-time FX stage.
- `kokoro_gui/qt/` is the PySide6 shell; every panel is a dock under `kokoro_gui/qt/docks/`.
- `docs/` is the GitHub Pages site.
Loading
Loading