{"id":16538648,"url":"https://github.com/spyoungtech/voice-commander","last_synced_at":"2026-02-26T08:42:51.098Z","repository":{"id":144102101,"uuid":"133729324","full_name":"spyoungtech/voice-commander","owner":"spyoungtech","description":"cross-platform voice-activation hooks and keyboard macros","archived":false,"fork":false,"pushed_at":"2025-12-08T20:37:59.000Z","size":122,"stargazers_count":8,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-14T08:57:04.798Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spyoungtech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-05-16T22:25:53.000Z","updated_at":"2025-09-16T21:07:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"d5813b7b-226b-46a7-b163-c779b0d6c38b","html_url":"https://github.com/spyoungtech/voice-commander","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/spyoungtech/voice-commander","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fvoice-commander","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fvoice-commander/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fvoice-commander/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fvoice-commander/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spyoungtech","download_url":"https://codeload.github.com/spyoungtech/voice-commander/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fvoice-commander/sbom","scorecard":{"id":842946,"data":{"date":"2025-08-11","repo":{"name":"github.com/spyoungtech/voice-commander","commit":"167a840cca9a843e3c0cbd5e00ddce5a36a75426"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":-1,"reason":"Found no human activity in the last 14 changesets","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release.yaml:13","Warn: no topLevel permission defined: .github/workflows/release.yaml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/spyoungtech/voice-commander/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/spyoungtech/voice-commander/release.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/spyoungtech/voice-commander/release.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/spyoungtech/voice-commander/release.yaml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/release.yaml:25","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":4,"reason":"5 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.0.3 not signed: https://api.github.com/repos/spyoungtech/voice-commander/releases/159446760","Warn: release artifact v0.0.2 not signed: https://api.github.com/repos/spyoungtech/voice-commander/releases/158737646","Warn: release artifact 0.0.1a0 not signed: https://api.github.com/repos/spyoungtech/voice-commander/releases/12404425","Warn: release artifact v0.0.3 does not have provenance: https://api.github.com/repos/spyoungtech/voice-commander/releases/159446760","Warn: release artifact v0.0.2 does not have provenance: https://api.github.com/repos/spyoungtech/voice-commander/releases/158737646","Warn: release artifact 0.0.1a0 does not have provenance: https://api.github.com/repos/spyoungtech/voice-commander/releases/12404425"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":2,"reason":"8 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2021-47 / GHSA-5jqp-qgf6-3pvh","Warn: Project is vulnerable to: GHSA-mr82-8j83-vxmv","Warn: Project is vulnerable to: PYSEC-2021-142 / GHSA-8q59-q68h-6hv4","Warn: Project is vulnerable to: PYSEC-2018-49 / GHSA-rprw-h62v-c2w7","Warn: Project is vulnerable to: PYSEC-2013-22 / GHSA-27x4-j476-jp5f","Warn: Project is vulnerable to: PYSEC-2025-49 / GHSA-5rjg-fvgr-3xxf","Warn: Project is vulnerable to: GHSA-cx63-2mw6-8hw5","Warn: Project is vulnerable to: PYSEC-2022-43012 / GHSA-r9hx-vwmv-q579"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T20:51:58.472Z","repository_id":144102101,"created_at":"2025-08-23T20:51:58.473Z","updated_at":"2025-08-23T20:51:58.473Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29854194,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-25T22:37:40.667Z","status":"online","status_checked_at":"2026-02-26T02:00:06.774Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T18:46:15.487Z","updated_at":"2026-02-26T08:42:51.083Z","avatar_url":"https://github.com/spyoungtech.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# voice-commander\n\nAn application for defining macros and triggers using voice commands and hotkeys. Inspired by the popular commercial\nsoftware [VoiceAttack](https://www.voiceattack.com/).\n\n**Requires Python 3.12+**\n\nThis is a major rewrite of a pre-existing project. If you're looking for the older version of this software, see the [pre-rewrite tag](https://github.com/spyoungtech/voice-commander/releases/tag/pre-rewrite) (or the now-yanked `0.0.1a` version on PyPI).\n\n## Installation\n\n### Via pip\n\nTo install, ideally in a virtualenv, use `pip`:\n\n```bash\npip install voice-commander\n```\n\nThis software also requires that you have AutoHotkey installed. You can either install AutoHotkey to a default location or, alternatively, install the `ahk-binary` package in your virtualenv:\n\n```bash\npip install ahk-binary\n```\n\n### Windows executable\n\nComing soon.\n\n\n## Usage\n\nThe basic primitives include **profiles**, **triggers**, **actions**, and **conditions**.\n\n- An **action** defines the underlying action is to be performed upon triggering, such as pressing a keyboard key, playing a sound, opening a program, etc.\n- A **trigger** is used to trigger an associated set of _actions_. For example, speaking a voice activation phrase, pressing a hotkey combination (like win+n), or similar. A trigger may trigger any number of _actions_.\n- A **condition** is used to conditionally control execution of a trigger or any specific action within a trigger. For example, you may only want an action to perform a key press to actually activate when a specific window (like a game) is open/focused. A trigger may be attached to a _trigger_ or an _action_.\n- A **profile** is a collection of triggers (and their associated actions/conditions) which can be activated/deactivated together for convenience.\n\n### Basic example\n\nYou can define and run profiles in Python code.\n\n\n```python\nfrom voice_commander.profile import Profile\nfrom voice_commander.triggers import *\nfrom voice_commander.actions import *\n\nprofile = Profile(\"myprofile\")\n\n# triggers when any of these phrases are spoken\n# You can add as many phrases as you want\ntrigger = VoiceTrigger('lower landing gear', 'retract landing gear')\n# When the above trigger activates from a voice command, presses the \"l\" button (bound in-game to landing gear toggle)\naction = AHKPressAction(\"l\")\ntrigger.add_action(action)  # you can add multiple actions if you want. Here, we're just adding one action.\nprofile.add_trigger(trigger)\n\nprofile.run()\n```\n\nYou can also serialize/deserialize profiles to/from JSON.\n\n```python\n# save the profile to the present working directory\nprofile.save_json(dirname='.', filename='myprofile.vcp.json')  # \"vcp\" means \"Voice Commander Profile\"\n```\n\n```python\nfrom voice_commander.profile import load_profile\n# easily load profiles from JSON\nprofile = load_profile('./myprofile.vcp.json')\nprofile.run()\n```\n\nYou may also edit and run JSON files which represent the complete profile directly. The above example produces a JSON file substantially as follows:\n\n```json\n{\n    \"configuration\": {\n        \"profile_name\": \"myprofile\",\n        \"schema_version\": \"0\",\n        \"triggers\": [\n            {\n                \"trigger_type\": \"voice_commander.triggers.VoiceTrigger\",\n                \"trigger_config\": {\n                    \"*trigger_phrases\": [\n                        \"lower landing gear\",\n                        \"retract landing gear\"\n                    ]\n                },\n                \"actions\": [\n                    {\n                        \"action_type\": \"voice_commander.actions.AHKPressAction\",\n                        \"action_config\": {\n                            \"key\": \"l\"\n                        }\n                    }\n                ]\n            }\n        ]\n    }\n}\n```\n\nJSON5 is also supported. More formats may be supported in the future.\n\nYou can run profiles from these files directly from the command line:\n\n```bash\npython -m voice_commander run-profile --profile-file ./myprofile.vcp.json\n```\n\n\nFull documentation coming soon.\n\n## Extending voice commander\n\nvoice-commander is being built with extension in mind. We don't have much to share here just yet, but you can check out\nthe [voice-commander-elite](https://github.com/spyoungtech/voice-commander-elite) project, which is an extension intended\nto provide special functionality for players of the game _Elite Dangerous_. It is currently being used as a guinea pig\nfor future extensions. `voice-commander-elite` may also give you ideas of the kinds of other extensions that may be possible.\n\n## Status\n\nThis project is in early stages of development, but is ready for use. Efforts will be made to keep existing\nprofile schemas compatible with (or convertable to) any future schema versions, though the Python API is likely to have\nsome breaking changes, at least while we're getting off the ground.\n\n\n### Current Limitations\n\nSome of the notable limitations of this software are as follows:\n\n- Can only read `X`, `Y`, `Z`, `R`, `U`, and `V` axes of Joystick controllers. Some special axes (such as the `Dial` of certain throttle controllers) cannot be used as a trigger\n- While controller/joystick inputs can be used for _triggering_ macros, we do not yet support _sending_ joystick or controller inputs in macros. You will, therefore, probably want to make sure you have keyboard bindings available for in-game actions.\n- Only wave audio files (`.wav`) are currently supported for playing sounds (and only supported on Windows)\n- Does not yet support XInput devices (e.g., Xbox One controllers) for triggers or sending\n- Requires `ahk` (and therefore also AutoHotkey, and Windows) for most meaningful functionality. Future versions will support Linux-friendly alternatives\n- Input interception (preventing the active program from receiving the input) is not supported for joystick/controller inputs.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspyoungtech%2Fvoice-commander","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspyoungtech%2Fvoice-commander","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspyoungtech%2Fvoice-commander/lists"}