@iamsamuelrodda/dictate 2026.5.18-1

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.
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@iamsamuelrodda/dictate",
3
+ "version": "2026.5.18-1",
4
+ "description": "Installer shim for Dictate desktop dictation.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "homepage": "https://github.com/arcforgelabs/dictate#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/arcforgelabs/dictate.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/arcforgelabs/dictate/issues"
14
+ },
15
+ "bin": {
16
+ "dictate-install": "npm/dictate-lifecycle.mjs",
17
+ "dictate-update": "npm/dictate-lifecycle.mjs",
18
+ "dictate-uninstall": "npm/dictate-lifecycle.mjs"
19
+ },
20
+ "files": [
21
+ "install.ps1",
22
+ "update.ps1",
23
+ "install-windows.ps1",
24
+ "install-windows-wizard.ps1",
25
+ "update-windows.ps1",
26
+ "uninstall.ps1",
27
+ "uninstall-windows.ps1",
28
+ "install.sh",
29
+ "update.sh",
30
+ "uninstall.sh",
31
+ "config/default-config.yaml",
32
+ "assets/dictate.ico",
33
+ "assets/dictate.png",
34
+ "assets/dictate-listening.ico",
35
+ "assets/dictate-listening.png",
36
+ "npm/",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "scripts": {
45
+ "pack:check": "npm pack --dry-run"
46
+ },
47
+ "engines": {
48
+ "node": ">=18"
49
+ }
50
+ }
@@ -0,0 +1,83 @@
1
+ param(
2
+ [switch]$Quiet,
3
+ [switch]$RemoveUserData
4
+ )
5
+
6
+ $ErrorActionPreference = "Stop"
7
+
8
+ function Remove-IfExists {
9
+ param([string]$Path)
10
+ if (Test-Path $Path) {
11
+ Remove-Item -Force -Path $Path
12
+ }
13
+ }
14
+
15
+ function Stop-DictateProcesses {
16
+ $currentPid = $PID
17
+ $matches = Get-CimInstance Win32_Process |
18
+ Where-Object {
19
+ $_.ProcessId -ne $currentPid -and (
20
+ $_.Name -in @("dictate.exe", "dictate-controls.exe") -or
21
+ $_.CommandLine -like '*dictate.exe* --type-backend pynput*' -or
22
+ $_.CommandLine -like '*pythonw.exe* -m dictate --type-backend pynput*' -or
23
+ $_.CommandLine -like '*dictate-daemon.cmd*' -or
24
+ $_.CommandLine -like '*dictate-controls*'
25
+ )
26
+ }
27
+ foreach ($match in $matches) {
28
+ Stop-Process -Id $match.ProcessId -Force -ErrorAction SilentlyContinue
29
+ }
30
+ Start-Sleep -Milliseconds 500
31
+ }
32
+
33
+ $programsDir = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs"
34
+ if (-not $env:APPDATA) {
35
+ $programsDir = Join-Path $HOME "AppData\Roaming\Microsoft\Windows\Start Menu\Programs"
36
+ }
37
+ $startupDir = Join-Path $programsDir "Startup"
38
+
39
+ Remove-IfExists -Path (Join-Path $programsDir "Dictate.lnk")
40
+ Remove-IfExists -Path (Join-Path $programsDir "Dictate Controls.lnk")
41
+ Remove-IfExists -Path (Join-Path $startupDir "Dictate.lnk")
42
+
43
+ $uninstallKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\Dictate"
44
+ if (Test-Path $uninstallKey) {
45
+ Remove-Item -Recurse -Force -Path $uninstallKey
46
+ }
47
+
48
+ Stop-DictateProcesses
49
+
50
+ $venvDir = Join-Path $PSScriptRoot ".venv"
51
+ if (Test-Path $venvDir) {
52
+ Remove-Item -Recurse -Force -Path $venvDir
53
+ }
54
+
55
+ $localAppData = $env:LOCALAPPDATA
56
+ if (-not $localAppData) {
57
+ $localAppData = Join-Path $HOME "AppData\Local"
58
+ }
59
+ $appData = $env:APPDATA
60
+ if (-not $appData) {
61
+ $appData = Join-Path $HOME "AppData\Roaming"
62
+ }
63
+ $dataDir = Join-Path $localAppData "dictate"
64
+ $configDir = Join-Path $appData "dictate"
65
+
66
+ if ($RemoveUserData) {
67
+ if (Test-Path $dataDir) {
68
+ Remove-Item -Recurse -Force -Path $dataDir
69
+ }
70
+ if (Test-Path $configDir) {
71
+ Remove-Item -Recurse -Force -Path $configDir
72
+ }
73
+ }
74
+
75
+ if (-not $Quiet) {
76
+ Write-Host "Dictate shortcuts, startup entry, app registration, and runtime venv removed."
77
+ if ($RemoveUserData) {
78
+ Write-Host "User config/data removed."
79
+ } else {
80
+ Write-Host "User config/data preserved. Re-run with -RemoveUserData to remove it."
81
+ }
82
+ Write-Host "Install source files were left in place: $PSScriptRoot"
83
+ }
package/uninstall.ps1 ADDED
@@ -0,0 +1,51 @@
1
+ param(
2
+ [string]$InstallRoot,
3
+ [switch]$Quiet,
4
+ [switch]$RemoveUserData
5
+ )
6
+
7
+ $ErrorActionPreference = "Stop"
8
+
9
+ if (-not $InstallRoot) {
10
+ $base = $env:LOCALAPPDATA
11
+ if (-not $base) {
12
+ $base = Join-Path $HOME "AppData\Local"
13
+ }
14
+ $InstallRoot = Join-Path $base "Dictate"
15
+ }
16
+
17
+ $installRootPath = [System.IO.Path]::GetFullPath($InstallRoot)
18
+ $sourceDir = Join-Path $installRootPath "source"
19
+ $uninstaller = Join-Path $sourceDir "uninstall-windows.ps1"
20
+
21
+ if (Test-Path $uninstaller) {
22
+ $args = @("-NoProfile", "-ExecutionPolicy", "Bypass", "-File", $uninstaller)
23
+ if ($Quiet) { $args += "-Quiet" }
24
+ if ($RemoveUserData) { $args += "-RemoveUserData" }
25
+ & powershell @args
26
+ if ($LASTEXITCODE -ne 0) {
27
+ throw "Dictate Windows uninstaller failed with exit code $LASTEXITCODE."
28
+ }
29
+ } else {
30
+ if (-not $Quiet) {
31
+ Write-Host "Dictate source uninstaller not found: $uninstaller"
32
+ Write-Host "Removing known Start Menu, startup, and Installed Apps entries."
33
+ }
34
+ $programsDir = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs"
35
+ if (-not $env:APPDATA) {
36
+ $programsDir = Join-Path $HOME "AppData\Roaming\Microsoft\Windows\Start Menu\Programs"
37
+ }
38
+ Remove-Item -Force -ErrorAction SilentlyContinue -Path `
39
+ (Join-Path $programsDir "Dictate.lnk"), `
40
+ (Join-Path $programsDir "Dictate Controls.lnk"), `
41
+ (Join-Path $programsDir "Startup\Dictate.lnk")
42
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\Dictate"
43
+ }
44
+
45
+ if (Test-Path $installRootPath) {
46
+ Remove-Item -Recurse -Force -Path $installRootPath
47
+ }
48
+
49
+ if (-not $Quiet) {
50
+ Write-Host "Dictate removed from: $installRootPath"
51
+ }
package/uninstall.sh ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env bash
2
+ # Remove Dictate launchers/autostart and installed runtime files.
3
+ set -euo pipefail
4
+
5
+ INSTALL_DIR="$HOME/.local/share/dictate"
6
+ BIN_PATH="$HOME/.local/bin/dictate"
7
+ DESKTOP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
8
+ AUTOSTART_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/autostart"
9
+ CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/dictate"
10
+ REMOVE_USER_DATA=0
11
+ QUIET=0
12
+
13
+ usage() {
14
+ cat <<EOF
15
+ Usage: $0 [--remove-user-data] [--quiet]
16
+
17
+ Removes Dictate launcher/autostart entries, ~/.local/bin/dictate, and the
18
+ installed runtime venv/icons. User config, logs, history, and downloaded models
19
+ are preserved unless --remove-user-data is passed.
20
+ EOF
21
+ }
22
+
23
+ while [ "$#" -gt 0 ]; do
24
+ case "$1" in
25
+ --remove-user-data)
26
+ REMOVE_USER_DATA=1
27
+ ;;
28
+ --quiet)
29
+ QUIET=1
30
+ ;;
31
+ -h|--help)
32
+ usage
33
+ exit 0
34
+ ;;
35
+ *)
36
+ usage
37
+ exit 1
38
+ ;;
39
+ esac
40
+ shift
41
+ done
42
+
43
+ say() {
44
+ if [ "$QUIET" -eq 0 ]; then
45
+ printf '%s\n' "$1"
46
+ fi
47
+ }
48
+
49
+ remove_file() {
50
+ local path="$1"
51
+ if [ -e "$path" ] || [ -L "$path" ]; then
52
+ rm -f "$path"
53
+ say "Removed $path"
54
+ fi
55
+ }
56
+
57
+ remove_dir_if_empty() {
58
+ local path="$1"
59
+ if [ -d "$path" ]; then
60
+ rmdir "$path" 2>/dev/null || true
61
+ fi
62
+ }
63
+
64
+ remove_file "$DESKTOP_DIR/dictate.desktop"
65
+ remove_file "$DESKTOP_DIR/dictate-settings.desktop"
66
+ remove_file "$AUTOSTART_DIR/dictate.desktop"
67
+
68
+ if [ -L "$BIN_PATH" ]; then
69
+ target="$(readlink "$BIN_PATH" || true)"
70
+ if [ "$target" = "$INSTALL_DIR/venv/bin/dictate" ]; then
71
+ remove_file "$BIN_PATH"
72
+ else
73
+ say "Leaving $BIN_PATH because it points to $target"
74
+ fi
75
+ elif [ -e "$BIN_PATH" ]; then
76
+ say "Leaving $BIN_PATH because it is not a Dictate-managed symlink"
77
+ fi
78
+
79
+ rm -rf "$INSTALL_DIR/venv" "$INSTALL_DIR/share/icons"
80
+ remove_dir_if_empty "$INSTALL_DIR/share"
81
+ say "Removed installed runtime files from $INSTALL_DIR"
82
+
83
+ if [ "$REMOVE_USER_DATA" -eq 1 ]; then
84
+ rm -rf "$CONFIG_DIR" "$INSTALL_DIR"
85
+ say "Removed user config/data: $CONFIG_DIR and $INSTALL_DIR"
86
+ else
87
+ say "Preserved user config/data: $CONFIG_DIR and $INSTALL_DIR"
88
+ fi
89
+
90
+ update-desktop-database "$DESKTOP_DIR" 2>/dev/null || true
91
+
92
+ say "Dictate uninstall complete."
@@ -0,0 +1,70 @@
1
+ param(
2
+ [switch]$NoVerify,
3
+ [switch]$NoPrepareTurbo,
4
+ [switch]$NoShortcut,
5
+ [switch]$NoStartup,
6
+ [switch]$ForceStartup,
7
+ [switch]$RecreateVenv,
8
+ [switch]$SkipGitPull
9
+ )
10
+
11
+ $ErrorActionPreference = "Stop"
12
+
13
+ function Get-StartMenuProgramsDir {
14
+ $programsDir = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs"
15
+ if (-not $env:APPDATA) {
16
+ $programsDir = Join-Path $HOME "AppData\Roaming\Microsoft\Windows\Start Menu\Programs"
17
+ }
18
+ return $programsDir
19
+ }
20
+
21
+ function Remove-LegacyEntries {
22
+ $programsDir = Get-StartMenuProgramsDir
23
+ Remove-Item -Force -ErrorAction SilentlyContinue -Path (Join-Path $programsDir "Dictate Controls.lnk")
24
+ }
25
+
26
+ function Get-StartupShortcutPath {
27
+ $programsDir = Get-StartMenuProgramsDir
28
+ return (Join-Path (Join-Path $programsDir "Startup") "Dictate.lnk")
29
+ }
30
+
31
+ function Stop-DictateProcesses {
32
+ $currentPid = $PID
33
+ $matches = Get-CimInstance Win32_Process |
34
+ Where-Object {
35
+ $_.ProcessId -ne $currentPid -and (
36
+ $_.Name -in @("dictate.exe", "dictate-controls.exe") -or
37
+ $_.CommandLine -like '*dictate.exe* --type-backend pynput*' -or
38
+ $_.CommandLine -like '*pythonw.exe* -m dictate --type-backend pynput*' -or
39
+ $_.CommandLine -like '*dictate-daemon.cmd*' -or
40
+ $_.CommandLine -like '*dictate-controls*'
41
+ )
42
+ }
43
+ foreach ($match in $matches) {
44
+ Stop-Process -Id $match.ProcessId -Force -ErrorAction SilentlyContinue
45
+ }
46
+ Start-Sleep -Milliseconds 500
47
+ }
48
+
49
+ if ((-not $SkipGitPull) -and (Test-Path (Join-Path $PSScriptRoot ".git"))) {
50
+ Write-Host "==> Updating source checkout"
51
+ & git -C $PSScriptRoot pull --ff-only
52
+ if ($LASTEXITCODE -ne 0) {
53
+ throw "git pull failed with exit code $LASTEXITCODE."
54
+ }
55
+ }
56
+
57
+ Remove-LegacyEntries
58
+ Stop-DictateProcesses
59
+
60
+ $installerArgs = @("-ExecutionPolicy", "Bypass", "-File", (Join-Path $PSScriptRoot "install-windows.ps1"))
61
+ if ($NoVerify) { $installerArgs += "-NoVerify" }
62
+ if ($NoPrepareTurbo) { $installerArgs += "-NoPrepareTurbo" }
63
+ if ($NoShortcut) { $installerArgs += "-NoShortcut" }
64
+ if ($NoStartup -or ((-not $ForceStartup) -and (-not (Test-Path (Get-StartupShortcutPath))))) { $installerArgs += "-NoStartup" }
65
+ if ($RecreateVenv) { $installerArgs += "-RecreateVenv" }
66
+
67
+ & powershell @installerArgs
68
+ if ($LASTEXITCODE -ne 0) {
69
+ throw "Dictate Windows update failed with exit code $LASTEXITCODE."
70
+ }
package/update.ps1 ADDED
@@ -0,0 +1,115 @@
1
+ param(
2
+ [string]$InstallRoot,
3
+ [string]$ArchiveUrl,
4
+ [switch]$NoVerify,
5
+ [switch]$NoPrepareTurbo,
6
+ [switch]$NoShortcut,
7
+ [switch]$NoStartup,
8
+ [switch]$ForceStartup,
9
+ [switch]$RecreateVenv
10
+ )
11
+
12
+ $ErrorActionPreference = "Stop"
13
+ $DictateVersion = "2026.5.18-1"
14
+
15
+ if (-not $ArchiveUrl) {
16
+ $ArchiveUrl = "https://github.com/arcforgelabs/dictate/archive/refs/tags/v$DictateVersion.zip"
17
+ }
18
+
19
+ if (-not $InstallRoot) {
20
+ $currentDirectory = [System.IO.Directory]::GetCurrentDirectory()
21
+ $candidateSource = Join-Path $currentDirectory "source"
22
+ if (
23
+ (Test-Path (Join-Path $candidateSource "update-windows.ps1")) -and
24
+ (Test-Path (Join-Path $candidateSource "pyproject.toml")) -and
25
+ (Test-Path (Join-Path $candidateSource "src\dictate"))
26
+ ) {
27
+ $InstallRoot = $currentDirectory
28
+ } else {
29
+ $base = $env:LOCALAPPDATA
30
+ if (-not $base) {
31
+ $base = Join-Path $HOME "AppData\Local"
32
+ }
33
+ $InstallRoot = Join-Path $base "Dictate"
34
+ }
35
+ }
36
+
37
+ $installRootPath = [System.IO.Path]::GetFullPath($InstallRoot)
38
+ $sourceDir = Join-Path $installRootPath "source"
39
+ $stagingRoot = Join-Path $env:TEMP ("dictate-update-" + [guid]::NewGuid().ToString("N"))
40
+ $archivePath = Join-Path $stagingRoot "dictate.zip"
41
+
42
+ function Stop-DictateProcesses {
43
+ $currentPid = $PID
44
+ $matches = Get-CimInstance Win32_Process |
45
+ Where-Object {
46
+ $_.ProcessId -ne $currentPid -and (
47
+ $_.Name -in @("dictate.exe", "dictate-controls.exe") -or
48
+ $_.CommandLine -like '*dictate.exe* --type-backend pynput*' -or
49
+ $_.CommandLine -like '*pythonw.exe* -m dictate --type-backend pynput*' -or
50
+ $_.CommandLine -like '*dictate-daemon.cmd*' -or
51
+ $_.CommandLine -like '*dictate-controls*'
52
+ )
53
+ }
54
+ foreach ($match in $matches) {
55
+ Stop-Process -Id $match.ProcessId -Force -ErrorAction SilentlyContinue
56
+ }
57
+ Start-Sleep -Milliseconds 500
58
+ }
59
+
60
+ Write-Host "==> Updating Dictate in $installRootPath"
61
+ New-Item -ItemType Directory -Force -Path $stagingRoot | Out-Null
62
+ New-Item -ItemType Directory -Force -Path $installRootPath | Out-Null
63
+
64
+ try {
65
+ if (Test-Path -LiteralPath $ArchiveUrl) {
66
+ Write-Host "==> Copying local archive $ArchiveUrl"
67
+ Copy-Item -Force -LiteralPath $ArchiveUrl -Destination $archivePath
68
+ } else {
69
+ Write-Host "==> Downloading $ArchiveUrl"
70
+ Invoke-WebRequest -UseBasicParsing -Uri $ArchiveUrl -OutFile $archivePath
71
+ }
72
+
73
+ Write-Host "==> Expanding source archive"
74
+ Expand-Archive -Force -Path $archivePath -DestinationPath $stagingRoot
75
+ $expanded = Get-ChildItem -Path $stagingRoot -Directory |
76
+ Where-Object { Test-Path (Join-Path $_.FullName "update-windows.ps1") } |
77
+ Select-Object -First 1
78
+ if (-not $expanded) {
79
+ throw "Downloaded archive did not contain update-windows.ps1."
80
+ }
81
+
82
+ if (Test-Path $sourceDir) {
83
+ Stop-DictateProcesses
84
+ Write-Host "==> Replacing existing managed source: $sourceDir"
85
+ Remove-Item -Recurse -Force $sourceDir
86
+ }
87
+ Move-Item -Path $expanded.FullName -Destination $sourceDir
88
+
89
+ $updaterArgs = @(
90
+ "-ExecutionPolicy",
91
+ "Bypass",
92
+ "-File",
93
+ (Join-Path $sourceDir "update-windows.ps1"),
94
+ "-SkipGitPull"
95
+ )
96
+ if ($NoVerify) { $updaterArgs += "-NoVerify" }
97
+ if ($NoPrepareTurbo) { $updaterArgs += "-NoPrepareTurbo" }
98
+ if ($NoShortcut) { $updaterArgs += "-NoShortcut" }
99
+ if ($NoStartup) { $updaterArgs += "-NoStartup" }
100
+ if ($ForceStartup) { $updaterArgs += "-ForceStartup" }
101
+ if ($RecreateVenv) { $updaterArgs += "-RecreateVenv" }
102
+
103
+ Write-Host "==> Running Dictate Windows updater"
104
+ & powershell @updaterArgs
105
+ if ($LASTEXITCODE -ne 0) {
106
+ throw "Dictate Windows updater failed with exit code $LASTEXITCODE."
107
+ }
108
+ } finally {
109
+ if (Test-Path $stagingRoot) {
110
+ Remove-Item -Recurse -Force $stagingRoot
111
+ }
112
+ }
113
+
114
+ Write-Host ""
115
+ Write-Host "Dictate updated from: $sourceDir"
package/update.sh ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env bash
2
+ # Update Dictate and migrate old launcher/icon names from previous installs.
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ INSTALL_DIR="$HOME/.local/share/dictate"
7
+ DESKTOP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
8
+ AUTOSTART_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/autostart"
9
+ ICON_DIR="$INSTALL_DIR/share/icons"
10
+ AUTOSTART_PATH="$AUTOSTART_DIR/dictate.desktop"
11
+
12
+ cleanup_legacy_entries() {
13
+ rm -f "$DESKTOP_DIR/dictate-settings.desktop"
14
+ rm -f "$ICON_DIR/dictate-controls.png" "$ICON_DIR/dictate.png"
15
+ }
16
+
17
+ if [ -d "$SCRIPT_DIR/.git" ]; then
18
+ git -C "$SCRIPT_DIR" pull --ff-only
19
+ fi
20
+
21
+ cleanup_legacy_entries
22
+
23
+ args=("$@")
24
+ startup_option_seen=0
25
+ for arg in "${args[@]}"; do
26
+ if [ "$arg" = "--no-startup" ]; then
27
+ startup_option_seen=1
28
+ fi
29
+ done
30
+ if [ "$startup_option_seen" -eq 0 ] && [ ! -e "$AUTOSTART_PATH" ]; then
31
+ args+=("--no-startup")
32
+ fi
33
+
34
+ "$SCRIPT_DIR/install.sh" "${args[@]}"