feat(commands): add PC control packs — volume, apps, file_search, output_device
All four packs are pure Lua (sandbox=full) and call out to PowerShell helpers
where COM / native APIs are needed. No new Rust code, no rebuild required:
post_build.py --sync copies them under target/{debug,release}/resources/.
volume/
- volume_up / volume_down: 5x VK_VOLUME_UP|DOWN via keybd_event
- volume_mute: VK_VOLUME_MUTE
- volume_max: 50x VK_VOLUME_UP (system clamps)
Helper _volume_helper.ps1 P/Invokes user32!keybd_event.
apps/
- open_browser : start "" https://www.google.com (uses system default browser)
- open_notepad : notepad.exe
- open_calculator: calc.exe
- open_explorer : explorer.exe
- open_terminal : wt.exe, falls back to powershell.exe
- open_settings : ms-settings: protocol
- open_task_manager: taskmgr.exe
- lock_screen : rundll32 user32.dll,LockWorkStation
- screenshot : System.Drawing capture to ~/Pictures/jarvis_screenshot_*.png
file_search/
- find file <query> : recursive Get-ChildItem in Desktop/Documents/Downloads
(depth 3, top 5 matches). Strips Russian/English/Ukrainian trigger
prefixes from the recognized phrase, then opens explorer /select on the
first hit and notifies with the total count.
output_device/
- list_output_devices : enumerates active render endpoints via
IMMDeviceEnumerator and notifies friendly names with indices
- next_output_device : cycles the system default render device via the
undocumented IPolicyConfig::SetDefaultEndpoint (eConsole/Multimedia/
Communications). Tested locally — listed 7 devices, current correctly
identified at index 5.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
307688c7d8
commit
54dcf7e564
22 changed files with 932 additions and 0 deletions
31
resources/commands/volume/_volume_helper.ps1
Normal file
31
resources/commands/volume/_volume_helper.ps1
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[ValidateSet("up","down","mute","max")]
|
||||
[string]$Action,
|
||||
|
||||
[int]$Times = 1
|
||||
)
|
||||
|
||||
Add-Type -Name VolumeKey -Namespace Win32 -MemberDefinition @'
|
||||
[DllImport("user32.dll")]
|
||||
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, System.UIntPtr dwExtraInfo);
|
||||
'@
|
||||
|
||||
$KEY_UP = 0xAF
|
||||
$KEY_DOWN = 0xAE
|
||||
$KEY_MUTE = 0xAD
|
||||
|
||||
$vk = switch ($Action) {
|
||||
"up" { $KEY_UP }
|
||||
"down" { $KEY_DOWN }
|
||||
"mute" { $KEY_MUTE }
|
||||
"max" { $KEY_UP }
|
||||
}
|
||||
|
||||
$count = if ($Action -eq "max") { 50 } else { $Times }
|
||||
|
||||
for ($i = 0; $i -lt $count; $i++) {
|
||||
[Win32.VolumeKey]::keybd_event($vk, 0, 0, [UIntPtr]::Zero)
|
||||
[Win32.VolumeKey]::keybd_event($vk, 0, 2, [UIntPtr]::Zero)
|
||||
Start-Sleep -Milliseconds 25
|
||||
}
|
||||
106
resources/commands/volume/command.toml
Normal file
106
resources/commands/volume/command.toml
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
[[commands]]
|
||||
id = "volume_up"
|
||||
type = "lua"
|
||||
script = "volume_up.lua"
|
||||
sandbox = "full"
|
||||
timeout = 3000
|
||||
|
||||
[commands.phrases]
|
||||
ru = [
|
||||
"громче",
|
||||
"сделай громче",
|
||||
"прибавь звук",
|
||||
"увеличь громкость",
|
||||
"погромче",
|
||||
]
|
||||
en = [
|
||||
"louder",
|
||||
"volume up",
|
||||
"increase volume",
|
||||
"turn it up",
|
||||
]
|
||||
ua = [
|
||||
"голосніше",
|
||||
"зроби голосніше",
|
||||
"збільш гучність",
|
||||
]
|
||||
|
||||
|
||||
[[commands]]
|
||||
id = "volume_down"
|
||||
type = "lua"
|
||||
script = "volume_down.lua"
|
||||
sandbox = "full"
|
||||
timeout = 3000
|
||||
|
||||
[commands.phrases]
|
||||
ru = [
|
||||
"тише",
|
||||
"сделай тише",
|
||||
"убавь звук",
|
||||
"уменьши громкость",
|
||||
"потише",
|
||||
]
|
||||
en = [
|
||||
"quieter",
|
||||
"volume down",
|
||||
"decrease volume",
|
||||
"turn it down",
|
||||
]
|
||||
ua = [
|
||||
"тихіше",
|
||||
"зроби тихіше",
|
||||
"зменш гучність",
|
||||
]
|
||||
|
||||
|
||||
[[commands]]
|
||||
id = "volume_mute"
|
||||
type = "lua"
|
||||
script = "volume_mute.lua"
|
||||
sandbox = "full"
|
||||
timeout = 3000
|
||||
|
||||
[commands.phrases]
|
||||
ru = [
|
||||
"выключи звук",
|
||||
"заткнись",
|
||||
"тишина",
|
||||
"приглуши звук",
|
||||
"отключи звук",
|
||||
]
|
||||
en = [
|
||||
"mute",
|
||||
"silence",
|
||||
"shut up",
|
||||
"be quiet",
|
||||
]
|
||||
ua = [
|
||||
"вимкни звук",
|
||||
"тиша",
|
||||
"стихни",
|
||||
]
|
||||
|
||||
|
||||
[[commands]]
|
||||
id = "volume_max"
|
||||
type = "lua"
|
||||
script = "volume_max.lua"
|
||||
sandbox = "full"
|
||||
timeout = 3000
|
||||
|
||||
[commands.phrases]
|
||||
ru = [
|
||||
"максимальная громкость",
|
||||
"звук на максимум",
|
||||
"на полную",
|
||||
]
|
||||
en = [
|
||||
"max volume",
|
||||
"full volume",
|
||||
"maximum",
|
||||
]
|
||||
ua = [
|
||||
"максимальна гучність",
|
||||
"звук на максимум",
|
||||
]
|
||||
16
resources/commands/volume/volume_down.lua
Normal file
16
resources/commands/volume/volume_down.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
local helper = jarvis.context.command_path .. "\\_volume_helper.ps1"
|
||||
local cmd = string.format(
|
||||
'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action down -Times 5',
|
||||
helper
|
||||
)
|
||||
|
||||
local res = jarvis.system.exec(cmd)
|
||||
if res.success then
|
||||
jarvis.log("info", "volume down")
|
||||
jarvis.audio.play_ok()
|
||||
else
|
||||
jarvis.log("error", "volume down failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr))
|
||||
jarvis.audio.play_error()
|
||||
end
|
||||
|
||||
return { chain = false }
|
||||
16
resources/commands/volume/volume_max.lua
Normal file
16
resources/commands/volume/volume_max.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
local helper = jarvis.context.command_path .. "\\_volume_helper.ps1"
|
||||
local cmd = string.format(
|
||||
'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action max',
|
||||
helper
|
||||
)
|
||||
|
||||
local res = jarvis.system.exec(cmd)
|
||||
if res.success then
|
||||
jarvis.log("info", "volume max")
|
||||
jarvis.audio.play_ok()
|
||||
else
|
||||
jarvis.log("error", "volume max failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr))
|
||||
jarvis.audio.play_error()
|
||||
end
|
||||
|
||||
return { chain = false }
|
||||
16
resources/commands/volume/volume_mute.lua
Normal file
16
resources/commands/volume/volume_mute.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
local helper = jarvis.context.command_path .. "\\_volume_helper.ps1"
|
||||
local cmd = string.format(
|
||||
'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action mute',
|
||||
helper
|
||||
)
|
||||
|
||||
local res = jarvis.system.exec(cmd)
|
||||
if res.success then
|
||||
jarvis.log("info", "mute toggled")
|
||||
jarvis.audio.play_ok()
|
||||
else
|
||||
jarvis.log("error", "mute failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr))
|
||||
jarvis.audio.play_error()
|
||||
end
|
||||
|
||||
return { chain = false }
|
||||
16
resources/commands/volume/volume_up.lua
Normal file
16
resources/commands/volume/volume_up.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
local helper = jarvis.context.command_path .. "\\_volume_helper.ps1"
|
||||
local cmd = string.format(
|
||||
'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action up -Times 5',
|
||||
helper
|
||||
)
|
||||
|
||||
local res = jarvis.system.exec(cmd)
|
||||
if res.success then
|
||||
jarvis.log("info", "volume up")
|
||||
jarvis.audio.play_ok()
|
||||
else
|
||||
jarvis.log("error", "volume up failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr))
|
||||
jarvis.audio.play_error()
|
||||
end
|
||||
|
||||
return { chain = false }
|
||||
Loading…
Add table
Add a link
Reference in a new issue