getinvoke 0.5.3__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.
- getinvoke-0.5.3/.env.example +40 -0
- getinvoke-0.5.3/.github/workflows/build-installer.yml +107 -0
- getinvoke-0.5.3/.github/workflows/ci.yml +36 -0
- getinvoke-0.5.3/.github/workflows/publish-pypi.yml +33 -0
- getinvoke-0.5.3/.gitignore +24 -0
- getinvoke-0.5.3/LICENSE +21 -0
- getinvoke-0.5.3/PKG-INFO +312 -0
- getinvoke-0.5.3/README.md +267 -0
- getinvoke-0.5.3/THIRD-PARTY-LICENSES.txt +86 -0
- getinvoke-0.5.3/installer/build.ps1 +108 -0
- getinvoke-0.5.3/installer/generate_icon.py +87 -0
- getinvoke-0.5.3/installer/invoke.ico +0 -0
- getinvoke-0.5.3/installer/invoke.iss +74 -0
- getinvoke-0.5.3/installer/invoke.spec +114 -0
- getinvoke-0.5.3/pyproject.toml +55 -0
- getinvoke-0.5.3/ruff.toml +15 -0
- getinvoke-0.5.3/setup.cfg +4 -0
- getinvoke-0.5.3/src/getinvoke/__init__.py +8 -0
- getinvoke-0.5.3/src/getinvoke/__main__.py +5 -0
- getinvoke-0.5.3/src/getinvoke/app.py +93 -0
- getinvoke-0.5.3/src/getinvoke/cli.py +536 -0
- getinvoke-0.5.3/src/getinvoke/clipboard.py +38 -0
- getinvoke-0.5.3/src/getinvoke/config.py +187 -0
- getinvoke-0.5.3/src/getinvoke/context.py +525 -0
- getinvoke-0.5.3/src/getinvoke/engine.py +393 -0
- getinvoke-0.5.3/src/getinvoke/feedback.py +62 -0
- getinvoke-0.5.3/src/getinvoke/history.py +152 -0
- getinvoke-0.5.3/src/getinvoke/hotkey.py +133 -0
- getinvoke-0.5.3/src/getinvoke/icon.py +16 -0
- getinvoke-0.5.3/src/getinvoke/license.py +349 -0
- getinvoke-0.5.3/src/getinvoke/license_gui.py +163 -0
- getinvoke-0.5.3/src/getinvoke/modes/__init__.py +5 -0
- getinvoke-0.5.3/src/getinvoke/modes/prompts.py +253 -0
- getinvoke-0.5.3/src/getinvoke/modes/registry.py +84 -0
- getinvoke-0.5.3/src/getinvoke/overlay.py +175 -0
- getinvoke-0.5.3/src/getinvoke/recorder.py +112 -0
- getinvoke-0.5.3/src/getinvoke/reformatter.py +262 -0
- getinvoke-0.5.3/src/getinvoke/settings_gui.py +503 -0
- getinvoke-0.5.3/src/getinvoke/setup_cli.py +221 -0
- getinvoke-0.5.3/src/getinvoke/terminal.py +144 -0
- getinvoke-0.5.3/src/getinvoke/transcriber.py +108 -0
- getinvoke-0.5.3/src/getinvoke/tray.py +347 -0
- getinvoke-0.5.3/src/getinvoke/updater.py +233 -0
- getinvoke-0.5.3/src/getinvoke/window.py +147 -0
- getinvoke-0.5.3/src/getinvoke/wizard.py +484 -0
- getinvoke-0.5.3/src/getinvoke.egg-info/PKG-INFO +312 -0
- getinvoke-0.5.3/src/getinvoke.egg-info/SOURCES.txt +58 -0
- getinvoke-0.5.3/src/getinvoke.egg-info/dependency_links.txt +1 -0
- getinvoke-0.5.3/src/getinvoke.egg-info/entry_points.txt +5 -0
- getinvoke-0.5.3/src/getinvoke.egg-info/requires.txt +24 -0
- getinvoke-0.5.3/src/getinvoke.egg-info/top_level.txt +1 -0
- getinvoke-0.5.3/tests/conftest.py +11 -0
- getinvoke-0.5.3/tests/test_config.py +111 -0
- getinvoke-0.5.3/tests/test_context.py +283 -0
- getinvoke-0.5.3/tests/test_history.py +89 -0
- getinvoke-0.5.3/tests/test_license.py +246 -0
- getinvoke-0.5.3/tests/test_modes.py +104 -0
- getinvoke-0.5.3/tests/test_reformatter.py +215 -0
- getinvoke-0.5.3/tests/test_transcriber.py +85 -0
- getinvoke-0.5.3/tests/test_updater.py +121 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
## Reformatter backend: "none" (fastest), "openrouter", "claude-cli", or "ollama"
|
|
2
|
+
## Use "none" if you paste into Claude Code / Cursor — they'll interpret raw speech fine
|
|
3
|
+
REFORMATTER_BACKEND=none
|
|
4
|
+
|
|
5
|
+
## OpenRouter settings (when REFORMATTER_BACKEND=openrouter)
|
|
6
|
+
OPENROUTER_API_KEY=sk-or-REPLACE-ME
|
|
7
|
+
DICTATION_MODEL=anthropic/claude-sonnet-4-6
|
|
8
|
+
|
|
9
|
+
## Claude CLI settings (when REFORMATTER_BACKEND=claude-cli)
|
|
10
|
+
# CLAUDE_CLI_PATH=claude
|
|
11
|
+
# CLAUDE_CLI_MODEL=haiku
|
|
12
|
+
|
|
13
|
+
## Ollama settings (when REFORMATTER_BACKEND=ollama)
|
|
14
|
+
# OLLAMA_URL=http://localhost:11434
|
|
15
|
+
# OLLAMA_MODEL=llama3.2
|
|
16
|
+
|
|
17
|
+
## Target mode: claude-code, cursor, windsurf, copilot, raw, commit, pr
|
|
18
|
+
MODE=claude-code
|
|
19
|
+
|
|
20
|
+
## Whisper settings
|
|
21
|
+
WHISPER_MODEL=distil-large-v3
|
|
22
|
+
# WHISPER_DEVICE=auto
|
|
23
|
+
|
|
24
|
+
## Language: "en", "auto" (auto-detect), or any Whisper language code (es, fr, de, zh, ja, ko, etc.)
|
|
25
|
+
# LANGUAGE=en
|
|
26
|
+
|
|
27
|
+
## Hotkey (mouse5, mouse4, or keyboard combo)
|
|
28
|
+
# HOTKEY=mouse5
|
|
29
|
+
|
|
30
|
+
## Auto-paste: "true" = insta-dump (types at cursor), "false" = clipboard only (Ctrl+V yourself)
|
|
31
|
+
# AUTO_PASTE=false
|
|
32
|
+
|
|
33
|
+
## Custom vocabulary (comma-separated, boosts Whisper recognition)
|
|
34
|
+
# CUSTOM_VOCAB=KeyGrip,OpenRouter,pyproject,FastAPI
|
|
35
|
+
|
|
36
|
+
## History
|
|
37
|
+
# HISTORY_ENABLED=true
|
|
38
|
+
# HISTORY_RETENTION_DAYS=30
|
|
39
|
+
|
|
40
|
+
LOG_LEVEL=INFO
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: Build Windows Installer
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: windows-latest
|
|
15
|
+
env:
|
|
16
|
+
HAS_SIGNING_CERT: ${{ secrets.CODE_SIGNING_CERT_BASE64 != '' }}
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
cache: "pip"
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: |
|
|
28
|
+
pip install -e ".[gui,dev]"
|
|
29
|
+
pip install pyinstaller
|
|
30
|
+
|
|
31
|
+
- name: Install CUDA runtime libraries
|
|
32
|
+
run: pip install nvidia-cublas-cu12 nvidia-cuda-runtime-cu12
|
|
33
|
+
|
|
34
|
+
- name: Build with PyInstaller
|
|
35
|
+
run: python -m PyInstaller installer/invoke.spec --noconfirm --clean
|
|
36
|
+
|
|
37
|
+
- name: Bundle CUDA DLLs
|
|
38
|
+
shell: powershell
|
|
39
|
+
run: |
|
|
40
|
+
$sitePackages = python -c "import site; print(site.getsitepackages()[0])"
|
|
41
|
+
$cudaDlls = Get-ChildItem -Path $sitePackages -Recurse -Include "cublas64_*.dll","cublasLt64_*.dll","cudart64_*.dll"
|
|
42
|
+
foreach ($dll in $cudaDlls) {
|
|
43
|
+
Copy-Item $dll.FullName -Destination "dist\invoke\" -Force
|
|
44
|
+
Write-Host "Bundled: $($dll.Name) ($([math]::Round($dll.Length / 1MB, 1)) MB)"
|
|
45
|
+
}
|
|
46
|
+
if ($cudaDlls.Count -eq 0) { Write-Warning "No CUDA DLLs found - GPU will require system CUDA" }
|
|
47
|
+
|
|
48
|
+
- name: Smoke test
|
|
49
|
+
run: dist\invoke\invoke-cli.exe health
|
|
50
|
+
continue-on-error: true
|
|
51
|
+
|
|
52
|
+
- name: Import code signing certificate
|
|
53
|
+
if: env.HAS_SIGNING_CERT == 'true'
|
|
54
|
+
env:
|
|
55
|
+
CODE_SIGNING_CERT: ${{ secrets.CODE_SIGNING_CERT_BASE64 }}
|
|
56
|
+
shell: powershell
|
|
57
|
+
run: |
|
|
58
|
+
$certBytes = [Convert]::FromBase64String($env:CODE_SIGNING_CERT)
|
|
59
|
+
[IO.File]::WriteAllBytes("$env:RUNNER_TEMP\cert.pfx", $certBytes)
|
|
60
|
+
|
|
61
|
+
- name: Sign executables
|
|
62
|
+
if: env.HAS_SIGNING_CERT == 'true'
|
|
63
|
+
env:
|
|
64
|
+
CODE_SIGNING_PASSWORD: ${{ secrets.CODE_SIGNING_PASSWORD }}
|
|
65
|
+
shell: cmd
|
|
66
|
+
run: |
|
|
67
|
+
signtool sign /f "%RUNNER_TEMP%\cert.pfx" /p "%CODE_SIGNING_PASSWORD%" /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /d "Invoke" dist\invoke\invoke.exe
|
|
68
|
+
signtool sign /f "%RUNNER_TEMP%\cert.pfx" /p "%CODE_SIGNING_PASSWORD%" /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /d "Invoke" dist\invoke\invoke-cli.exe
|
|
69
|
+
|
|
70
|
+
- name: Install Inno Setup
|
|
71
|
+
run: choco install innosetup -y --no-progress
|
|
72
|
+
|
|
73
|
+
- name: Set version from tag
|
|
74
|
+
shell: bash
|
|
75
|
+
run: |
|
|
76
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
77
|
+
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
78
|
+
sed -i "s/#define MyAppVersion \".*\"/#define MyAppVersion \"$VERSION\"/" installer/invoke.iss
|
|
79
|
+
|
|
80
|
+
- name: Build installer
|
|
81
|
+
run: iscc installer/invoke.iss
|
|
82
|
+
|
|
83
|
+
- name: Sign installer
|
|
84
|
+
if: env.HAS_SIGNING_CERT == 'true'
|
|
85
|
+
env:
|
|
86
|
+
CODE_SIGNING_PASSWORD: ${{ secrets.CODE_SIGNING_PASSWORD }}
|
|
87
|
+
shell: cmd
|
|
88
|
+
run: |
|
|
89
|
+
for %%f in (dist\invoke-setup-*.exe) do signtool sign /f "%RUNNER_TEMP%\cert.pfx" /p "%CODE_SIGNING_PASSWORD%" /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /d "Invoke Setup" "%%f"
|
|
90
|
+
|
|
91
|
+
- name: Clean up certificate
|
|
92
|
+
if: always()
|
|
93
|
+
shell: powershell
|
|
94
|
+
run: Remove-Item "$env:RUNNER_TEMP\cert.pfx" -ErrorAction SilentlyContinue
|
|
95
|
+
|
|
96
|
+
- name: Upload installer artifact
|
|
97
|
+
uses: actions/upload-artifact@v4
|
|
98
|
+
with:
|
|
99
|
+
name: invoke-installer
|
|
100
|
+
path: dist/invoke-setup-*.exe
|
|
101
|
+
|
|
102
|
+
- name: Upload to release
|
|
103
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
104
|
+
uses: softprops/action-gh-release@v2
|
|
105
|
+
with:
|
|
106
|
+
files: dist/invoke-setup-*.exe
|
|
107
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- run: pip install ruff
|
|
19
|
+
- run: ruff check src/ tests/
|
|
20
|
+
- run: ruff format --check src/ tests/
|
|
21
|
+
|
|
22
|
+
test:
|
|
23
|
+
runs-on: ${{ matrix.os }}
|
|
24
|
+
strategy:
|
|
25
|
+
matrix:
|
|
26
|
+
os: [ubuntu-latest, windows-latest]
|
|
27
|
+
python-version: ["3.11", "3.12"]
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
- uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: ${{ matrix.python-version }}
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: pip install -e ".[dev]"
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: pytest tests/ -v --ignore=tests/test_gpu.py
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
uses: ./.github/workflows/ci.yml
|
|
11
|
+
|
|
12
|
+
publish:
|
|
13
|
+
needs: test
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
id-token: write # Trusted publishing
|
|
17
|
+
contents: read # Checkout private repo
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.12"
|
|
25
|
+
|
|
26
|
+
- name: Install build tools
|
|
27
|
+
run: pip install build
|
|
28
|
+
|
|
29
|
+
- name: Build sdist + wheel
|
|
30
|
+
run: python -m build
|
|
31
|
+
|
|
32
|
+
- name: Publish to PyPI
|
|
33
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.eggs/
|
|
8
|
+
*.egg
|
|
9
|
+
|
|
10
|
+
venv/
|
|
11
|
+
.venv/
|
|
12
|
+
env/
|
|
13
|
+
|
|
14
|
+
.env
|
|
15
|
+
*.wav
|
|
16
|
+
*.mp3
|
|
17
|
+
|
|
18
|
+
.ruff_cache/
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
htmlcov/
|
|
22
|
+
.coverage
|
|
23
|
+
|
|
24
|
+
*.log
|
getinvoke-0.5.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zach Roth
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
getinvoke-0.5.3/PKG-INFO
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getinvoke
|
|
3
|
+
Version: 0.5.3
|
|
4
|
+
Summary: Voice-to-prompt for developers. Hold a button, speak, release — structured prompts on your clipboard in under a second.
|
|
5
|
+
Author-email: Zach Roth <zach@scrn.co>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://getinvoke.dev
|
|
8
|
+
Project-URL: Repository, https://github.com/zmroth/invoke
|
|
9
|
+
Keywords: voice,dictation,whisper,coding,prompt,speech-to-text,developer-tools,claude,cursor,copilot
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: faster-whisper>=1.1.0
|
|
24
|
+
Requires-Dist: httpx>=0.28.0
|
|
25
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
26
|
+
Requires-Dist: pynput>=1.8.0
|
|
27
|
+
Requires-Dist: sounddevice>=0.5.0
|
|
28
|
+
Requires-Dist: numpy>=1.24.0
|
|
29
|
+
Requires-Dist: scipy>=1.11.0
|
|
30
|
+
Requires-Dist: pyperclip>=1.9.0
|
|
31
|
+
Requires-Dist: click>=8.0.0
|
|
32
|
+
Requires-Dist: rich>=13.0.0
|
|
33
|
+
Provides-Extra: gui
|
|
34
|
+
Requires-Dist: pystray>=0.19.0; extra == "gui"
|
|
35
|
+
Requires-Dist: Pillow>=10.0.0; extra == "gui"
|
|
36
|
+
Provides-Extra: cuda
|
|
37
|
+
Requires-Dist: nvidia-cublas-cu12; extra == "cuda"
|
|
38
|
+
Requires-Dist: nvidia-cuda-runtime-cu12; extra == "cuda"
|
|
39
|
+
Provides-Extra: dev
|
|
40
|
+
Requires-Dist: pytest; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
42
|
+
Requires-Dist: ruff; extra == "dev"
|
|
43
|
+
Requires-Dist: pyinstaller; extra == "dev"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# Invoke
|
|
47
|
+
|
|
48
|
+
[](https://pypi.org/project/getinvoke/)
|
|
49
|
+
[](https://pypi.org/project/getinvoke/)
|
|
50
|
+
[](https://github.com/zmroth/invoke/blob/main/LICENSE)
|
|
51
|
+
|
|
52
|
+
**Voice-to-prompt for developers.**
|
|
53
|
+
|
|
54
|
+
Hold a button, speak, release. Your words hit the clipboard (or auto-paste at your cursor) in under a second. GPU-accelerated local transcription via Whisper — no cloud round-trip for speech-to-text.
|
|
55
|
+
|
|
56
|
+
Optionally run your transcription through an AI reformatter to clean it up into structured prompts for Claude Code, Cursor, Windsurf, Copilot, or raw text.
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# CLI only (headless, any platform)
|
|
62
|
+
pip install getinvoke
|
|
63
|
+
|
|
64
|
+
# With GUI (system tray + overlay)
|
|
65
|
+
pip install getinvoke[gui]
|
|
66
|
+
|
|
67
|
+
# Or use pipx for isolated install
|
|
68
|
+
pipx install getinvoke
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
> **Note:** The CLI command is `dictate`, not `invoke`, to avoid conflict with the pyinvoke task runner.
|
|
72
|
+
|
|
73
|
+
## Quick Start
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Check your setup (GPU, mic, settings)
|
|
77
|
+
dictate health
|
|
78
|
+
|
|
79
|
+
# Run the setup wizard
|
|
80
|
+
dictate setup
|
|
81
|
+
|
|
82
|
+
# Start dictating (headless mode)
|
|
83
|
+
dictate run
|
|
84
|
+
|
|
85
|
+
# Start with GUI (requires [gui] extras)
|
|
86
|
+
dictate run # auto-detects GUI availability
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Default workflow:** Hold **Mouse5** (forward side button) → speak → release → text on clipboard.
|
|
90
|
+
|
|
91
|
+
## How It Works
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
YOU SPEAK into your mic
|
|
95
|
+
│
|
|
96
|
+
▼
|
|
97
|
+
┌─────────────────────────────┐
|
|
98
|
+
│ WHISPER (runs locally) │
|
|
99
|
+
│ Model: distil-large-v3 │
|
|
100
|
+
│ GPU (CUDA) or CPU │
|
|
101
|
+
│ No internet. No API key. │
|
|
102
|
+
│ │
|
|
103
|
+
│ Output: raw transcription │
|
|
104
|
+
│ "uh so like fix the um │
|
|
105
|
+
│ auth middleware thing" │
|
|
106
|
+
└──────────────┬──────────────┘
|
|
107
|
+
│
|
|
108
|
+
▼
|
|
109
|
+
┌─────────────────────────────┐
|
|
110
|
+
│ AI REFORMATTER (optional) │
|
|
111
|
+
│ │
|
|
112
|
+
│ Takes raw speech and │
|
|
113
|
+
│ reshapes it based on the │
|
|
114
|
+
│ selected MODE: │
|
|
115
|
+
│ │
|
|
116
|
+
│ Claude Code → conversational│
|
|
117
|
+
│ Cursor → @file references │
|
|
118
|
+
│ Commit → git commit msg │
|
|
119
|
+
│ Raw → just clean up speech │
|
|
120
|
+
│ none → SKIP (no AI call) │
|
|
121
|
+
│ │
|
|
122
|
+
│ Backend options: │
|
|
123
|
+
│ • openrouter (cloud API) │
|
|
124
|
+
│ • claude-cli (local CC) │
|
|
125
|
+
│ • ollama (fully local) │
|
|
126
|
+
│ • none (skip AI entirely) │
|
|
127
|
+
└──────────────┬──────────────┘
|
|
128
|
+
│
|
|
129
|
+
▼
|
|
130
|
+
┌─────────────────────────────┐
|
|
131
|
+
│ CLIPBOARD + AUTO-PASTE │
|
|
132
|
+
│ "Fix the auth middleware │
|
|
133
|
+
│ to validate JWT tokens │
|
|
134
|
+
│ before checking roles" │
|
|
135
|
+
└─────────────────────────────┘
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Platform Support
|
|
139
|
+
|
|
140
|
+
| Platform | CLI (headless) | GUI (tray + overlay) | Installer |
|
|
141
|
+
|---|---|---|---|
|
|
142
|
+
| Windows | `pip install getinvoke` | `pip install getinvoke[gui]` | `.exe` via GitHub Releases |
|
|
143
|
+
| Linux | `pip install getinvoke` | `pip install getinvoke[gui]` | — |
|
|
144
|
+
| macOS | `pip install getinvoke` | Planned | — |
|
|
145
|
+
|
|
146
|
+
## Comparison
|
|
147
|
+
|
|
148
|
+
| Feature | Invoke | whisper.cpp CLI | nerd-dictation | macOS Dictation |
|
|
149
|
+
|---|---|---|---|---|
|
|
150
|
+
| Local Whisper | Yes | Yes | Yes | No |
|
|
151
|
+
| AI reformatting | Yes (4 backends) | No | No | No |
|
|
152
|
+
| Code-aware modes | 7 modes | No | No | No |
|
|
153
|
+
| Project context | Auto-detected | No | No | No |
|
|
154
|
+
| GPU acceleration | CUDA | CUDA/Metal | No | — |
|
|
155
|
+
| Cross-platform | Win/Linux/Mac | Win/Linux/Mac | Linux | Mac only |
|
|
156
|
+
| pip installable | Yes | No | No | — |
|
|
157
|
+
|
|
158
|
+
## Requirements
|
|
159
|
+
|
|
160
|
+
- Python 3.11+
|
|
161
|
+
- NVIDIA GPU recommended (CUDA) — works on CPU but slower
|
|
162
|
+
- Windows, Linux, or macOS
|
|
163
|
+
|
|
164
|
+
## CLI Commands
|
|
165
|
+
|
|
166
|
+
| Command | Description |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `dictate run` | Start Invoke (auto-detects GUI vs headless) |
|
|
169
|
+
| `dictate run --headless` | Force headless mode |
|
|
170
|
+
| `dictate run --no-beep` | Start without audio feedback |
|
|
171
|
+
| `dictate health` | Check GPU, model, mic, API keys, config |
|
|
172
|
+
| `dictate devices` | List audio input devices |
|
|
173
|
+
| `dictate modes` | List available target modes |
|
|
174
|
+
| `dictate history` | View dictation history |
|
|
175
|
+
| `dictate setup` | Run setup wizard |
|
|
176
|
+
| `dictate setup --cli` | Force CLI wizard (no GUI) |
|
|
177
|
+
| `dictate config` | View all configuration |
|
|
178
|
+
| `dictate config mode cursor` | Set a config value |
|
|
179
|
+
| `dictate license status` | Check license status |
|
|
180
|
+
| `dictate license activate <key>` | Activate a license |
|
|
181
|
+
| `dictate install` | Create Windows Startup shortcut |
|
|
182
|
+
| `dictate transcribe <file>` | One-shot WAV transcription |
|
|
183
|
+
| `dictate logs` | View log file |
|
|
184
|
+
|
|
185
|
+
## Configuration
|
|
186
|
+
|
|
187
|
+
### Key Settings
|
|
188
|
+
|
|
189
|
+
| Setting | Default | Options |
|
|
190
|
+
|---|---|---|
|
|
191
|
+
| `reformatter_backend` | `none` | `openrouter`, `claude-cli`, `ollama`, `none` |
|
|
192
|
+
| `mode` | `claude-code` | `claude-code`, `cursor`, `windsurf`, `copilot`, `raw`, `commit`, `pr` |
|
|
193
|
+
| `whisper_model` | `distil-large-v3` | Any [faster-whisper model](https://huggingface.co/Systran) |
|
|
194
|
+
| `whisper_device` | `auto` | `auto`, `cuda`, `cpu` |
|
|
195
|
+
| `hotkey` | `mouse5` | `mouse5`, `mouse4`, or keyboard combo |
|
|
196
|
+
| `auto_paste` | `false` | `true` = insta-dump at cursor |
|
|
197
|
+
| `audio_device` | system default | Device index from `dictate devices` |
|
|
198
|
+
| `beep_enabled` | `true` | `true` / `false` |
|
|
199
|
+
|
|
200
|
+
Set values quickly from the terminal:
|
|
201
|
+
```bash
|
|
202
|
+
dictate config mode cursor
|
|
203
|
+
dictate config reformatter_backend claude-cli
|
|
204
|
+
dictate config auto_paste true
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### AI Reformatter Backends
|
|
208
|
+
|
|
209
|
+
| Backend | Where it runs | What you need | Cost |
|
|
210
|
+
|---|---|---|---|
|
|
211
|
+
| `openrouter` | Cloud (OpenRouter API) | `OPENROUTER_API_KEY` | ~$0.001/dictation |
|
|
212
|
+
| `claude-cli` | Local (your Claude Code) | Claude Code installed | Part of your CC plan |
|
|
213
|
+
| `ollama` | Local (your machine) | Ollama, LM Studio, or any local LLM server | Free, no internet |
|
|
214
|
+
| `none` | Skipped entirely | Nothing | Free — raw Whisper output only |
|
|
215
|
+
|
|
216
|
+
### Target Modes
|
|
217
|
+
|
|
218
|
+
| Mode | What the AI does with your speech |
|
|
219
|
+
|---|---|
|
|
220
|
+
| `claude-code` | Formats as a conversational prompt for Claude Code |
|
|
221
|
+
| `cursor` | Adds `@file` references, structured for Cursor's chat |
|
|
222
|
+
| `windsurf` | Cascade-style prompt for Windsurf |
|
|
223
|
+
| `copilot` | GitHub Copilot Chat format |
|
|
224
|
+
| `raw` | Cleans up filler/grammar only — no prompt structure |
|
|
225
|
+
| `commit` | Turns your description into a git commit message |
|
|
226
|
+
| `pr` | Turns your description into a PR title + body |
|
|
227
|
+
|
|
228
|
+
### Custom Vocabulary
|
|
229
|
+
|
|
230
|
+
Boost Whisper recognition for domain-specific terms:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
dictate config custom_vocab "KeyGrip,OpenRouter,pyproject,FastAPI,pynput"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### History
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
dictate history # Recent entries
|
|
240
|
+
dictate history -n 20 # Last 20
|
|
241
|
+
dictate history -s "fix" # Search
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Audio Feedback
|
|
245
|
+
|
|
246
|
+
- **Short high tick** — recording started (hotkey pressed)
|
|
247
|
+
- **Rising chirp** — done, text is on clipboard / pasted
|
|
248
|
+
- Disable with `dictate run --no-beep` or `dictate config beep_enabled false`
|
|
249
|
+
|
|
250
|
+
## System Tray (GUI mode)
|
|
251
|
+
|
|
252
|
+
When installed with `pip install getinvoke[gui]`, Invoke runs in the system tray with:
|
|
253
|
+
- State indicator (idle / recording / processing / error)
|
|
254
|
+
- Current AI backend + model displayed
|
|
255
|
+
- Mode switcher (right-click menu)
|
|
256
|
+
- License management
|
|
257
|
+
- Settings editor
|
|
258
|
+
- Open logs
|
|
259
|
+
- Quit
|
|
260
|
+
|
|
261
|
+
Use `dictate-gui` to launch without a console window.
|
|
262
|
+
|
|
263
|
+
## Building the Windows Installer
|
|
264
|
+
|
|
265
|
+
See the [installer README](installer/) for details on building the `.exe` installer with PyInstaller + Inno Setup.
|
|
266
|
+
|
|
267
|
+
## Development
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
pip install -e ".[dev,gui]"
|
|
271
|
+
ruff check src/ tests/
|
|
272
|
+
ruff format src/ tests/
|
|
273
|
+
pytest
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Architecture
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
src/getinvoke/
|
|
280
|
+
engine.py # Core pipeline engine (FrontendProtocol + InvokeEngine)
|
|
281
|
+
app.py # GUI frontend wrapper (GuiFrontend + InvokeApp)
|
|
282
|
+
terminal.py # Rich terminal frontend (TerminalFrontend)
|
|
283
|
+
cli.py # Click CLI commands
|
|
284
|
+
setup_cli.py # Terminal-based setup wizard
|
|
285
|
+
clipboard.py # Copy + auto-paste via pynput
|
|
286
|
+
config.py # Settings from config.json / env vars / .env
|
|
287
|
+
context.py # Project context loader (18 file types + git)
|
|
288
|
+
feedback.py # Audio cues (beeps/chirps)
|
|
289
|
+
history.py # SQLite dictation history
|
|
290
|
+
hotkey.py # Global hotkey listener (mouse/keyboard)
|
|
291
|
+
license.py # Lemon Squeezy license validation (7-day trial)
|
|
292
|
+
license_gui.py # License activation dialog (tkinter, GUI only)
|
|
293
|
+
modes/ # 7 target mode system prompts
|
|
294
|
+
overlay.py # Recording/processing overlay (tkinter, GUI only)
|
|
295
|
+
recorder.py # Push-to-talk audio capture (sounddevice)
|
|
296
|
+
reformatter.py # LLM reformatting (OpenRouter/Claude CLI/Ollama/none)
|
|
297
|
+
settings_gui.py # Settings editor (tkinter, GUI only)
|
|
298
|
+
transcriber.py # Whisper model loading + transcription
|
|
299
|
+
tray.py # System tray icon + menu (pystray, GUI only)
|
|
300
|
+
updater.py # Auto-updater (GitHub releases + pip-aware)
|
|
301
|
+
window.py # Active window/file detection
|
|
302
|
+
wizard.py # First-run setup wizard (tkinter, GUI only)
|
|
303
|
+
|
|
304
|
+
installer/
|
|
305
|
+
invoke.spec # PyInstaller build config
|
|
306
|
+
invoke.iss # Inno Setup installer script
|
|
307
|
+
build.ps1 # Local build script
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
MIT — see [THIRD-PARTY-LICENSES.txt](THIRD-PARTY-LICENSES.txt) for bundled dependency licenses.
|