dictare 0.1.140rc1__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.
- dictare-0.1.140rc1/.dockerignore +22 -0
- dictare-0.1.140rc1/.github/ISSUE_TEMPLATE/bug_report.md +57 -0
- dictare-0.1.140rc1/.github/ISSUE_TEMPLATE/feature_request.md +29 -0
- dictare-0.1.140rc1/.github/PULL_REQUEST_TEMPLATE.md +29 -0
- dictare-0.1.140rc1/.github/workflows/build-launcher.yml +197 -0
- dictare-0.1.140rc1/.github/workflows/ci-macos.yml +25 -0
- dictare-0.1.140rc1/.github/workflows/ci.yml +48 -0
- dictare-0.1.140rc1/.github/workflows/claude-dedupe-issues.yml +45 -0
- dictare-0.1.140rc1/.github/workflows/claude-issue-triage.yml +49 -0
- dictare-0.1.140rc1/.github/workflows/claude-pr-review.yml +57 -0
- dictare-0.1.140rc1/.github/workflows/claude.yml +35 -0
- dictare-0.1.140rc1/.github/workflows/lock-closed-issues.yml +53 -0
- dictare-0.1.140rc1/.github/workflows/publish-pypi.yml +29 -0
- dictare-0.1.140rc1/.github/workflows/sweep.yml +29 -0
- dictare-0.1.140rc1/.gitignore +113 -0
- dictare-0.1.140rc1/.gitlab-ci.yml +61 -0
- dictare-0.1.140rc1/.python-version +1 -0
- dictare-0.1.140rc1/ARCHITECTURE.md +71 -0
- dictare-0.1.140rc1/CHANGELOG.md +1320 -0
- dictare-0.1.140rc1/CLAUDE.md +58 -0
- dictare-0.1.140rc1/CODE_OF_CONDUCT.md +38 -0
- dictare-0.1.140rc1/CONTRIBUTING.md +141 -0
- dictare-0.1.140rc1/LICENSE +21 -0
- dictare-0.1.140rc1/PKG-INFO +289 -0
- dictare-0.1.140rc1/README.md +225 -0
- dictare-0.1.140rc1/SECURITY.md +55 -0
- dictare-0.1.140rc1/TERMINAL_COMPATIBILITY.md +173 -0
- dictare-0.1.140rc1/assets/icon.svg +9 -0
- dictare-0.1.140rc1/install.sh +196 -0
- dictare-0.1.140rc1/openapitools.json +7 -0
- dictare-0.1.140rc1/packaging/deb/build-deb.sh +71 -0
- dictare-0.1.140rc1/packaging/deb/debian/control +10 -0
- dictare-0.1.140rc1/packaging/deb/debian/postinst +37 -0
- dictare-0.1.140rc1/packaging/deb/debian/postrm +15 -0
- dictare-0.1.140rc1/packaging/deb/debian/prerm +14 -0
- dictare-0.1.140rc1/packaging/homebrew/dictare.rb +41 -0
- dictare-0.1.140rc1/pyproject.toml +128 -0
- dictare-0.1.140rc1/remove-permissions.sh +31 -0
- dictare-0.1.140rc1/scripts/dev/full-install.sh +26 -0
- dictare-0.1.140rc1/scripts/dev/local-build-check.sh +32 -0
- dictare-0.1.140rc1/scripts/dev/publish.sh +203 -0
- dictare-0.1.140rc1/scripts/install.sh +32 -0
- dictare-0.1.140rc1/scripts/linux/install.sh +297 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/Dockerfile.arch +45 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/Dockerfile.debian +43 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/Dockerfile.fedora +43 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/Dockerfile.ubuntu +45 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/README.md +33 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/run.sh +154 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/tests/e2e.sh +115 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/tests/engine.sh +93 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/tests/smoke.sh +30 -0
- dictare-0.1.140rc1/scripts/linux/test-distros/tests/tray.sh +48 -0
- dictare-0.1.140rc1/scripts/linux/uninstall.sh +138 -0
- dictare-0.1.140rc1/scripts/macos/install.sh +214 -0
- dictare-0.1.140rc1/scripts/macos/sign-launcher.sh +45 -0
- dictare-0.1.140rc1/scripts/macos/uninstall.sh +181 -0
- dictare-0.1.140rc1/scripts/test.sh +17 -0
- dictare-0.1.140rc1/scripts/uninstall.sh +12 -0
- dictare-0.1.140rc1/setup-permissions.sh +21 -0
- dictare-0.1.140rc1/spec/README.md +46 -0
- dictare-0.1.140rc1/src/dictare/__init__.py +8 -0
- dictare-0.1.140rc1/src/dictare/__main__.py +6 -0
- dictare-0.1.140rc1/src/dictare/agent/__init__.py +5 -0
- dictare-0.1.140rc1/src/dictare/agent/base.py +78 -0
- dictare-0.1.140rc1/src/dictare/agent/injection/__init__.py +1 -0
- dictare-0.1.140rc1/src/dictare/agent/injection/base.py +114 -0
- dictare-0.1.140rc1/src/dictare/agent/injection/quartz.py +254 -0
- dictare-0.1.140rc1/src/dictare/agent/injection/ydotool.py +260 -0
- dictare-0.1.140rc1/src/dictare/agent/keyboard.py +199 -0
- dictare-0.1.140rc1/src/dictare/agent/mux.py +846 -0
- dictare-0.1.140rc1/src/dictare/agent/pty_session.py +194 -0
- dictare-0.1.140rc1/src/dictare/agent/sse.py +35 -0
- dictare-0.1.140rc1/src/dictare/agent/status_bar.py +207 -0
- dictare-0.1.140rc1/src/dictare/app/__init__.py +12 -0
- dictare-0.1.140rc1/src/dictare/app/bindings.py +156 -0
- dictare-0.1.140rc1/src/dictare/app/controller.py +699 -0
- dictare-0.1.140rc1/src/dictare/audio/__init__.py +1 -0
- dictare-0.1.140rc1/src/dictare/audio/beep.py +556 -0
- dictare-0.1.140rc1/src/dictare/audio/capture.py +323 -0
- dictare-0.1.140rc1/src/dictare/audio/device_monitor.py +328 -0
- dictare-0.1.140rc1/src/dictare/audio/feedback_policy.py +117 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/carriage-return.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/down-beep.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/pencil-write-1.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/pencil-write-2.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/pencil-write-3.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/pencil-write-4.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/pencil-write-5.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/pencil-write.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/transcribing.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/typewriter-burst.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/typewriter.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/sounds/up-beep.wav +0 -0
- dictare-0.1.140rc1/src/dictare/audio/vad.py +394 -0
- dictare-0.1.140rc1/src/dictare/cli/__init__.py +142 -0
- dictare-0.1.140rc1/src/dictare/cli/_helpers.py +19 -0
- dictare-0.1.140rc1/src/dictare/cli/agent.py +225 -0
- dictare-0.1.140rc1/src/dictare/cli/config.py +157 -0
- dictare-0.1.140rc1/src/dictare/cli/dependencies.py +182 -0
- dictare-0.1.140rc1/src/dictare/cli/logs.py +212 -0
- dictare-0.1.140rc1/src/dictare/cli/misc.py +60 -0
- dictare-0.1.140rc1/src/dictare/cli/models.py +368 -0
- dictare-0.1.140rc1/src/dictare/cli/panel.py +434 -0
- dictare-0.1.140rc1/src/dictare/cli/serve.py +223 -0
- dictare-0.1.140rc1/src/dictare/cli/service.py +211 -0
- dictare-0.1.140rc1/src/dictare/cli/setup.py +91 -0
- dictare-0.1.140rc1/src/dictare/cli/shortcuts.py +228 -0
- dictare-0.1.140rc1/src/dictare/cli/speak.py +293 -0
- dictare-0.1.140rc1/src/dictare/cli/status.py +242 -0
- dictare-0.1.140rc1/src/dictare/cli/tray.py +105 -0
- dictare-0.1.140rc1/src/dictare/config.py +1126 -0
- dictare-0.1.140rc1/src/dictare/core/__init__.py +21 -0
- dictare-0.1.140rc1/src/dictare/core/agent_manager.py +358 -0
- dictare-0.1.140rc1/src/dictare/core/audio_manager.py +646 -0
- dictare-0.1.140rc1/src/dictare/core/bus.py +137 -0
- dictare-0.1.140rc1/src/dictare/core/controller.py +436 -0
- dictare-0.1.140rc1/src/dictare/core/engine.py +1727 -0
- dictare-0.1.140rc1/src/dictare/core/events.py +45 -0
- dictare-0.1.140rc1/src/dictare/core/fsm.py +299 -0
- dictare-0.1.140rc1/src/dictare/core/http_server.py +1553 -0
- dictare-0.1.140rc1/src/dictare/core/openvip_messages.py +65 -0
- dictare-0.1.140rc1/src/dictare/core/openvip_validator.py +45 -0
- dictare-0.1.140rc1/src/dictare/core/toml_sections.py +531 -0
- dictare-0.1.140rc1/src/dictare/core/transcriber.py +157 -0
- dictare-0.1.140rc1/src/dictare/core/tts_manager.py +592 -0
- dictare-0.1.140rc1/src/dictare/credits.json +12 -0
- dictare-0.1.140rc1/src/dictare/cuda_setup.py +179 -0
- dictare-0.1.140rc1/src/dictare/daemon/__init__.py +1 -0
- dictare-0.1.140rc1/src/dictare/daemon/app_bundle.py +274 -0
- dictare-0.1.140rc1/src/dictare/daemon/launchd.py +369 -0
- dictare-0.1.140rc1/src/dictare/daemon/systemd.py +100 -0
- dictare-0.1.140rc1/src/dictare/hotkey/__init__.py +5 -0
- dictare-0.1.140rc1/src/dictare/hotkey/base.py +57 -0
- dictare-0.1.140rc1/src/dictare/hotkey/evdev_listener.py +351 -0
- dictare-0.1.140rc1/src/dictare/hotkey/ipc.py +288 -0
- dictare-0.1.140rc1/src/dictare/hotkey/pynput_listener.py +172 -0
- dictare-0.1.140rc1/src/dictare/hotkey/runtime_status.py +32 -0
- dictare-0.1.140rc1/src/dictare/hotkey/tap_detector.py +211 -0
- dictare-0.1.140rc1/src/dictare/input/__init__.py +6 -0
- dictare-0.1.140rc1/src/dictare/input/backends/__init__.py +83 -0
- dictare-0.1.140rc1/src/dictare/input/backends/base.py +76 -0
- dictare-0.1.140rc1/src/dictare/input/backends/evdev_backend.py +199 -0
- dictare-0.1.140rc1/src/dictare/input/backends/hidapi_backend.py +210 -0
- dictare-0.1.140rc1/src/dictare/input/backends/karabiner_backend.py +283 -0
- dictare-0.1.140rc1/src/dictare/input/base.py +57 -0
- dictare-0.1.140rc1/src/dictare/input/constants.py +26 -0
- dictare-0.1.140rc1/src/dictare/input/device.py +366 -0
- dictare-0.1.140rc1/src/dictare/input/keyboard.py +172 -0
- dictare-0.1.140rc1/src/dictare/input/manager.py +152 -0
- dictare-0.1.140rc1/src/dictare/logging/__init__.py +36 -0
- dictare-0.1.140rc1/src/dictare/logging/jsonl.py +294 -0
- dictare-0.1.140rc1/src/dictare/logging/setup.py +147 -0
- dictare-0.1.140rc1/src/dictare/models.json +59 -0
- dictare-0.1.140rc1/src/dictare/pipeline/__init__.py +52 -0
- dictare-0.1.140rc1/src/dictare/pipeline/base.py +208 -0
- dictare-0.1.140rc1/src/dictare/pipeline/executors/__init__.py +7 -0
- dictare-0.1.140rc1/src/dictare/pipeline/executors/agent_switch.py +75 -0
- dictare-0.1.140rc1/src/dictare/pipeline/executors/input.py +73 -0
- dictare-0.1.140rc1/src/dictare/pipeline/executors/mute.py +72 -0
- dictare-0.1.140rc1/src/dictare/pipeline/filters/__init__.py +7 -0
- dictare-0.1.140rc1/src/dictare/pipeline/filters/_text.py +207 -0
- dictare-0.1.140rc1/src/dictare/pipeline/filters/agent_filter.py +333 -0
- dictare-0.1.140rc1/src/dictare/pipeline/filters/input_filter.py +193 -0
- dictare-0.1.140rc1/src/dictare/pipeline/filters/mute_filter.py +156 -0
- dictare-0.1.140rc1/src/dictare/pipeline/loader.py +191 -0
- dictare-0.1.140rc1/src/dictare/platform/__init__.py +1 -0
- dictare-0.1.140rc1/src/dictare/platform/accessibility.py +163 -0
- dictare-0.1.140rc1/src/dictare/platform/microphone.py +82 -0
- dictare-0.1.140rc1/src/dictare/platform/permission_doctor.py +218 -0
- dictare-0.1.140rc1/src/dictare/platform/permissions.py +240 -0
- dictare-0.1.140rc1/src/dictare/plugins/__init__.py +166 -0
- dictare-0.1.140rc1/src/dictare/plugins/base.py +99 -0
- dictare-0.1.140rc1/src/dictare/resources/Dictare.entitlements +9 -0
- dictare-0.1.140rc1/src/dictare/resources/Dictare.icns +0 -0
- dictare-0.1.140rc1/src/dictare/resources/__init__.py +0 -0
- dictare-0.1.140rc1/src/dictare/resources/app_icon.svg +11 -0
- dictare-0.1.140rc1/src/dictare/resources/launcher.swift +623 -0
- dictare-0.1.140rc1/src/dictare/resources/openvip-message-v1.0.json +134 -0
- dictare-0.1.140rc1/src/dictare/resources/openvip-openapi.json +680 -0
- dictare-0.1.140rc1/src/dictare/services/__init__.py +12 -0
- dictare-0.1.140rc1/src/dictare/services/base.py +98 -0
- dictare-0.1.140rc1/src/dictare/services/stt_service.py +194 -0
- dictare-0.1.140rc1/src/dictare/services/tts_service.py +129 -0
- dictare-0.1.140rc1/src/dictare/status.py +72 -0
- dictare-0.1.140rc1/src/dictare/stt/__init__.py +1 -0
- dictare-0.1.140rc1/src/dictare/stt/base.py +70 -0
- dictare-0.1.140rc1/src/dictare/stt/faster_whisper.py +416 -0
- dictare-0.1.140rc1/src/dictare/stt/mlx_whisper.py +175 -0
- dictare-0.1.140rc1/src/dictare/stt/parakeet.py +149 -0
- dictare-0.1.140rc1/src/dictare/tray/__init__.py +6 -0
- dictare-0.1.140rc1/src/dictare/tray/app.py +905 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare.svg +10 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare@2x.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_active.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_active.svg +10 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_active@2x.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_disconnected.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_disconnected.svg +12 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_disconnected@2x.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_loading.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_loading.svg +13 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_loading@2x.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_muted.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_muted.svg +12 -0
- dictare-0.1.140rc1/src/dictare/tray/icons/dictare_muted@2x.png +0 -0
- dictare-0.1.140rc1/src/dictare/tray/lifecycle.py +175 -0
- dictare-0.1.140rc1/src/dictare/tts/__init__.py +134 -0
- dictare-0.1.140rc1/src/dictare/tts/__main__.py +5 -0
- dictare-0.1.140rc1/src/dictare/tts/base.py +129 -0
- dictare-0.1.140rc1/src/dictare/tts/cache.py +64 -0
- dictare-0.1.140rc1/src/dictare/tts/coqui.py +165 -0
- dictare-0.1.140rc1/src/dictare/tts/espeak.py +139 -0
- dictare-0.1.140rc1/src/dictare/tts/kokoro.py +326 -0
- dictare-0.1.140rc1/src/dictare/tts/outetts.py +247 -0
- dictare-0.1.140rc1/src/dictare/tts/piper.py +219 -0
- dictare-0.1.140rc1/src/dictare/tts/proxy.py +122 -0
- dictare-0.1.140rc1/src/dictare/tts/say.py +146 -0
- dictare-0.1.140rc1/src/dictare/tts/venv.py +254 -0
- dictare-0.1.140rc1/src/dictare/tts/worker.py +232 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/env.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/assets/0.u29JO9q6.css +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/assets/2.ADhTY10N.css +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/B5iEOtbf.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/BR0tsQvA.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/BfcgiW2_.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/BqKnRztf.js +2 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/CFFbbuus.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/TwTPH6iZ.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/WyvEpU-T.js +3 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/Yvw_uC43.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/chunks/uOPFAhOp.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/entry/app.BmNgH3es.js +2 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/entry/start.COqxU25x.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/nodes/0.CJgu44HO.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/nodes/1.DHFV5XMT.js +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/immutable/nodes/2.CRPCjhHz.js +33 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/_app/version.json +1 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/favicon.svg +11 -0
- dictare-0.1.140rc1/src/dictare/ui/dist/index.html +49 -0
- dictare-0.1.140rc1/src/dictare/utils/__init__.py +1 -0
- dictare-0.1.140rc1/src/dictare/utils/hardware.py +248 -0
- dictare-0.1.140rc1/src/dictare/utils/hf_download.py +217 -0
- dictare-0.1.140rc1/src/dictare/utils/install_info.py +157 -0
- dictare-0.1.140rc1/src/dictare/utils/jellyfish.py +265 -0
- dictare-0.1.140rc1/src/dictare/utils/loading.py +128 -0
- dictare-0.1.140rc1/src/dictare/utils/paths.py +15 -0
- dictare-0.1.140rc1/src/dictare/utils/platform.py +744 -0
- dictare-0.1.140rc1/src/dictare/utils/state.py +102 -0
- dictare-0.1.140rc1/src/dictare/utils/stats.py +246 -0
- dictare-0.1.140rc1/tests/__init__.py +1 -0
- dictare-0.1.140rc1/tests/conftest.py +160 -0
- dictare-0.1.140rc1/tests/test_agent_template.py +375 -0
- dictare-0.1.140rc1/tests/test_audio_devices.py +446 -0
- dictare-0.1.140rc1/tests/test_claim_agent.py +241 -0
- dictare-0.1.140rc1/tests/test_cli.py +194 -0
- dictare-0.1.140rc1/tests/test_cli_status.py +109 -0
- dictare-0.1.140rc1/tests/test_code_quality_fixes.py +288 -0
- dictare-0.1.140rc1/tests/test_config.py +273 -0
- dictare-0.1.140rc1/tests/test_controller.py +805 -0
- dictare-0.1.140rc1/tests/test_device_monitor.py +692 -0
- dictare-0.1.140rc1/tests/test_engine.py +1765 -0
- dictare-0.1.140rc1/tests/test_event_bus.py +207 -0
- dictare-0.1.140rc1/tests/test_executor_agent_switch.py +70 -0
- dictare-0.1.140rc1/tests/test_executor_submit.py +87 -0
- dictare-0.1.140rc1/tests/test_feedback_policy.py +128 -0
- dictare-0.1.140rc1/tests/test_fsm.py +450 -0
- dictare-0.1.140rc1/tests/test_hardware.py +124 -0
- dictare-0.1.140rc1/tests/test_hotkey_ipc.py +55 -0
- dictare-0.1.140rc1/tests/test_http_server.py +324 -0
- dictare-0.1.140rc1/tests/test_logging.py +228 -0
- dictare-0.1.140rc1/tests/test_loop_audio.py +215 -0
- dictare-0.1.140rc1/tests/test_messages.py +63 -0
- dictare-0.1.140rc1/tests/test_mode_switch.py +226 -0
- dictare-0.1.140rc1/tests/test_model_cache.py +99 -0
- dictare-0.1.140rc1/tests/test_mute.py +264 -0
- dictare-0.1.140rc1/tests/test_mux_focus.py +71 -0
- dictare-0.1.140rc1/tests/test_mux_session.py +323 -0
- dictare-0.1.140rc1/tests/test_onnx_asr_contract.py +52 -0
- dictare-0.1.140rc1/tests/test_openvip_internal.py +263 -0
- dictare-0.1.140rc1/tests/test_openvip_protocol.py +1144 -0
- dictare-0.1.140rc1/tests/test_panel.py +92 -0
- dictare-0.1.140rc1/tests/test_parakeet_engine.py +110 -0
- dictare-0.1.140rc1/tests/test_permission_doctor.py +57 -0
- dictare-0.1.140rc1/tests/test_pipeline.py +907 -0
- dictare-0.1.140rc1/tests/test_pipeline_loader.py +242 -0
- dictare-0.1.140rc1/tests/test_race_conditions.py +367 -0
- dictare-0.1.140rc1/tests/test_sdk_extension_fields.py +185 -0
- dictare-0.1.140rc1/tests/test_service.py +443 -0
- dictare-0.1.140rc1/tests/test_settings_api.py +430 -0
- dictare-0.1.140rc1/tests/test_single_instance.py +92 -0
- dictare-0.1.140rc1/tests/test_sse_agent.py +651 -0
- dictare-0.1.140rc1/tests/test_state.py +360 -0
- dictare-0.1.140rc1/tests/test_stats.py +225 -0
- dictare-0.1.140rc1/tests/test_status.py +89 -0
- dictare-0.1.140rc1/tests/test_status_bar.py +245 -0
- dictare-0.1.140rc1/tests/test_status_health.py +132 -0
- dictare-0.1.140rc1/tests/test_tap_detector.py +454 -0
- dictare-0.1.140rc1/tests/test_toml_sections.py +345 -0
- dictare-0.1.140rc1/tests/test_tray.py +297 -0
- dictare-0.1.140rc1/tests/test_tts_cache.py +298 -0
- dictare-0.1.140rc1/tests/test_tts_kokoro.py +123 -0
- dictare-0.1.140rc1/tests/test_tts_venv.py +283 -0
- dictare-0.1.140rc1/tests/test_tts_worker.py +306 -0
- dictare-0.1.140rc1/ui/components.json +16 -0
- dictare-0.1.140rc1/ui/package.json +39 -0
- dictare-0.1.140rc1/ui/pnpm-lock.yaml +1909 -0
- dictare-0.1.140rc1/ui/postcss.config.js +6 -0
- dictare-0.1.140rc1/ui/src/app.css +60 -0
- dictare-0.1.140rc1/ui/src/app.d.ts +2 -0
- dictare-0.1.140rc1/ui/src/app.html +22 -0
- dictare-0.1.140rc1/ui/src/lib/api.ts +406 -0
- dictare-0.1.140rc1/ui/src/lib/components/dashboard/DashboardPage.svelte +282 -0
- dictare-0.1.140rc1/ui/src/lib/components/models/ModelsPage.svelte +337 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/EngineStatusBar.svelte +125 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/FieldRenderer.svelte +219 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/SaveBar.svelte +39 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/SettingsLayout.svelte +352 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/SettingsNav.svelte +143 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/SettingsSection.svelte +60 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/BoolField.svelte +15 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/ComplexField.svelte +8 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/KeyCaptureField.svelte +241 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/NumberField.svelte +39 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/SelectField.svelte +112 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/ShortcutsField.svelte +108 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/StringField.svelte +26 -0
- dictare-0.1.140rc1/ui/src/lib/components/settings/fields/TomlField.svelte +171 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/badge/badge.svelte +50 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/badge/index.ts +2 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/button/button.svelte +74 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/button/index.ts +17 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/card/card-content.svelte +16 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/card/card-description.svelte +16 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/card/card-footer.svelte +16 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/card/card-header.svelte +16 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/card/card-title.svelte +25 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/card/card.svelte +20 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/card/index.ts +22 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/input/index.ts +7 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/input/input.svelte +46 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/label/index.ts +7 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/label/label.svelte +19 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/select/index.ts +13 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/select/select-content.svelte +28 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/select/select-item.svelte +32 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/select/select-trigger.svelte +28 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/separator/index.ts +7 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/separator/separator.svelte +22 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/switch/index.ts +1 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/switch/switch.svelte +27 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/tooltip/index.ts +18 -0
- dictare-0.1.140rc1/ui/src/lib/components/ui/tooltip/tooltip-content.svelte +21 -0
- dictare-0.1.140rc1/ui/src/lib/registry/field-config.ts +84 -0
- dictare-0.1.140rc1/ui/src/lib/registry/tabs.ts +88 -0
- dictare-0.1.140rc1/ui/src/lib/schema.ts +40 -0
- dictare-0.1.140rc1/ui/src/lib/stores/presets.svelte.ts +2 -0
- dictare-0.1.140rc1/ui/src/lib/stores/settings.svelte.ts +279 -0
- dictare-0.1.140rc1/ui/src/lib/stores/tab-guard.svelte.ts +32 -0
- dictare-0.1.140rc1/ui/src/lib/stores/theme.svelte.ts +21 -0
- dictare-0.1.140rc1/ui/src/lib/types.ts +60 -0
- dictare-0.1.140rc1/ui/src/lib/utils.ts +6 -0
- dictare-0.1.140rc1/ui/src/routes/+layout.svelte +10 -0
- dictare-0.1.140rc1/ui/src/routes/+page.svelte +22 -0
- dictare-0.1.140rc1/ui/static/favicon.svg +11 -0
- dictare-0.1.140rc1/ui/svelte.config.js +19 -0
- dictare-0.1.140rc1/ui/tailwind.config.js +62 -0
- dictare-0.1.140rc1/ui/tsconfig.json +14 -0
- dictare-0.1.140rc1/ui/vite.config.ts +13 -0
- dictare-0.1.140rc1/uv.lock +1961 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Exclude dev artifacts from test builds
|
|
2
|
+
.venv/
|
|
3
|
+
.git/
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.pyc
|
|
6
|
+
*.egg-info/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.mypy_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
|
|
13
|
+
# Config/data
|
|
14
|
+
.env
|
|
15
|
+
*.log
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.vscode/
|
|
19
|
+
.idea/
|
|
20
|
+
|
|
21
|
+
# Test outputs
|
|
22
|
+
/scripts/test-distros/*.log
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a bug to help us improve dictare
|
|
4
|
+
title: ''
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
A clear and concise description of the bug.
|
|
12
|
+
|
|
13
|
+
## Steps to Reproduce
|
|
14
|
+
|
|
15
|
+
1. Run `dictare listen`
|
|
16
|
+
2. Do '...'
|
|
17
|
+
3. See error
|
|
18
|
+
|
|
19
|
+
## Expected Behavior
|
|
20
|
+
|
|
21
|
+
What you expected to happen.
|
|
22
|
+
|
|
23
|
+
## Actual Behavior
|
|
24
|
+
|
|
25
|
+
What actually happened.
|
|
26
|
+
|
|
27
|
+
## Environment
|
|
28
|
+
|
|
29
|
+
- **OS**: [e.g., macOS 14.0, Ubuntu 24.04]
|
|
30
|
+
- **Architecture**: [e.g., Apple Silicon M1, x86_64]
|
|
31
|
+
- **Python version**: [e.g., 3.11.5]
|
|
32
|
+
- **dictare version**: [run `dictare --version`]
|
|
33
|
+
- **Installation method**: [e.g., install.sh, uv tool install, pip]
|
|
34
|
+
|
|
35
|
+
## Logs
|
|
36
|
+
|
|
37
|
+
<details>
|
|
38
|
+
<summary>Output of `dictare check`</summary>
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
[paste output here]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
</details>
|
|
45
|
+
|
|
46
|
+
<details>
|
|
47
|
+
<summary>Error messages or logs</summary>
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
[paste any error messages here]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
</details>
|
|
54
|
+
|
|
55
|
+
## Additional Context
|
|
56
|
+
|
|
57
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for dictare
|
|
4
|
+
title: ''
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem Statement
|
|
10
|
+
|
|
11
|
+
A clear and concise description of the problem or limitation you're experiencing.
|
|
12
|
+
|
|
13
|
+
Example: "I'm always frustrated when [...]"
|
|
14
|
+
|
|
15
|
+
## Proposed Solution
|
|
16
|
+
|
|
17
|
+
A clear and concise description of what you want to happen.
|
|
18
|
+
|
|
19
|
+
## Alternatives Considered
|
|
20
|
+
|
|
21
|
+
A description of any alternative solutions or features you've considered.
|
|
22
|
+
|
|
23
|
+
## Use Case
|
|
24
|
+
|
|
25
|
+
Describe your use case and how this feature would help you.
|
|
26
|
+
|
|
27
|
+
## Additional Context
|
|
28
|
+
|
|
29
|
+
Add any other context, mockups, or examples about the feature request here.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- Brief description of what this PR does -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- List the main changes in this PR -->
|
|
8
|
+
|
|
9
|
+
-
|
|
10
|
+
|
|
11
|
+
## Test Plan
|
|
12
|
+
|
|
13
|
+
<!-- How did you test these changes? -->
|
|
14
|
+
|
|
15
|
+
- [ ] Ran `uv run pytest tests/`
|
|
16
|
+
- [ ] Ran `uv run ruff check .`
|
|
17
|
+
- [ ] Tested manually with `dictare listen`
|
|
18
|
+
|
|
19
|
+
## Checklist
|
|
20
|
+
|
|
21
|
+
- [ ] I have read the [CONTRIBUTING](../CONTRIBUTING.md) guidelines
|
|
22
|
+
- [ ] My code follows the project's code style
|
|
23
|
+
- [ ] I have added tests for my changes (if applicable)
|
|
24
|
+
- [ ] I have updated the documentation (if applicable)
|
|
25
|
+
- [ ] I have updated CHANGELOG.md (if applicable)
|
|
26
|
+
|
|
27
|
+
## Related Issues
|
|
28
|
+
|
|
29
|
+
<!-- Link to any related issues: Fixes #123, Closes #456 -->
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
name: "0 - release: sign launcher"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
build-sign-notarize:
|
|
8
|
+
runs-on: macos-latest
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
# Fetch secrets from Infisical (single token, all secrets centralized)
|
|
15
|
+
- name: Load secrets from Infisical
|
|
16
|
+
env:
|
|
17
|
+
INFISICAL_TOKEN: ${{ secrets.INFISICAL_TOKEN }}
|
|
18
|
+
run: |
|
|
19
|
+
brew install infisical/get-cli/infisical
|
|
20
|
+
# Export secrets as JSON → write to GITHUB_ENV + mask values
|
|
21
|
+
# Note: cannot use IFS='=' because base64 values contain '=' padding
|
|
22
|
+
infisical export \
|
|
23
|
+
--domain "https://eu.infisical.com" \
|
|
24
|
+
--projectId "7d6c2573-e67b-4243-9911-0a9ddaed58b8" \
|
|
25
|
+
--path "/work/dictare/app/ci" \
|
|
26
|
+
--env prod \
|
|
27
|
+
--format json | \
|
|
28
|
+
jq -c '.[]' | while read -r item; do
|
|
29
|
+
key=$(echo "$item" | jq -r '.key')
|
|
30
|
+
value=$(echo "$item" | jq -r '.value')
|
|
31
|
+
# Mask each line separately (multiline values like PEM keys)
|
|
32
|
+
while IFS= read -r line; do
|
|
33
|
+
[[ -n "$line" ]] && echo "::add-mask::$line"
|
|
34
|
+
done <<< "$value"
|
|
35
|
+
# Use heredoc for multiline values (e.g. PEM keys)
|
|
36
|
+
EOF_MARKER="EOF_$(head -c 8 /dev/urandom | xxd -p)"
|
|
37
|
+
echo "$key<<$EOF_MARKER" >> "$GITHUB_ENV"
|
|
38
|
+
echo "$value" >> "$GITHUB_ENV"
|
|
39
|
+
echo "$EOF_MARKER" >> "$GITHUB_ENV"
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
# Verify secrets were loaded
|
|
43
|
+
- name: Verify secrets
|
|
44
|
+
run: |
|
|
45
|
+
missing=()
|
|
46
|
+
for var in APPLE_DEVELOPER_ID_P12 APPLE_DEVELOPER_ID_P12_PASSWORD \
|
|
47
|
+
APPLE_NOTARIZATION_DICTARE_KEY APPLE_NOTARIZATION_DICTARE_KEY_ID \
|
|
48
|
+
APPLE_NOTARIZATION_ISSUER_ID; do
|
|
49
|
+
if [[ -z "${!var:-}" ]]; then
|
|
50
|
+
missing+=("$var")
|
|
51
|
+
else
|
|
52
|
+
val="${!var}"
|
|
53
|
+
echo "✓ $var is set (${#val} chars)"
|
|
54
|
+
fi
|
|
55
|
+
done
|
|
56
|
+
if [[ ${#missing[@]} -gt 0 ]]; then
|
|
57
|
+
echo "::error::Missing secrets: ${missing[*]}"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Import Developer ID certificate into a temporary keychain
|
|
62
|
+
- name: Import signing certificate
|
|
63
|
+
run: |
|
|
64
|
+
KEYCHAIN="$RUNNER_TEMP/signing.keychain-db"
|
|
65
|
+
security create-keychain -p "" "$KEYCHAIN"
|
|
66
|
+
security set-keychain-settings -lut 21600 "$KEYCHAIN"
|
|
67
|
+
echo "$APPLE_DEVELOPER_ID_P12" | base64 -d > "$RUNNER_TEMP/cert.p12"
|
|
68
|
+
security import "$RUNNER_TEMP/cert.p12" -k "$KEYCHAIN" \
|
|
69
|
+
-P "$APPLE_DEVELOPER_ID_P12_PASSWORD" -T /usr/bin/codesign
|
|
70
|
+
security set-key-partition-list -S apple-tool:,apple: \
|
|
71
|
+
-s -k "" "$KEYCHAIN"
|
|
72
|
+
security list-keychains -d user -s "$KEYCHAIN" login.keychain
|
|
73
|
+
|
|
74
|
+
# Build universal binary + sign with Hardened Runtime
|
|
75
|
+
- name: Build and sign launcher
|
|
76
|
+
run: |
|
|
77
|
+
DICTARE_SIGN_IDENTITY="Developer ID Application" \
|
|
78
|
+
./scripts/macos/sign-launcher.sh
|
|
79
|
+
|
|
80
|
+
# Assemble the complete .app bundle (binary + Info.plist + icon)
|
|
81
|
+
# python_path is NOT inside the bundle — the launcher reads it from
|
|
82
|
+
# ~/.dictare/python_path at runtime, so the signed bundle stays immutable.
|
|
83
|
+
- name: Assemble .app bundle
|
|
84
|
+
run: |
|
|
85
|
+
VERSION=$(grep -E '^__version__' src/dictare/__init__.py | sed 's/.*"\(.*\)"/\1/')
|
|
86
|
+
BUNDLE="build/bundle/Dictare.app"
|
|
87
|
+
CONTENTS="$BUNDLE/Contents"
|
|
88
|
+
MACOS_DIR="$CONTENTS/MacOS"
|
|
89
|
+
RESOURCES_DIR="$CONTENTS/Resources"
|
|
90
|
+
|
|
91
|
+
mkdir -p "$MACOS_DIR" "$RESOURCES_DIR"
|
|
92
|
+
|
|
93
|
+
# Binary
|
|
94
|
+
cp build/launcher/Dictare "$MACOS_DIR/Dictare"
|
|
95
|
+
|
|
96
|
+
# Info.plist
|
|
97
|
+
/usr/libexec/PlistBuddy -c "Clear dict" "$CONTENTS/Info.plist" 2>/dev/null || true
|
|
98
|
+
cat > "$CONTENTS/Info.plist" << 'PLIST'
|
|
99
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
100
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
101
|
+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
102
|
+
<plist version="1.0">
|
|
103
|
+
<dict>
|
|
104
|
+
<key>CFBundleName</key>
|
|
105
|
+
<string>Dictare</string>
|
|
106
|
+
<key>CFBundleDisplayName</key>
|
|
107
|
+
<string>Dictare</string>
|
|
108
|
+
<key>CFBundleIdentifier</key>
|
|
109
|
+
<string>dev.dragfly.dictare</string>
|
|
110
|
+
<key>CFBundleVersion</key>
|
|
111
|
+
<string>VERSION_PLACEHOLDER</string>
|
|
112
|
+
<key>CFBundleShortVersionString</key>
|
|
113
|
+
<string>VERSION_PLACEHOLDER</string>
|
|
114
|
+
<key>CFBundlePackageType</key>
|
|
115
|
+
<string>APPL</string>
|
|
116
|
+
<key>CFBundleExecutable</key>
|
|
117
|
+
<string>Dictare</string>
|
|
118
|
+
<key>CFBundleIconFile</key>
|
|
119
|
+
<string>Dictare</string>
|
|
120
|
+
<key>LSUIElement</key>
|
|
121
|
+
<true/>
|
|
122
|
+
<key>NSMicrophoneUsageDescription</key>
|
|
123
|
+
<string>Dictare needs microphone access for voice-to-text.</string>
|
|
124
|
+
<key>NSInputMonitoringUsageDescription</key>
|
|
125
|
+
<string>Dictare uses Input Monitoring to detect the global Right ⌘ hotkey.</string>
|
|
126
|
+
</dict>
|
|
127
|
+
</plist>
|
|
128
|
+
PLIST
|
|
129
|
+
# Inject actual version
|
|
130
|
+
sed -i '' "s/VERSION_PLACEHOLDER/$VERSION/g" "$CONTENTS/Info.plist"
|
|
131
|
+
|
|
132
|
+
# Icon
|
|
133
|
+
cp src/dictare/resources/Dictare.icns "$RESOURCES_DIR/Dictare.icns"
|
|
134
|
+
|
|
135
|
+
# Launcher metadata — stored in Resources/ (not MacOS/) because
|
|
136
|
+
# codesign requires all files in MacOS/ to be signed Mach-O binaries.
|
|
137
|
+
HASH=$(shasum -a 256 src/dictare/resources/launcher.swift | cut -c1-16)
|
|
138
|
+
echo "$HASH" > "$RESOURCES_DIR/launcher_hash"
|
|
139
|
+
echo "true" > "$RESOURCES_DIR/launcher_signed"
|
|
140
|
+
|
|
141
|
+
echo "==> Bundle assembled: $BUNDLE (version $VERSION)"
|
|
142
|
+
ls -laR "$BUNDLE"
|
|
143
|
+
|
|
144
|
+
# Sign the complete .app bundle (not just the binary)
|
|
145
|
+
- name: Sign bundle
|
|
146
|
+
run: |
|
|
147
|
+
codesign --force --options runtime \
|
|
148
|
+
--entitlements src/dictare/resources/Dictare.entitlements \
|
|
149
|
+
--sign "Developer ID Application" \
|
|
150
|
+
build/bundle/Dictare.app
|
|
151
|
+
codesign --verify --strict build/bundle/Dictare.app
|
|
152
|
+
echo "==> Bundle signed and verified"
|
|
153
|
+
|
|
154
|
+
# Notarize the complete bundle
|
|
155
|
+
- name: Notarize
|
|
156
|
+
run: |
|
|
157
|
+
echo "$APPLE_NOTARIZATION_DICTARE_KEY" > "$RUNNER_TEMP/AuthKey.p8"
|
|
158
|
+
ditto -c -k --keepParent build/bundle/Dictare.app build/bundle/Dictare.app.zip
|
|
159
|
+
xcrun notarytool submit build/bundle/Dictare.app.zip \
|
|
160
|
+
--key "$RUNNER_TEMP/AuthKey.p8" \
|
|
161
|
+
--key-id "$APPLE_NOTARIZATION_DICTARE_KEY_ID" \
|
|
162
|
+
--issuer "$APPLE_NOTARIZATION_ISSUER_ID" \
|
|
163
|
+
--wait --timeout 10m
|
|
164
|
+
|
|
165
|
+
# Staple the notarization ticket to the bundle
|
|
166
|
+
- name: Staple
|
|
167
|
+
run: |
|
|
168
|
+
xcrun stapler staple build/bundle/Dictare.app
|
|
169
|
+
echo "==> Notarization ticket stapled"
|
|
170
|
+
|
|
171
|
+
# Upload to the fixed "launcher" release tag (version-independent)
|
|
172
|
+
- name: Upload to launcher release
|
|
173
|
+
env:
|
|
174
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
175
|
+
run: |
|
|
176
|
+
ZIP="Dictare-launcher-universal.zip"
|
|
177
|
+
# ditto -c -k on a directory zips its CONTENTS, losing the .app
|
|
178
|
+
# wrapper. Use -keepParent to preserve the Dictare.app directory
|
|
179
|
+
# so extraction yields Dictare.app/Contents/... as expected.
|
|
180
|
+
ditto -c -k --keepParent build/bundle/Dictare.app "$ZIP"
|
|
181
|
+
# Create or update the fixed "launcher" release.
|
|
182
|
+
# First try to upload to existing release; if it doesn't exist, create it.
|
|
183
|
+
if gh release view "launcher" &>/dev/null; then
|
|
184
|
+
gh release upload "launcher" "$ZIP" --clobber
|
|
185
|
+
else
|
|
186
|
+
gh release create "launcher" "$ZIP" \
|
|
187
|
+
--title "Universal Dictare Launcher" \
|
|
188
|
+
--notes "Pre-built signed + notarized Dictare.app bundle. Downloaded automatically by install.sh."
|
|
189
|
+
fi
|
|
190
|
+
echo "==> Uploaded $ZIP to 'launcher' release"
|
|
191
|
+
|
|
192
|
+
# Upload as artifact (always, for manual builds)
|
|
193
|
+
- name: Upload artifact
|
|
194
|
+
uses: actions/upload-artifact@v4
|
|
195
|
+
with:
|
|
196
|
+
name: Dictare-launcher-universal
|
|
197
|
+
path: build/bundle/Dictare.app
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: "auto: test macOS"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 4 * * *" # daily at 04:00 UTC
|
|
6
|
+
workflow_dispatch: # allow manual trigger from GitHub UI
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test-macos:
|
|
10
|
+
runs-on: macos-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Install uv
|
|
15
|
+
uses: astral-sh/setup-uv@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python and install deps
|
|
18
|
+
run: |
|
|
19
|
+
uv venv --python 3.11 --seed .venv
|
|
20
|
+
echo "VIRTUAL_ENV=$PWD/.venv" >> $GITHUB_ENV
|
|
21
|
+
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
|
22
|
+
.venv/bin/pip install -e ".[dev]"
|
|
23
|
+
|
|
24
|
+
- name: Run CoreAudio tests
|
|
25
|
+
run: pytest tests/ -v -m macos
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: "auto: test + lint"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["*"] # Run on all branches
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.11"
|
|
18
|
+
cache: pip
|
|
19
|
+
cache-dependency-path: pyproject.toml
|
|
20
|
+
|
|
21
|
+
- name: Install system deps
|
|
22
|
+
run: sudo apt-get install -y libportaudio2 xvfb
|
|
23
|
+
|
|
24
|
+
- name: Install deps
|
|
25
|
+
run: pip install -e ".[dev]"
|
|
26
|
+
|
|
27
|
+
- name: Run linter
|
|
28
|
+
run: ruff check src/ tests/
|
|
29
|
+
|
|
30
|
+
- name: Run tests with coverage
|
|
31
|
+
run: xvfb-run pytest tests/ -v -m '' --cov=dictare --cov-report=term-missing
|
|
32
|
+
|
|
33
|
+
typecheck:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
|
|
38
|
+
- uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.11"
|
|
41
|
+
cache: pip
|
|
42
|
+
cache-dependency-path: pyproject.toml
|
|
43
|
+
|
|
44
|
+
- name: Install deps
|
|
45
|
+
run: pip install -e ".[dev]"
|
|
46
|
+
|
|
47
|
+
- name: Run mypy
|
|
48
|
+
run: mypy src/
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: "claude: issue dedupe"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [opened]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
issue_number:
|
|
9
|
+
description: Issue number to check for duplicates
|
|
10
|
+
required: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
dedupe:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
timeout-minutes: 10
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
issues: write
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Run Claude Code for Deduplication
|
|
23
|
+
timeout-minutes: 8
|
|
24
|
+
uses: anthropics/claude-code-action@v1
|
|
25
|
+
env:
|
|
26
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
27
|
+
GH_REPO: ${{ github.repository }}
|
|
28
|
+
with:
|
|
29
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
30
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
31
|
+
claude_args: "--model claude-sonnet-4-6"
|
|
32
|
+
prompt: |
|
|
33
|
+
Check if this issue is a duplicate for the dictare project.
|
|
34
|
+
|
|
35
|
+
REPO: ${{ github.repository }}
|
|
36
|
+
ISSUE_NUMBER: ${{ github.event.issue.number || github.event.inputs.issue_number }}
|
|
37
|
+
|
|
38
|
+
Instructions:
|
|
39
|
+
1. Read the new issue
|
|
40
|
+
2. Search existing issues for similar ones (use gh issue list --state all --limit 200)
|
|
41
|
+
3. If a duplicate is found:
|
|
42
|
+
- Comment on the new issue linking to the original: "Duplicate of #NNN"
|
|
43
|
+
- Add the label "duplicate"
|
|
44
|
+
- Do NOT close it (the maintainer will decide)
|
|
45
|
+
4. If no duplicate, do nothing (no comment needed)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: "claude: issue triage"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [opened]
|
|
6
|
+
issue_comment:
|
|
7
|
+
types: [created]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
triage-issue:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 10
|
|
13
|
+
if: >-
|
|
14
|
+
github.event_name == 'issues' ||
|
|
15
|
+
(github.event_name == 'issue_comment' && !github.event.issue.pull_request && github.event.comment.user.type != 'Bot')
|
|
16
|
+
concurrency:
|
|
17
|
+
group: issue-triage-${{ github.event.issue.number }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
issues: write
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Run Claude Code for Issue Triage
|
|
26
|
+
timeout-minutes: 5
|
|
27
|
+
uses: anthropics/claude-code-action@v1
|
|
28
|
+
env:
|
|
29
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
30
|
+
GH_REPO: ${{ github.repository }}
|
|
31
|
+
with:
|
|
32
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
33
|
+
allowed_non_write_users: "*"
|
|
34
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
35
|
+
claude_args: "--model claude-sonnet-4-6"
|
|
36
|
+
prompt: |
|
|
37
|
+
Triage this GitHub issue for the dictare project (voice-first control for AI coding agents).
|
|
38
|
+
|
|
39
|
+
REPO: ${{ github.repository }}
|
|
40
|
+
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
41
|
+
EVENT: ${{ github.event_name }}
|
|
42
|
+
|
|
43
|
+
Instructions:
|
|
44
|
+
1. Read the issue carefully using the GitHub CLI
|
|
45
|
+
2. Add the appropriate label(s): bug, enhancement, question, documentation, good first issue
|
|
46
|
+
3. If it's a bug, ask for: OS (macOS/Linux), dictare version, steps to reproduce
|
|
47
|
+
4. If it's a feature request, acknowledge it and explain where it fits in the roadmap
|
|
48
|
+
5. If it's a question, answer it directly if possible or point to the README/docs
|
|
49
|
+
6. Be concise and friendly. Sign off as "dictare bot"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: "claude: pr review"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
review:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
timeout-minutes: 15
|
|
11
|
+
# Skip PRs from the maintainer (manual review) and bots
|
|
12
|
+
if: |
|
|
13
|
+
github.event.pull_request.user.login != 'twisteroo' &&
|
|
14
|
+
github.event.pull_request.user.type != 'Bot'
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
pull-requests: write
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
|
|
23
|
+
- name: Run Claude Code for PR Review
|
|
24
|
+
timeout-minutes: 10
|
|
25
|
+
uses: anthropics/claude-code-action@v1
|
|
26
|
+
env:
|
|
27
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
28
|
+
GH_REPO: ${{ github.repository }}
|
|
29
|
+
with:
|
|
30
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
32
|
+
claude_args: "--model claude-sonnet-4-6"
|
|
33
|
+
prompt: |
|
|
34
|
+
Review this pull request for the dictare project.
|
|
35
|
+
|
|
36
|
+
REPO: ${{ github.repository }}
|
|
37
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
38
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
39
|
+
AUTHOR: ${{ github.event.pull_request.user.login }}
|
|
40
|
+
BASE_BRANCH: ${{ github.event.pull_request.base.ref }}
|
|
41
|
+
|
|
42
|
+
Dictare is a voice-first control layer for AI coding agents (Claude Code, Cursor, etc.).
|
|
43
|
+
It implements the OpenVIP protocol. Python 3.11, FastAPI, Typer, uv.
|
|
44
|
+
|
|
45
|
+
Review instructions:
|
|
46
|
+
1. Read the PR diff using gh CLI
|
|
47
|
+
2. Check: code correctness, test coverage, docs updates, breaking changes
|
|
48
|
+
3. Verify CHANGELOG.md is updated if the change is user-visible
|
|
49
|
+
4. Check for security concerns (no credentials hardcoded, no unsafe operations)
|
|
50
|
+
5. Verify Python 3.11 compatibility and uv/ruff style compliance
|
|
51
|
+
6. Post a concise review comment with: summary of changes, specific feedback (if any),
|
|
52
|
+
and LGTM or requested changes
|
|
53
|
+
7. Add labels: "needs-review" if changes needed, "ready-to-merge" if LGTM
|
|
54
|
+
8. Be constructive and friendly. First-time contributors deserve extra encouragement.
|
|
55
|
+
9. Sign off as "dictare bot"
|
|
56
|
+
|
|
57
|
+
Keep the review focused — max 200 words unless there are real issues to flag.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: "claude: code"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issue_comment:
|
|
5
|
+
types: [created]
|
|
6
|
+
pull_request_review_comment:
|
|
7
|
+
types: [created]
|
|
8
|
+
pull_request_review:
|
|
9
|
+
types: [submitted]
|
|
10
|
+
issues:
|
|
11
|
+
types: [opened, assigned]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 10
|
|
17
|
+
if: |
|
|
18
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
19
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
20
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
21
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
pull-requests: read
|
|
25
|
+
issues: read
|
|
26
|
+
id-token: write
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: Run Claude Code
|
|
31
|
+
uses: anthropics/claude-code-action@v1
|
|
32
|
+
with:
|
|
33
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
34
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
35
|
+
claude_args: "--model claude-sonnet-4-6"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: "auto: lock issues"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 14 * * *" # daily at 14:00 UTC
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lock:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
issues: write
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/github-script@v7
|
|
15
|
+
with:
|
|
16
|
+
script: |
|
|
17
|
+
const sevenDaysAgo = new Date();
|
|
18
|
+
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
|
|
19
|
+
|
|
20
|
+
const issues = await github.paginate(github.rest.issues.listForRepo, {
|
|
21
|
+
owner: context.repo.owner,
|
|
22
|
+
repo: context.repo.repo,
|
|
23
|
+
state: 'closed',
|
|
24
|
+
sort: 'updated',
|
|
25
|
+
direction: 'asc',
|
|
26
|
+
per_page: 100,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
let locked = 0;
|
|
30
|
+
for (const issue of issues) {
|
|
31
|
+
if (issue.pull_request) continue;
|
|
32
|
+
if (issue.locked) continue;
|
|
33
|
+
if (new Date(issue.updated_at) > sevenDaysAgo) continue;
|
|
34
|
+
|
|
35
|
+
await github.rest.issues.createComment({
|
|
36
|
+
owner: context.repo.owner,
|
|
37
|
+
repo: context.repo.repo,
|
|
38
|
+
issue_number: issue.number,
|
|
39
|
+
body: 'This issue has been automatically locked since it has been closed ' +
|
|
40
|
+
'and had no activity for 7 days. If you are experiencing a similar ' +
|
|
41
|
+
'issue, please open a new one.',
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
await github.rest.issues.lock({
|
|
45
|
+
owner: context.repo.owner,
|
|
46
|
+
repo: context.repo.repo,
|
|
47
|
+
issue_number: issue.number,
|
|
48
|
+
lock_reason: 'resolved',
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
locked++;
|
|
52
|
+
}
|
|
53
|
+
console.log(`Locked ${locked} issues.`);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: "0 - release: publish to PyPI"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
publish:
|
|
8
|
+
name: Build and publish to PyPI
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
id-token: write # Required for Trusted Publisher (OIDC)
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.11"
|
|
21
|
+
|
|
22
|
+
- name: Install build tools
|
|
23
|
+
run: pip install build
|
|
24
|
+
|
|
25
|
+
- name: Build sdist and wheel
|
|
26
|
+
run: python -m build
|
|
27
|
+
|
|
28
|
+
- name: Publish to PyPI
|
|
29
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|