textflowkit 0.1.11__tar.gz → 0.1.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {textflowkit-0.1.11 → textflowkit-0.1.12}/CHANGELOG.md +57 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/PKG-INFO +132 -10
- {textflowkit-0.1.11 → textflowkit-0.1.12}/README.md +131 -9
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/adapters.md +70 -4
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/architecture.md +63 -1
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/index.html +70 -10
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/install.md +57 -4
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/release-checklist.md +11 -5
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/roadmap.md +9 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/streaming.md +4 -4
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/user-manual.md +149 -9
- textflowkit-0.1.12/packaging/windows/README.md +71 -0
- textflowkit-0.1.12/packaging/windows/THIRD-PARTY-NOTICES.txt +34 -0
- textflowkit-0.1.12/packaging/windows/assets.lock.json +56 -0
- textflowkit-0.1.12/packaging/windows/launch.py +140 -0
- textflowkit-0.1.12/packaging/windows/source-materials.json +20 -0
- textflowkit-0.1.12/packaging/windows/textflowkit.iss +77 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/pyproject.toml +2 -1
- textflowkit-0.1.12/scripts/build_windows_installer.py +160 -0
- textflowkit-0.1.12/scripts/prepare_windows_payload.py +992 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/__init__.py +1 -1
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/service.py +3 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/streaming_process.py +4 -3
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/whistle.py +3 -0
- textflowkit-0.1.12/src/textflowkit/core/windows_process.py +24 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/sources/acquire.py +4 -1
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/app.py +101 -0
- textflowkit-0.1.12/src/textflowkit/ui/cleanup.py +306 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/launcher.py +3 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/static/app.css +7 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/static/app.js +6 -0
- textflowkit-0.1.12/src/textflowkit/ui/static/cleanup.js +151 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/static/index.html +23 -0
- textflowkit-0.1.12/tests/test_ui_cleanup.py +452 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_packaging.py +5 -2
- textflowkit-0.1.12/tests/test_windows_installer.py +512 -0
- textflowkit-0.1.12/tests/test_windows_payload.py +413 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.dockerignore +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.env.example +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.gitattributes +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.github/dependabot.yml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.github/workflows/ci.yml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.github/workflows/publish-pypi.yml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.gitignore +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/.pre-commit-config.yaml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/CONTRIBUTING.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/Dockerfile +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/LEGAL.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/LICENSE +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/SECURITY.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/compose.yaml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/.nojekyll +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/404.html +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/assets/architecture-overview.svg +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/assets/live-streaming-flow.svg +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/assets/local-ui-flow.svg +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/assets/whistle-resume.svg +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/site-deployment.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/docs/sources.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/scripts/fetch_published_fonts.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/scripts/smoke_installed_wheel.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/scripts/smoke_live_youtube.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/scripts/verify_readme_release.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/scripts/verify_release_ci.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/scripts/verify_release_versions.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/scripts/write_release_manifest.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/adapters/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/adapters/http_server.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/adapters/mcp_server.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/adapters/streaming_ws.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/assets/README.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/assets/selftest-speech.wav +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/cli.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/batch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/bind.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/cancel.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/checkpoint.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/diarize.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/engine.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/executor.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/jobs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/model.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/paths.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/pipeline.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/retrieval.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/runner.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/sqlite_store.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/startup.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/stream_worker.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/streaming.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/streaming_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/streaming_events.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/submission.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/timeutil.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/translate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/core/whistle_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/_cue_layout.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/_cue_text.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/_rename_excl.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/_rename_noreplace.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/docx.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/markdown.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/pdf.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/srt.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/txt.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/render/vtt.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/sources/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/sources/detect.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/sources/scratch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/capabilities.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/ownership.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/paths.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/security.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/static/streaming-capture-worklet.js +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/static/streaming-example.html +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/src/textflowkit/ui/uploads.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/ollama_stub.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_acquire.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_adapters.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_admission_ownership.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_atomic_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_atomic_resume_aba.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_batch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_batch_item_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_batch_resume_shared.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_bind.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cancellation_finalization.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_checkpoint.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_checkpoint_single_copy.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cli.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cli_batch_feedback.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cli_owning_recovery.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cli_resume_batch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cli_stage_feedback.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cli_stdout_format.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_confined_decoder_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_confined_indirect_media.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_confined_resume_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_container_example.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_cue_layout.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_diarize.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_diarize_example_flags.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_diarize_token_docs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_docx_publication_identity.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_done_output_integrity.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_empty_formats_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_engine_adapters.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_engine_cache.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_engine_faster.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_engine_quiet.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_executor.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_executor_store_failure.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_export.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_export_file_mode.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_export_preflight.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_faster_whisper_docs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_fetch_published_fonts.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_font_notices.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_http_host_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_http_trusted_proxy.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_job_progress.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_jobs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_landing_commands.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_landing_page.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_legal_summary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_linux_no_hardlink.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_live_smoke_script.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_macos_no_hardlink.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_mcp_batch_cookie_docs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_mcp_http_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_mcp_protocol_cleanliness.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_mcp_terminal_guidance.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_mcp_tool_descriptions.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_mcp_work_root.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_model.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_partial_output_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_partial_pdf_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_paths.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_pipeline_integrity.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_pipeline_resume_setup.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_production_browser_cookies.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_publish_ci_gate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_publish_fonts_wiring.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_publish_manifest_wiring.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_publish_workflow_gate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_readme_layout.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_readme_release_guard.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_release_boundaries.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_release_manifest.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_release_surfaces.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_render.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_retrieval.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_sdist_allowlist.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_service_profile.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_site_not_found.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_sources.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_stage_reuse_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_startup_recovery.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_stdio_protocol.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_browser_lifecycle.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_core.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_example.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_repairs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_transport.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_u5_repairs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_streaming_ui_integration.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_submission.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_submission_validation.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_translate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_translate_completeness.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_assets_and_capabilities.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_consoleless_logging.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_existing_routes_unchanged.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_launcher.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_ownership_and_shutdown.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_real_serve.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_security.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_submission_and_download.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_ui_uploads.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_verify_release_versions.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_whistle_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_whistle_defaults.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_whistle_engine.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_whistle_job_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.12}/tests/test_windows_no_hardlink.py +0 -0
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.1.12 — 2026-10-17
|
|
4
|
+
|
|
5
|
+
Core: 0.1.12; unchanged optional fonts: 0.1.6. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available.
|
|
6
|
+
|
|
7
|
+
### Optional local UI proofreading (v0.1.12)
|
|
8
|
+
|
|
9
|
+
- Add explicit post-transcription local Ollama proofreading with an installed-tag
|
|
10
|
+
picker; prefer `qwen3.5:9b` only when installed (size/performance fit unverified),
|
|
11
|
+
otherwise require selection.
|
|
12
|
+
No model downloads, cloud tags, paid provider, telemetry or new package dependency.
|
|
13
|
+
- Preserve original jobs and exports; persist a separate original-hash-bound AI
|
|
14
|
+
variant with provider/model/time provenance, source segment IDs/timestamps, no
|
|
15
|
+
inherited word alignment, comparison/original-only views and corrected TXT/copy.
|
|
16
|
+
- Bound background work and validate complete JSON/segment coverage atomically.
|
|
17
|
+
One cleanup at a time; fail without partial output. Normal shutdown drains work;
|
|
18
|
+
interrupted leases expire. AI corrections require human review.
|
|
19
|
+
|
|
20
|
+
- Validation history: the first cold full-UI attempt ended in a generic error; a
|
|
21
|
+
later hot 39-segment run returned zero edits despite clear spelling errors.
|
|
22
|
+
Final cold run (model explicitly unloaded first) completed all 39 segments in
|
|
23
|
+
three chunks with four changed segments at 2026-10-16 17:39:52 UTC. The original
|
|
24
|
+
SQLite JSON/source and IDs/timestamps matched; visible side-by-side review and
|
|
25
|
+
corrected TXT save were verified, with the saved file hash matching the variant.
|
|
26
|
+
This proves workflow completion for one run, not accuracy; “fundamental” and
|
|
27
|
+
“victims” were plausible guesses not verified against audio. Review against audio.
|
|
28
|
+
|
|
29
|
+
### Native Windows installer
|
|
30
|
+
|
|
31
|
+
- Package the existing local browser UI in a native per-user installer for core
|
|
32
|
+
v0.1.12. Built and tested locally; public EXE publication remains gated on
|
|
33
|
+
corresponding-source compliance review. No public installer link is available.
|
|
34
|
+
- Bundle: private embeddable CPython, the UI and HTTP, export, and
|
|
35
|
+
streaming dependencies, the pinned Whistle model and runtime, and ffmpeg,
|
|
36
|
+
ffprobe, and Node. The installer is designed to need no separate Python, WSL,
|
|
37
|
+
or Docker installation.
|
|
38
|
+
- Prebundled Whistle assets and media binaries mean local file jobs need no
|
|
39
|
+
first-use asset download. URL media still needs network access. The default
|
|
40
|
+
Whistle engine supports only these seven advertised languages: `en`, `de`,
|
|
41
|
+
`fr`, `es`, `it`, `nl`, and `pl`.
|
|
42
|
+
- Per-user setup with a Start Menu entry and optional desktop shortcut; launch
|
|
43
|
+
starts the loopback server and opens the existing UI in the browser. It normally
|
|
44
|
+
needs no administrator rights, changes no global `PATH`, and has no automatic
|
|
45
|
+
updates.
|
|
46
|
+
- Keep UI data outside the app install directory and preserve it on upgrade and
|
|
47
|
+
uninstall. Stop server and wait before upgrade or uninstall; the candidate will
|
|
48
|
+
block while it is running rather than force-kill active jobs. Stop server drains
|
|
49
|
+
jobs, so cancel one first if it should not finish.
|
|
50
|
+
- Do not bundle optional `openai-whisper` or diarization dependencies; their
|
|
51
|
+
documented optional paths remain available through the Python package. Bundled
|
|
52
|
+
streaming dependencies do not change the opt-in default; physical browser
|
|
53
|
+
microphone capture remains unverified.
|
|
54
|
+
- The installer bundle includes third-party license and notice files,
|
|
55
|
+
including FFmpeg LGPL notices and corresponding-source information. Verify
|
|
56
|
+
exact notices and source-distribution details against final binaries before
|
|
57
|
+
publication.
|
|
58
|
+
- The candidate is unsigned, so Windows may show a SmartScreen warning.
|
|
59
|
+
|
|
3
60
|
## v0.1.11 — 2026-10-06
|
|
4
61
|
|
|
5
62
|
Optional native live streaming supports **Windows x86_64 only**. Core version:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: textflowkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: Cross-platform media transcription toolkit: URL or file in, timestamped transcripts and subtitle files out.
|
|
5
5
|
Project-URL: Homepage, https://www.textflowkit.org/
|
|
6
6
|
Project-URL: Issues, https://github.com/scottconverse/textflowkit/issues
|
|
@@ -73,7 +73,7 @@ Cross-platform media transcription toolkit. **One core, one CLI, thin adapters.*
|
|
|
73
73
|
[User manual](https://github.com/scottconverse/textflowkit/blob/main/docs/user-manual.md) ·
|
|
74
74
|
[Developer and integration manual](https://github.com/scottconverse/textflowkit/blob/main/docs/adapters.md)
|
|
75
75
|
|
|
76
|
-
**Current release: [v0.1.
|
|
76
|
+
**Current release: [v0.1.12](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.12).**
|
|
77
77
|
|
|
78
78
|
The [static site deployment](https://github.com/scottconverse/textflowkit/blob/main/docs/site-deployment.md) is hosted on Cloudflare
|
|
79
79
|
Pages. GitHub remains the source and CI host; the website does not run the
|
|
@@ -134,7 +134,7 @@ DOCX and PDF are available through the optional `export` extra.
|
|
|
134
134
|
|
|
135
135
|
## Architecture
|
|
136
136
|
|
|
137
|
-
 sit above one core that acquires and decodes media, transcribes with the default Whistle engine or an explicitly selected openai-whisper, keeps job state and resume checkpoints in an optional SQLite store, adds optional speaker or translation postprocessing, and publishes TXT, SRT, VTT, JSON, Markdown, and optional DOCX/PDF exports.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/architecture-overview.svg)
|
|
138
138
|
|
|
139
139
|
The design principle is **one shared core, thin doors**. Everything of substance
|
|
140
140
|
lives in the core; the interfaces are thin — the local browser UI is a fifth door
|
|
@@ -158,7 +158,7 @@ see [docs/architecture.md](https://github.com/scottconverse/textflowkit/blob/mai
|
|
|
158
158
|
|
|
159
159
|
## Live microphone streaming (opt-in)
|
|
160
160
|
|
|
161
|
-
In v0.1.
|
|
161
|
+
In v0.1.12, live streaming supports **Windows x86_64 only**. When
|
|
162
162
|
`TEXTFLOWKIT_STREAMING=1` is set, the developer HTTP app serves a `/stream`
|
|
163
163
|
WebSocket and the local UI serves `/api/stream`, both transcribing a live microphone
|
|
164
164
|
as you speak. A **runnable, self-hosted browser example** ships at
|
|
@@ -167,7 +167,7 @@ as you speak. A **runnable, self-hosted browser example** ships at
|
|
|
167
167
|
No CDN, no analytics, no external fetch. Requires the `streaming` extra:
|
|
168
168
|
|
|
169
169
|
```bash
|
|
170
|
-
python -m pip install "textflowkit[streaming]==0.1.
|
|
170
|
+
python -m pip install "textflowkit[streaming]==0.1.12"
|
|
171
171
|
```
|
|
172
172
|
|
|
173
173
|
It is **off by default** — with the switch unset the endpoint does not exist — and
|
|
@@ -233,6 +233,38 @@ installs `textflowkit-fonts` for offline multilingual PDF rendering:
|
|
|
233
233
|
python -m pip install 'textflowkit[export]'
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
+
## Windows desktop installer (v0.1.12; public EXE pending)
|
|
237
|
+
|
|
238
|
+
An installer for the existing local browser workspace accompanies core v0.1.12. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available. The Python package remains supported for developers and integrations.
|
|
239
|
+
|
|
240
|
+
The candidate is designed to run without a separately installed Python, WSL, or
|
|
241
|
+
Docker. Its bundle includes a private embeddable CPython runtime, the
|
|
242
|
+
browser UI and HTTP, export, and streaming dependencies, the pinned Whistle model
|
|
243
|
+
and runtime, and ffmpeg, ffprobe, and Node. The setup installs per user,
|
|
244
|
+
creates a Start Menu shortcut, and offers an optional desktop shortcut. Opening
|
|
245
|
+
the shortcut will start the local server and open the existing browser UI at
|
|
246
|
+
localhost. It is designed to need no administrator rights in normal use, change
|
|
247
|
+
no global `PATH`, and avoid automatic updates.
|
|
248
|
+
|
|
249
|
+
The pinned Whistle assets and media binaries are prebundled, so local file jobs
|
|
250
|
+
need no first-use asset download. URL sources still need their normal network
|
|
251
|
+
access. The default Whistle engine supports only these seven advertised languages:
|
|
252
|
+
`en`, `de`, `fr`, `es`, `it`, `nl`, and `pl`. Optional `openai-whisper` and diarization dependencies are not
|
|
253
|
+
bundled; those features remain documented for the Python package when separately
|
|
254
|
+
installed and configured. Streaming dependencies are bundled, but live streaming
|
|
255
|
+
remains opt-in and physical browser microphone capture has not been verified.
|
|
256
|
+
|
|
257
|
+
The candidate is designed to keep UI data outside the application install
|
|
258
|
+
directory and preserve it on upgrades and uninstall. Stop the UI server with
|
|
259
|
+
**Stop server** and wait for it to exit before upgrading or uninstalling; the
|
|
260
|
+
installer will block while it is running rather than force-killing active jobs.
|
|
261
|
+
Cancel a job first if it should not drain to completion. The bundle also
|
|
262
|
+
includes third-party license and notice files, including FFmpeg's LGPL notices
|
|
263
|
+
and corresponding-source information. Check exact notices and source-distribution
|
|
264
|
+
details against the final bundled binaries before publication. The candidate is
|
|
265
|
+
unsigned, so Windows may show a SmartScreen warning. See the [installer candidate
|
|
266
|
+
notes](docs/install.md#windows-desktop-installer-v0112-public-exe-pending).
|
|
267
|
+
|
|
236
268
|
## Python API
|
|
237
269
|
|
|
238
270
|
The same pipeline used by the CLI and adapters is available to Python callers:
|
|
@@ -328,7 +360,7 @@ textflowkit export ./transcript.json --format vtt
|
|
|
328
360
|
needs no PyTorch, so a fresh `pip install textflowkit` stays small and pulls no
|
|
329
361
|
torch; `openai-whisper` is an explicitly selectable opt-in engine.
|
|
330
362
|
|
|
331
|
-
, each core runs as one owned child with forced telemetry-off flags, a partial checkpoint is written after each core, and a resume validates the source and decoded-WAV hashes then re-runs only the unfinished cores.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/whistle-resume.svg)
|
|
332
364
|
|
|
333
365
|
- **CPU only, no torch.** It runs a pinned native binary and downloads one pinned
|
|
334
366
|
model on first use. Naming a GPU device is refused rather than silently
|
|
@@ -439,7 +471,7 @@ its own beyond the `http` extra. It ships with the core package as of v0.1.10:
|
|
|
439
471
|
a regular install of the current release carries it.
|
|
440
472
|
|
|
441
473
|
```bash
|
|
442
|
-
python -m pip install 'textflowkit[http,export]==0.1.
|
|
474
|
+
python -m pip install 'textflowkit[http,export]==0.1.12'
|
|
443
475
|
textflowkit-ui
|
|
444
476
|
```
|
|
445
477
|
|
|
@@ -510,7 +542,10 @@ browser interface share the job contract without blocking a request.
|
|
|
510
542
|
|
|
511
543
|
## Status
|
|
512
544
|
|
|
513
|
-
**v0.1.
|
|
545
|
+
**v0.1.12 release.** Adds optional UI-only local Ollama proofreading and native
|
|
546
|
+
Windows installer packaging; public EXE distribution remains gated on unresolved
|
|
547
|
+
corresponding-source compliance review, with no public installer download link.
|
|
548
|
+
Existing optional live streaming provides a transport-neutral
|
|
514
549
|
`StreamingSession` Python API, incremental transcript events, and authenticated
|
|
515
550
|
loopback WebSockets (`/stream` on the developer HTTP API and `/api/stream` on the
|
|
516
551
|
local UI), with a packaged browser microphone example. The native live capability
|
|
@@ -554,7 +589,7 @@ MCP speech, seven-format exports and completed resume; the v0.1.8 runtime fixes
|
|
|
554
589
|
were independently checked through fresh-process CLI restart probes, real SQLite
|
|
555
590
|
setup-failure tests, and the full Windows test suite. Those checks are not new
|
|
556
591
|
individual-harness receipts. That is the previous releases' record, not evidence
|
|
557
|
-
for v0.1.
|
|
592
|
+
for v0.1.12.
|
|
558
593
|
|
|
559
594
|
The v0.1.6 release was the post-v0.1.5 review repair set: security hardening
|
|
560
595
|
for media acquisition and the HTTP and MCP adapters, safer subtitle wrapping and
|
|
@@ -573,7 +608,7 @@ and both [core](https://pypi.org/project/textflowkit/0.1.6/) and
|
|
|
573
608
|
[fonts](https://pypi.org/project/textflowkit-fonts/0.1.6/) PyPI projects are
|
|
574
609
|
live — that is the v0.1.6 release's evidence, not a receipt for a later release.
|
|
575
610
|
Everything from here to the end of this section is the v0.1.6 release's
|
|
576
|
-
historical record as published: it is not re-verified for v0.1.
|
|
611
|
+
historical record as published: it is not re-verified for v0.1.12, whose separate release evidence is not supplied by these historical paragraphs.
|
|
577
612
|
Merged-main CI passed 16/16 on the tagged commit; the published wheel and
|
|
578
613
|
sdist digests match the GitHub release assets and their SHA-256 list; and a fresh
|
|
579
614
|
Windows Python 3.12 install of `textflowkit[export,mcp,http]==0.1.6` from PyPI
|
|
@@ -610,3 +645,90 @@ limitation of liability.
|
|
|
610
645
|
|
|
611
646
|
Issues and PRs welcome. Please read [LEGAL.md](https://github.com/scottconverse/textflowkit/blob/main/LEGAL.md) before adding a source
|
|
612
647
|
adapter.
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
## Optional local AI transcript cleanup (v0.1.12)
|
|
651
|
+
|
|
652
|
+
v0.1.12 adds **opt-in proofreading in the local browser UI only**. After a transcription finishes, choose an
|
|
653
|
+
installed local Ollama model and click **Proofread with local AI**. Cleanup never
|
|
654
|
+
runs automatically. Ollama and cleanup models are not bundled in the installer.
|
|
655
|
+
The optional default preference is `qwen3.5:9b` only if already installed; its
|
|
656
|
+
size/performance fit has not been verified. Otherwise choose an installed local
|
|
657
|
+
model explicitly, such as `qwen3.8:27b-q4_K_M`. Larger models are never silently
|
|
658
|
+
selected. Install a model yourself through Ollama when needed; TextFlowKit does
|
|
659
|
+
not pull models, enable cloud tags, or use a paid provider.
|
|
660
|
+
|
|
661
|
+
The original transcript, job JSON, original copy button, search, and all existing
|
|
662
|
+
exports remain unchanged. Choose **Original only** or compare **source original
|
|
663
|
+
(left) / AI corrected (right)** in timestamp-anchored rows. Use **Copy corrected
|
|
664
|
+
text** or **Save corrected TXT** for the separate AI variant. The comparison
|
|
665
|
+
proofreads original source speech, not an optional translation. AI can make
|
|
666
|
+
plausible but wrong corrections, including names and facts: review against the
|
|
667
|
+
original and audio before using it. Prompt instructions reduce errors but do not
|
|
668
|
+
guarantee accuracy or resistance to instructions embedded in speech.
|
|
669
|
+
|
|
670
|
+
Corrected segments retain source start/end timestamps and stable zero-based
|
|
671
|
+
original segment indices. They have no inherited word alignment or translation;
|
|
672
|
+
**corrected word timing is not verified**. A separate persisted variant records
|
|
673
|
+
local provider, requested/returned model, UTC completion time, endpoint, successful
|
|
674
|
+
`done_reason=stop`, policy version and original SHA-256. If original job JSON
|
|
675
|
+
changes, its correction is invalidated. No partial replacement is published: bad,
|
|
676
|
+
truncated, missing, duplicated, reordered or extra segments fail the entire attempt.
|
|
677
|
+
A failed retry retains an earlier fully validated variant only if its original
|
|
678
|
+
hash still matches.
|
|
679
|
+
|
|
680
|
+
Cleanup uses a separate SQLite file named `<job database filename>.cleanup.sqlite3`
|
|
681
|
+
beside `TEXTFLOWKIT_DB` (or the UI default database). Include it when backing up UI
|
|
682
|
+
data; it contains transcript text and provenance. The canonical job store is never
|
|
683
|
+
updated by cleanup. Reloading/reopening a completed job retrieves its saved variant,
|
|
684
|
+
even if Ollama is offline. Model selection is per attempt; it is not a global
|
|
685
|
+
transcription/translation model setting.
|
|
686
|
+
|
|
687
|
+
Configuration is process-local environment, consistent with the existing UI:
|
|
688
|
+
|
|
689
|
+
- `TEXTFLOWKIT_CLEANUP_OLLAMA_URL`: default `http://127.0.0.1:11434`; only HTTP on
|
|
690
|
+
a literal loopback IP and explicit port is accepted (IPv6 `[::1]` also works).
|
|
691
|
+
DNS names, credentials, other paths, remote hosts and redirects are refused;
|
|
692
|
+
proxy environment variables are ignored by the cleanup client.
|
|
693
|
+
- `TEXTFLOWKIT_CLEANUP_MODEL`: optional preferred installed local tag; defaults
|
|
694
|
+
to `qwen3.5:9b`. If absent from installed tags, explicit selection is required.
|
|
695
|
+
Cloud tags and Ollama remote-model metadata are refused.
|
|
696
|
+
|
|
697
|
+
One cleanup runs at a time; the browser polls a background worker and remains
|
|
698
|
+
usable. Limits: 2,000 segments, 120,000 source characters, 60 chunks, at most
|
|
699
|
+
1,000 UTF-8 encoded bytes per chunk and 40 segments per chunk. A small read-only
|
|
700
|
+
neighboring context helps with sentences spanning segments without merging them.
|
|
701
|
+
Generation requests use temperature 0, thinking disabled, context 8,192 and at
|
|
702
|
+
most 4,096 generated tokens per chunk. Requests have a 180-second socket timeout,
|
|
703
|
+
bounded response reads (1 MiB), and strict 64 KiB model JSON limits. The overall
|
|
704
|
+
work budget remains 600 seconds, checked between requests and reads; a blocking
|
|
705
|
+
socket operation can take up to its remaining request timeout before failure is
|
|
706
|
+
observed. Oversize or timeout failures leave the original available.
|
|
707
|
+
|
|
708
|
+
Normal UI shutdown drains an active cleanup (it can take several minutes); there
|
|
709
|
+
is no cleanup cancellation button. Abrupt process exit leaves no partial variant;
|
|
710
|
+
an interrupted running lease becomes retryable after at most 785 seconds from its
|
|
711
|
+
start. Cleanup does not restart Ollama or stop/unload other models. Model text is
|
|
712
|
+
rendered with DOM text nodes, never HTML. Cleanup adds no Python dependency,
|
|
713
|
+
telemetry, cloud provider or network destination beyond the configured local
|
|
714
|
+
Ollama service. Existing media acquisition/translation network behavior is separate.
|
|
715
|
+
|
|
716
|
+
### Candidate validation status
|
|
717
|
+
|
|
718
|
+
The first cold full-UI attempt ended with a generic error and produced no variant;
|
|
719
|
+
the original remained intact. A subsequent hot 39-segment run returned zero text
|
|
720
|
+
edits despite clear source spelling errors, so it was not useful cleanup-quality
|
|
721
|
+
evidence. The final cold run began with the model explicitly unloaded and
|
|
722
|
+
completed all 39 segments in three chunks at
|
|
723
|
+
2026-10-16 17:39:52 UTC. It used matching requested/returned
|
|
724
|
+
`qwen3.8:27b-q4_K_M` and changed four segments. The original SQLite JSON matched
|
|
725
|
+
the source file, with segment IDs and timestamps preserved. The in-app-browser
|
|
726
|
+
side-by-side comparison was visible, and **Save corrected TXT** produced a
|
|
727
|
+
2,516-byte file whose SHA-256 matched the validated variant.
|
|
728
|
+
|
|
729
|
+
Observed edits included “guardrails,” “precludes,” and punctuation. “Fundamental”
|
|
730
|
+
and “victims” were plausible guesses, not verified against the audio. This is
|
|
731
|
+
measured evidence that the local full workflow completed and saved its separate
|
|
732
|
+
variant for this run; it does not establish transcription accuracy or general
|
|
733
|
+
cleanup quality. Review every correction against the audio. This is local workflow evidence,
|
|
734
|
+
not an audio-accuracy certification.
|
|
@@ -8,7 +8,7 @@ Cross-platform media transcription toolkit. **One core, one CLI, thin adapters.*
|
|
|
8
8
|
[User manual](https://github.com/scottconverse/textflowkit/blob/main/docs/user-manual.md) ·
|
|
9
9
|
[Developer and integration manual](https://github.com/scottconverse/textflowkit/blob/main/docs/adapters.md)
|
|
10
10
|
|
|
11
|
-
**Current release: [v0.1.
|
|
11
|
+
**Current release: [v0.1.12](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.12).**
|
|
12
12
|
|
|
13
13
|
The [static site deployment](https://github.com/scottconverse/textflowkit/blob/main/docs/site-deployment.md) is hosted on Cloudflare
|
|
14
14
|
Pages. GitHub remains the source and CI host; the website does not run the
|
|
@@ -69,7 +69,7 @@ DOCX and PDF are available through the optional `export` extra.
|
|
|
69
69
|
|
|
70
70
|
## Architecture
|
|
71
71
|
|
|
72
|
-
 sit above one core that acquires and decodes media, transcribes with the default Whistle engine or an explicitly selected openai-whisper, keeps job state and resume checkpoints in an optional SQLite store, adds optional speaker or translation postprocessing, and publishes TXT, SRT, VTT, JSON, Markdown, and optional DOCX/PDF exports.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/architecture-overview.svg)
|
|
73
73
|
|
|
74
74
|
The design principle is **one shared core, thin doors**. Everything of substance
|
|
75
75
|
lives in the core; the interfaces are thin — the local browser UI is a fifth door
|
|
@@ -93,7 +93,7 @@ see [docs/architecture.md](https://github.com/scottconverse/textflowkit/blob/mai
|
|
|
93
93
|
|
|
94
94
|
## Live microphone streaming (opt-in)
|
|
95
95
|
|
|
96
|
-
In v0.1.
|
|
96
|
+
In v0.1.12, live streaming supports **Windows x86_64 only**. When
|
|
97
97
|
`TEXTFLOWKIT_STREAMING=1` is set, the developer HTTP app serves a `/stream`
|
|
98
98
|
WebSocket and the local UI serves `/api/stream`, both transcribing a live microphone
|
|
99
99
|
as you speak. A **runnable, self-hosted browser example** ships at
|
|
@@ -102,7 +102,7 @@ as you speak. A **runnable, self-hosted browser example** ships at
|
|
|
102
102
|
No CDN, no analytics, no external fetch. Requires the `streaming` extra:
|
|
103
103
|
|
|
104
104
|
```bash
|
|
105
|
-
python -m pip install "textflowkit[streaming]==0.1.
|
|
105
|
+
python -m pip install "textflowkit[streaming]==0.1.12"
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
It is **off by default** — with the switch unset the endpoint does not exist — and
|
|
@@ -168,6 +168,38 @@ installs `textflowkit-fonts` for offline multilingual PDF rendering:
|
|
|
168
168
|
python -m pip install 'textflowkit[export]'
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
+
## Windows desktop installer (v0.1.12; public EXE pending)
|
|
172
|
+
|
|
173
|
+
An installer for the existing local browser workspace accompanies core v0.1.12. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available. The Python package remains supported for developers and integrations.
|
|
174
|
+
|
|
175
|
+
The candidate is designed to run without a separately installed Python, WSL, or
|
|
176
|
+
Docker. Its bundle includes a private embeddable CPython runtime, the
|
|
177
|
+
browser UI and HTTP, export, and streaming dependencies, the pinned Whistle model
|
|
178
|
+
and runtime, and ffmpeg, ffprobe, and Node. The setup installs per user,
|
|
179
|
+
creates a Start Menu shortcut, and offers an optional desktop shortcut. Opening
|
|
180
|
+
the shortcut will start the local server and open the existing browser UI at
|
|
181
|
+
localhost. It is designed to need no administrator rights in normal use, change
|
|
182
|
+
no global `PATH`, and avoid automatic updates.
|
|
183
|
+
|
|
184
|
+
The pinned Whistle assets and media binaries are prebundled, so local file jobs
|
|
185
|
+
need no first-use asset download. URL sources still need their normal network
|
|
186
|
+
access. The default Whistle engine supports only these seven advertised languages:
|
|
187
|
+
`en`, `de`, `fr`, `es`, `it`, `nl`, and `pl`. Optional `openai-whisper` and diarization dependencies are not
|
|
188
|
+
bundled; those features remain documented for the Python package when separately
|
|
189
|
+
installed and configured. Streaming dependencies are bundled, but live streaming
|
|
190
|
+
remains opt-in and physical browser microphone capture has not been verified.
|
|
191
|
+
|
|
192
|
+
The candidate is designed to keep UI data outside the application install
|
|
193
|
+
directory and preserve it on upgrades and uninstall. Stop the UI server with
|
|
194
|
+
**Stop server** and wait for it to exit before upgrading or uninstalling; the
|
|
195
|
+
installer will block while it is running rather than force-killing active jobs.
|
|
196
|
+
Cancel a job first if it should not drain to completion. The bundle also
|
|
197
|
+
includes third-party license and notice files, including FFmpeg's LGPL notices
|
|
198
|
+
and corresponding-source information. Check exact notices and source-distribution
|
|
199
|
+
details against the final bundled binaries before publication. The candidate is
|
|
200
|
+
unsigned, so Windows may show a SmartScreen warning. See the [installer candidate
|
|
201
|
+
notes](docs/install.md#windows-desktop-installer-v0112-public-exe-pending).
|
|
202
|
+
|
|
171
203
|
## Python API
|
|
172
204
|
|
|
173
205
|
The same pipeline used by the CLI and adapters is available to Python callers:
|
|
@@ -263,7 +295,7 @@ textflowkit export ./transcript.json --format vtt
|
|
|
263
295
|
needs no PyTorch, so a fresh `pip install textflowkit` stays small and pulls no
|
|
264
296
|
torch; `openai-whisper` is an explicitly selectable opt-in engine.
|
|
265
297
|
|
|
266
|
-
, each core runs as one owned child with forced telemetry-off flags, a partial checkpoint is written after each core, and a resume validates the source and decoded-WAV hashes then re-runs only the unfinished cores.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/whistle-resume.svg)
|
|
267
299
|
|
|
268
300
|
- **CPU only, no torch.** It runs a pinned native binary and downloads one pinned
|
|
269
301
|
model on first use. Naming a GPU device is refused rather than silently
|
|
@@ -374,7 +406,7 @@ its own beyond the `http` extra. It ships with the core package as of v0.1.10:
|
|
|
374
406
|
a regular install of the current release carries it.
|
|
375
407
|
|
|
376
408
|
```bash
|
|
377
|
-
python -m pip install 'textflowkit[http,export]==0.1.
|
|
409
|
+
python -m pip install 'textflowkit[http,export]==0.1.12'
|
|
378
410
|
textflowkit-ui
|
|
379
411
|
```
|
|
380
412
|
|
|
@@ -445,7 +477,10 @@ browser interface share the job contract without blocking a request.
|
|
|
445
477
|
|
|
446
478
|
## Status
|
|
447
479
|
|
|
448
|
-
**v0.1.
|
|
480
|
+
**v0.1.12 release.** Adds optional UI-only local Ollama proofreading and native
|
|
481
|
+
Windows installer packaging; public EXE distribution remains gated on unresolved
|
|
482
|
+
corresponding-source compliance review, with no public installer download link.
|
|
483
|
+
Existing optional live streaming provides a transport-neutral
|
|
449
484
|
`StreamingSession` Python API, incremental transcript events, and authenticated
|
|
450
485
|
loopback WebSockets (`/stream` on the developer HTTP API and `/api/stream` on the
|
|
451
486
|
local UI), with a packaged browser microphone example. The native live capability
|
|
@@ -489,7 +524,7 @@ MCP speech, seven-format exports and completed resume; the v0.1.8 runtime fixes
|
|
|
489
524
|
were independently checked through fresh-process CLI restart probes, real SQLite
|
|
490
525
|
setup-failure tests, and the full Windows test suite. Those checks are not new
|
|
491
526
|
individual-harness receipts. That is the previous releases' record, not evidence
|
|
492
|
-
for v0.1.
|
|
527
|
+
for v0.1.12.
|
|
493
528
|
|
|
494
529
|
The v0.1.6 release was the post-v0.1.5 review repair set: security hardening
|
|
495
530
|
for media acquisition and the HTTP and MCP adapters, safer subtitle wrapping and
|
|
@@ -508,7 +543,7 @@ and both [core](https://pypi.org/project/textflowkit/0.1.6/) and
|
|
|
508
543
|
[fonts](https://pypi.org/project/textflowkit-fonts/0.1.6/) PyPI projects are
|
|
509
544
|
live — that is the v0.1.6 release's evidence, not a receipt for a later release.
|
|
510
545
|
Everything from here to the end of this section is the v0.1.6 release's
|
|
511
|
-
historical record as published: it is not re-verified for v0.1.
|
|
546
|
+
historical record as published: it is not re-verified for v0.1.12, whose separate release evidence is not supplied by these historical paragraphs.
|
|
512
547
|
Merged-main CI passed 16/16 on the tagged commit; the published wheel and
|
|
513
548
|
sdist digests match the GitHub release assets and their SHA-256 list; and a fresh
|
|
514
549
|
Windows Python 3.12 install of `textflowkit[export,mcp,http]==0.1.6` from PyPI
|
|
@@ -545,3 +580,90 @@ limitation of liability.
|
|
|
545
580
|
|
|
546
581
|
Issues and PRs welcome. Please read [LEGAL.md](https://github.com/scottconverse/textflowkit/blob/main/LEGAL.md) before adding a source
|
|
547
582
|
adapter.
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
## Optional local AI transcript cleanup (v0.1.12)
|
|
586
|
+
|
|
587
|
+
v0.1.12 adds **opt-in proofreading in the local browser UI only**. After a transcription finishes, choose an
|
|
588
|
+
installed local Ollama model and click **Proofread with local AI**. Cleanup never
|
|
589
|
+
runs automatically. Ollama and cleanup models are not bundled in the installer.
|
|
590
|
+
The optional default preference is `qwen3.5:9b` only if already installed; its
|
|
591
|
+
size/performance fit has not been verified. Otherwise choose an installed local
|
|
592
|
+
model explicitly, such as `qwen3.8:27b-q4_K_M`. Larger models are never silently
|
|
593
|
+
selected. Install a model yourself through Ollama when needed; TextFlowKit does
|
|
594
|
+
not pull models, enable cloud tags, or use a paid provider.
|
|
595
|
+
|
|
596
|
+
The original transcript, job JSON, original copy button, search, and all existing
|
|
597
|
+
exports remain unchanged. Choose **Original only** or compare **source original
|
|
598
|
+
(left) / AI corrected (right)** in timestamp-anchored rows. Use **Copy corrected
|
|
599
|
+
text** or **Save corrected TXT** for the separate AI variant. The comparison
|
|
600
|
+
proofreads original source speech, not an optional translation. AI can make
|
|
601
|
+
plausible but wrong corrections, including names and facts: review against the
|
|
602
|
+
original and audio before using it. Prompt instructions reduce errors but do not
|
|
603
|
+
guarantee accuracy or resistance to instructions embedded in speech.
|
|
604
|
+
|
|
605
|
+
Corrected segments retain source start/end timestamps and stable zero-based
|
|
606
|
+
original segment indices. They have no inherited word alignment or translation;
|
|
607
|
+
**corrected word timing is not verified**. A separate persisted variant records
|
|
608
|
+
local provider, requested/returned model, UTC completion time, endpoint, successful
|
|
609
|
+
`done_reason=stop`, policy version and original SHA-256. If original job JSON
|
|
610
|
+
changes, its correction is invalidated. No partial replacement is published: bad,
|
|
611
|
+
truncated, missing, duplicated, reordered or extra segments fail the entire attempt.
|
|
612
|
+
A failed retry retains an earlier fully validated variant only if its original
|
|
613
|
+
hash still matches.
|
|
614
|
+
|
|
615
|
+
Cleanup uses a separate SQLite file named `<job database filename>.cleanup.sqlite3`
|
|
616
|
+
beside `TEXTFLOWKIT_DB` (or the UI default database). Include it when backing up UI
|
|
617
|
+
data; it contains transcript text and provenance. The canonical job store is never
|
|
618
|
+
updated by cleanup. Reloading/reopening a completed job retrieves its saved variant,
|
|
619
|
+
even if Ollama is offline. Model selection is per attempt; it is not a global
|
|
620
|
+
transcription/translation model setting.
|
|
621
|
+
|
|
622
|
+
Configuration is process-local environment, consistent with the existing UI:
|
|
623
|
+
|
|
624
|
+
- `TEXTFLOWKIT_CLEANUP_OLLAMA_URL`: default `http://127.0.0.1:11434`; only HTTP on
|
|
625
|
+
a literal loopback IP and explicit port is accepted (IPv6 `[::1]` also works).
|
|
626
|
+
DNS names, credentials, other paths, remote hosts and redirects are refused;
|
|
627
|
+
proxy environment variables are ignored by the cleanup client.
|
|
628
|
+
- `TEXTFLOWKIT_CLEANUP_MODEL`: optional preferred installed local tag; defaults
|
|
629
|
+
to `qwen3.5:9b`. If absent from installed tags, explicit selection is required.
|
|
630
|
+
Cloud tags and Ollama remote-model metadata are refused.
|
|
631
|
+
|
|
632
|
+
One cleanup runs at a time; the browser polls a background worker and remains
|
|
633
|
+
usable. Limits: 2,000 segments, 120,000 source characters, 60 chunks, at most
|
|
634
|
+
1,000 UTF-8 encoded bytes per chunk and 40 segments per chunk. A small read-only
|
|
635
|
+
neighboring context helps with sentences spanning segments without merging them.
|
|
636
|
+
Generation requests use temperature 0, thinking disabled, context 8,192 and at
|
|
637
|
+
most 4,096 generated tokens per chunk. Requests have a 180-second socket timeout,
|
|
638
|
+
bounded response reads (1 MiB), and strict 64 KiB model JSON limits. The overall
|
|
639
|
+
work budget remains 600 seconds, checked between requests and reads; a blocking
|
|
640
|
+
socket operation can take up to its remaining request timeout before failure is
|
|
641
|
+
observed. Oversize or timeout failures leave the original available.
|
|
642
|
+
|
|
643
|
+
Normal UI shutdown drains an active cleanup (it can take several minutes); there
|
|
644
|
+
is no cleanup cancellation button. Abrupt process exit leaves no partial variant;
|
|
645
|
+
an interrupted running lease becomes retryable after at most 785 seconds from its
|
|
646
|
+
start. Cleanup does not restart Ollama or stop/unload other models. Model text is
|
|
647
|
+
rendered with DOM text nodes, never HTML. Cleanup adds no Python dependency,
|
|
648
|
+
telemetry, cloud provider or network destination beyond the configured local
|
|
649
|
+
Ollama service. Existing media acquisition/translation network behavior is separate.
|
|
650
|
+
|
|
651
|
+
### Candidate validation status
|
|
652
|
+
|
|
653
|
+
The first cold full-UI attempt ended with a generic error and produced no variant;
|
|
654
|
+
the original remained intact. A subsequent hot 39-segment run returned zero text
|
|
655
|
+
edits despite clear source spelling errors, so it was not useful cleanup-quality
|
|
656
|
+
evidence. The final cold run began with the model explicitly unloaded and
|
|
657
|
+
completed all 39 segments in three chunks at
|
|
658
|
+
2026-10-16 17:39:52 UTC. It used matching requested/returned
|
|
659
|
+
`qwen3.8:27b-q4_K_M` and changed four segments. The original SQLite JSON matched
|
|
660
|
+
the source file, with segment IDs and timestamps preserved. The in-app-browser
|
|
661
|
+
side-by-side comparison was visible, and **Save corrected TXT** produced a
|
|
662
|
+
2,516-byte file whose SHA-256 matched the validated variant.
|
|
663
|
+
|
|
664
|
+
Observed edits included “guardrails,” “precludes,” and punctuation. “Fundamental”
|
|
665
|
+
and “victims” were plausible guesses, not verified against the audio. This is
|
|
666
|
+
measured evidence that the local full workflow completed and saved its separate
|
|
667
|
+
variant for this run; it does not establish transcription accuracy or general
|
|
668
|
+
cleanup quality. Review every correction against the audio. This is local workflow evidence,
|
|
669
|
+
not an audio-accuracy certification.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Developer and integration manual
|
|
2
2
|
|
|
3
|
-
Current release: [v0.1.
|
|
3
|
+
Current release: [v0.1.12](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.12).
|
|
4
4
|
Start with the [user manual](user-manual.md) for everyday use. Harness versions
|
|
5
5
|
in the compatibility table below identify **historical test sessions**, not
|
|
6
6
|
the version of TextFlowKit currently published.
|
|
@@ -22,6 +22,48 @@ API and WebSockets are ephemeral and bypass durable job submission.
|
|
|
22
22
|
HTTP ───────────►└──────────────────────┘
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
## Windows desktop installer (v0.1.12; public EXE pending)
|
|
26
|
+
|
|
27
|
+
The Windows x86_64 installer packages the existing browser interface for core v0.1.12. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available. Its bundle includes private embeddable CPython, the UI and HTTP, export, and streaming dependencies, the pinned Whistle model and runtime, and ffmpeg, ffprobe, and Node. It requires no separately installed Python, WSL, or Docker. The Python package remains supported for developers and integrations; Docker remains a separate operator deployment example.
|
|
28
|
+
|
|
29
|
+
The setup installs per user, adds a Start Menu entry, and offers an
|
|
30
|
+
optional desktop shortcut. Launching it will start the local server and open the
|
|
31
|
+
existing UI at localhost. Administrator rights are not normally required; the
|
|
32
|
+
installer is designed not to change global `PATH` or auto-update. The prebundled
|
|
33
|
+
Whistle assets and media binaries mean local file jobs need no first-use asset
|
|
34
|
+
download; URL media still needs network access. The default Whistle engine
|
|
35
|
+
supports only these seven advertised languages: `en`, `de`, `fr`, `es`, `it`,
|
|
36
|
+
`nl`, and `pl`.
|
|
37
|
+
|
|
38
|
+
UI data is designed to stay outside the install directory and be preserved on
|
|
39
|
+
upgrade and uninstall. Before either operation, stop the UI server with **Stop
|
|
40
|
+
server** and wait for it to exit. The candidate will block while that server is
|
|
41
|
+
running rather than force-kill it; the stop action drains active jobs, so cancel a
|
|
42
|
+
job first if it should not finish. The installer does not bundle optional
|
|
43
|
+
`openai-whisper` or diarization dependencies; those documented optional features
|
|
44
|
+
remain available to Python package users who install and configure the required
|
|
45
|
+
dependencies separately. Streaming dependencies are bundled, but streaming
|
|
46
|
+
remains opt-in, and physical browser microphone capture has not been verified.
|
|
47
|
+
The installer bundle includes third-party license and notice files,
|
|
48
|
+
including FFmpeg's LGPL notices and corresponding-source information. The exact
|
|
49
|
+
notices and source-distribution details must be checked against the final binaries
|
|
50
|
+
before publication. The candidate is unsigned, so Windows may show a SmartScreen
|
|
51
|
+
warning.
|
|
52
|
+
|
|
53
|
+
```mermaid
|
|
54
|
+
flowchart LR
|
|
55
|
+
Setup[Per-user Windows x86_64 installer candidate] --> Runtime[Private embeddable CPython and bundled components]
|
|
56
|
+
Shortcut[Start Menu or optional desktop shortcut] --> Server[Local server at 127.0.0.1]
|
|
57
|
+
Runtime --> Server
|
|
58
|
+
Server <--> Browser[Existing browser UI at localhost]
|
|
59
|
+
Server --> Core[Existing HTTP adapter and shared TextFlowKit core]
|
|
60
|
+
Core --> Data[Per-user jobs, uploads, transcripts, and outputs outside install folder]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This is a locally built and tested packaging path for the local UI; it does not turn the public
|
|
64
|
+
static website into a hosted transcription service or change the developer API
|
|
65
|
+
contracts.
|
|
66
|
+
|
|
25
67
|
## Resuming and batching
|
|
26
68
|
|
|
27
69
|
`textflowkit transcribe --resume` reuses completed work, and
|
|
@@ -509,7 +551,7 @@ observation rather than forwarding the caller's header, and keep
|
|
|
509
551
|
|
|
510
552
|
## Live microphone streaming (`/stream`, opt-in)
|
|
511
553
|
|
|
512
|
-
In v0.1.
|
|
554
|
+
In v0.1.12, native live streaming supports **Windows x86_64 only**. Other live
|
|
513
555
|
platforms are unsupported; existing standalone defaults and platform support are
|
|
514
556
|
unchanged. Physical browser microphone capture was not verified. The public site
|
|
515
557
|
is static documentation and serves no streams. Both local server surfaces can
|
|
@@ -520,7 +562,7 @@ exist and a connection is refused before any session is allocated - and it needs
|
|
|
520
562
|
`streaming` extra (`websockets`).
|
|
521
563
|
|
|
522
564
|
```powershell
|
|
523
|
-
python -m pip install "textflowkit[streaming]==0.1.
|
|
565
|
+
python -m pip install "textflowkit[streaming]==0.1.12"
|
|
524
566
|
# Native Windows PowerShell:
|
|
525
567
|
$env:TEXTFLOWKIT_API_TOKEN="choose-a-long-random-token"
|
|
526
568
|
$env:TEXTFLOWKIT_STREAMING="1"
|
|
@@ -560,7 +602,7 @@ supplies FastAPI and uvicorn, and adds no new dependency). It has no public site
|
|
|
560
602
|
of its own: it is a local app, not a hosted service.
|
|
561
603
|
|
|
562
604
|
```bash
|
|
563
|
-
python -m pip install 'textflowkit[http,export]==0.1.
|
|
605
|
+
python -m pip install 'textflowkit[http,export]==0.1.12'
|
|
564
606
|
textflowkit-ui # serve on 127.0.0.1 and open a browser
|
|
565
607
|
textflowkit-ui --no-browser --port 8901
|
|
566
608
|
```
|
|
@@ -943,3 +985,27 @@ job id immediately means:
|
|
|
943
985
|
By default the job store is in-memory and bounded (`max_jobs=200`, terminal
|
|
944
986
|
jobs evicted first). Set `TEXTFLOWKIT_DB` to use the durable SQLite store for
|
|
945
987
|
restart-safe jobs and checkpoints. The SQLite store assumes one owning process.
|
|
988
|
+
|
|
989
|
+
## UI-only proofreading routes (v0.1.12)
|
|
990
|
+
|
|
991
|
+
These routes belong to the local UI session gate, not the developer HTTP or MCP
|
|
992
|
+
API. POST requires the existing `x-textflowkit-ui-capability` header. Host, peer
|
|
993
|
+
and Origin remain subject to the existing UI restrictions.
|
|
994
|
+
|
|
995
|
+
| Route | Behavior |
|
|
996
|
+
|---|---|
|
|
997
|
+
| `GET /ui/cleanup/models` | Installed local tags only; selected preference only if installed; never pulls models |
|
|
998
|
+
| `POST /ui/jobs/{id}/cleanup` | Body `{"model":"installed-local-tag"}` (max 4 KiB); completed jobs only; 202 admitted, 409 busy/not complete, 422 model/config/input error |
|
|
999
|
+
| `GET /ui/jobs/{id}/cleanup` | `none`, `running`, `done`, `error` or `stale`; fully validated separate variant and provenance when available |
|
|
1000
|
+
| `GET /ui/jobs/{id}/cleanup/download` | Valid current variant as plain TXT attachment; 409 if none/stale |
|
|
1001
|
+
|
|
1002
|
+
Cleanup does not modify existing `/api` routes, original job JSON or original
|
|
1003
|
+
downloads. Polling is background and job-scoped. There is no cancel endpoint.
|
|
1004
|
+
See the user manual for time/token/output limits, crash lease expiry, local-only
|
|
1005
|
+
endpoint rules and human review requirements.
|
|
1006
|
+
|
|
1007
|
+
A cold local full-UI verification (model unloaded before start) completed 39
|
|
1008
|
+
segments in three chunks; four segments changed. The original JSON and segment
|
|
1009
|
+
IDs/timestamps were preserved, and visible comparison plus corrected TXT save
|
|
1010
|
+
were verified. This validates one workflow run, not accuracy. Review against
|
|
1011
|
+
audio; AI guesses are not audio-verified.
|