dmesg --follow
[ 67475400.000 ] posts.x: Full talk on using wait conditions and signals to make human approval durable inside a multi-agent system:  |   [ 67475400.000 ] posts.x: Calling a human for approval inside an agent loop as a plain function call is risky: if the service drops while it's waiting, the request can just…  |   [ 67467840.000 ] posts.x: 🤣  |   [ 67449720.000 ] posts.x: Full talk on why agent learning stalls without shared, promotable context, including the benchmark numbers from rebuilding their RAG pipeline:  |   [ 67449720.000 ] posts.x: Giving one agent memory turns out to be the easy part. Getting a second agent to use what the first one already learned is not, and that gap is…  |   [ 67402020.000 ] posts.x: Full talk on why dashboards are dying and what agents need instead:  |   [ 67402020.000 ] posts.x: Six months of using Datadog every day, then one frozen moment standing in front of it while a coworker watched, is the origin story behind a talk…  |   [ 67393080.000 ] posts.x: Full talk on why massive codebases are decaying under AI-generated code, and what Sourcegraph built to patch at repo scale:  |   [ 67393080.000 ] posts.x: A tech leader at one of the top 10 US banks sums up the scale problem in one line: sure, an agent can make the change, but there are 90,000…  |   [ 67376340.000 ] posts.x: The Level 2 review method is detailed in my @aiDotEngineer NYC talk. To learn more about how to rely on the work your agents do, read here:  |   [ 67376340.000 ] posts.x: Word to the wise: if you're consuming agent skills from any of these "skills hubs", NEVER raw-dog any of those skills! Have your agent, in cautious…  |   [ 67369680.000 ] posts.x: Meta are back at it!  |   [ 67364940.000 ] posts.x: Full talk on cache-aware routing, speculative decoding, KV cache offloading, and disaggregated prefill/decode:  |   [ 67364940.000 ] posts.x: Open models have closed most of the intelligence gap with proprietary ones, according to a benchmark from Artificial Analysis, but closing that gap…  |  
corey@gallon.me:~/til$

Launching a Web App from Stream Deck

FIGURE 1 ⋅ Launching a Web App from Stream Deck

This is actually much more of a hassle than I’d have expected …

The trick, in my case, is that I have a virtual desktop called Media and, on it, an always open Microsoft Edge browser window also called Media in which I keep the Brain.fm web player open. I want to be able to press a button on the Stream Deck and play or pause Brain.fm from anywhere.

I ended up writing a PowerShell script to accomplish this, using Claude to help. Claude did a relatively terrible job prompting him regularly. The way I ultimately got there quickly was to borrow from Manuel Odendahl’s brilliant suggestions (video and PDF handout) of having the model create a Domain Specific Language (DSL) for the tasks at hand, and then implement specific parts of the DSL.

The resulting utility is available on GitHub here. This was, at first, a hassle but then really effing cool to see how much better the model does with the DSL! h/t Manuel!

<#
.SYNOPSIS
Automates playing Brain.fm in Microsoft Edge on a specific virtual desktop.

.DESCRIPTION
This script navigates to a named virtual desktop, focuses on Microsoft Edge,
switches to the Brain.fm tab, and starts playback. It uses the VirtualDesktop
module and Windows API calls for desktop and window management.

.NOTES
Requires the VirtualDesktop module to be installed.
Feature_Image: ./images/feature_images/20240824_-_Launching_a_Web_App_from_Stream_Deck_3.png

#>

# Import the VirtualDesktop module
# Must be installed as admin by running "Install-Module VirtualDesktop -Scope CurrentUser"
Import-Module VirtualDesktop

Add-Type -AssemblyName System.Windows.Forms

# Add Windows API function declarations for window management
Add-Type @"
using System;
using System.Runtime.InteropServices;

public class User32 {
    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"@

<#
.SYNOPSIS
Switches to a named virtual desktop.

.PARAMETER name
The name of the virtual desktop to switch to.

.EXAMPLE
Switch-ToNamedDesktop -name "Media"
#>
function Switch-ToNamedDesktop {
    param([string]$name)
    $desktops = Get-DesktopList
    $targetDesktop = $desktops | Where-Object { $_.Name -eq $name }
    if ($targetDesktop) {
        try {
            Switch-Desktop -Desktop $targetDesktop.Number
            Write-Host "Switched to virtual desktop: $name"
        } catch {
            Write-Host "Error switching to desktop: $_"
        }
    } else {
        Write-Host "Virtual desktop '$name' not found."
        Write-Host "Available desktops: $($desktops | ForEach-Object { $_.Name } | Join-String -Separator ', ')"
    }
}

<#
.SYNOPSIS
Sets focus on an application window.

.PARAMETER name
The name of the application to focus on.

.EXAMPLE
Set-ApplicationFocus -name "Edge"
#>
function Set-ApplicationFocus {
    param([string]$name)
    $processes = Get-Process | Where-Object { $_.MainWindowTitle -ne "" }
    Write-Host "Searching for application with name containing '$name'"
    Write-Host "Running processes with non-empty window titles:"
    $processes | ForEach-Object { Write-Host "  - $($_.ProcessName): $($_.MainWindowTitle)" }

    $app = $processes | Where-Object { $_.ProcessName -like "*$name*" -or $_.MainWindowTitle -like "*$name*" } | Select-Object -First 1
    if ($app) {
        [User32]::ShowWindow($app.MainWindowHandle, 9) # 9 = SW_RESTORE
        [User32]::SetForegroundWindow($app.MainWindowHandle)
        Write-Host "Set focus on application: $($app.ProcessName) (Window Title: $($app.MainWindowTitle))"
        return $true
    } else {
        Write-Host "Application with name containing '$name' not found."
        return $false
    }
}

<#
.SYNOPSIS
Switches to a specific tab in Microsoft Edge.

.PARAMETER tabTitle
The title of the tab to switch to.

.EXAMPLE
Switch-EdgeTab -tabTitle "brain.fm"
#>
function Switch-EdgeTab {
    param(
        [string]$tabTitle
    )
    $edge = Get-Process | Where-Object { $_.ProcessName -eq "msedge" -and $_.MainWindowTitle -ne "" } | Select-Object -First 1
    if ($edge) {
        # Activate the Edge window
        [User32]::ShowWindow($edge.MainWindowHandle, 9) # 9 = SW_RESTORE
        [User32]::SetForegroundWindow($edge.MainWindowHandle)
        Write-Host "Activated Edge window: $($edge.MainWindowTitle)"

        # Use correct keyboard shortcut to search tabs
        $wshell = New-Object -ComObject wscript.shell
        $wshell.SendKeys("^+a")  # Ctrl+Shift+A to open tab search
        Start-Sleep -Milliseconds 500  # Wait for search to open
        $wshell.SendKeys($tabTitle)
        Start-Sleep -Milliseconds 500  # Wait for search results
        $wshell.SendKeys("{ENTER}")

        Write-Host "Attempted to switch to tab '$tabTitle' in Edge"
        return $true
    } else {
        Write-Host "No Edge window with a non-empty title found."
        return $false
    }
}

# Main execution
try {
    # Switch to the "Media" virtual desktop
    Switch-ToNamedDesktop -name "Media"

    # Set focus on the Edge browser window
    $focusSuccess = Set-ApplicationFocus -name "Media"

    # Only proceed if focus was successful
    if ($focusSuccess) {
        # Switch to the tab with brain.fm
        $switchSuccess = Switch-EdgeTab -tabTitle "brain.fm"

        if ($switchSuccess) {
            Write-Host "Navigation completed successfully."
            # Wait for 0.5 seconds
            Start-Sleep -Milliseconds 500
            # Send a space key press to start playing Brain.fm
            [System.Windows.Forms.SendKeys]::SendWait(' ')

        } else {
            Write-Host "Navigation partially completed. Failed to switch to the desired tab."
        }
    } else {
        Write-Host "Navigation failed. Could not focus on Microsoft Edge."
    }
} catch {
    Write-Host "An error occurred: $_"
}
corey@gallon.me:~$ tail -f /writing Attach to the stream. An email when I have something worth sending. Replies encouraged!
corey@gallon.me:~$ ls -lt /til ↑2024-08-24 Comments are Failures in Coding
▸2024-08-24 Launching a Web App from Stream Deck ⋅ you are here
↓2024-08-24 Programs Do Things