Configure this machine for Copilot Session Tracker. Installs the PowerShell module, configures auth, and updates copilot-instructions.md so Copilot automatically tracks sessions.
How this skill is triggered — by the user, by Claude, or both
Slash command
/copilot-session-tracker:initialize-machineThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill configures the current machine for Copilot Session Tracker. It installs the PowerShell module, verifies auth, and updates `copilot-instructions.md` so every future Copilot CLI session is automatically tracked.
This skill configures the current machine for Copilot Session Tracker. It installs the PowerShell module, verifies auth, and updates copilot-instructions.md so every future Copilot CLI session is automatically tracked.
Platform: Windows only (uses $env:USERPROFILE, Windows-style paths, PowerShell 7+).
STOP. You MUST ask the user for the following parameters before proceeding. Do NOT guess or use defaults without explicit user confirmation.
Ask the user: "What is the tracker server URL?"
This is required. There is no default. Store as $serverUrl.
$serverUrl = "<user-provided>"
Ask the user: "What is the Entra tenant ID for authentication?"
This is required. There is no default. Store as $tenantId.
$tenantId = "<user-provided>"
Ask the user: "What is the Entra app registration resource ID (Application ID URI)? This looks like api://<client-id>."
This is required. There is no default. Store as $resourceId.
$resourceId = "<user-provided>"
Display the collected parameters and ask: "I'll configure the tracker with these settings. Proceed?"
Server URL: <server-url>
Tenant ID: <tenant-id>
Resource ID: <resource-id>
Do NOT proceed until the user explicitly confirms.
# 1a. Check Azure CLI
try {
az version | Out-Null
Write-Output "✅ Azure CLI is installed."
} catch {
Write-Error "❌ Azure CLI (az) is not installed. Install from https://aka.ms/install-azure-cli"
return
}
# 1b. Check login state
$account = az account show 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "❌ Not logged in to Azure CLI. Run 'az login' first."
return
}
Write-Output "✅ Logged in to Azure CLI."
# 1c. Test token acquisition for the tracker tenant
$token = az account get-access-token --resource $resourceId --tenant $tenantId --query accessToken -o tsv 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Warning "⚠️ Cannot get a token for tenant $tenantId. Attempting login..."
az login --tenant $tenantId
$token = az account get-access-token --resource $resourceId --tenant $tenantId --query accessToken -o tsv 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "❌ Still cannot get a token after login attempt."
return
}
}
Write-Output "✅ Token acquired for tenant $tenantId"
# 1d. Verify server is reachable
try {
$health = Invoke-RestMethod -Uri "$serverUrl/api/health" -ErrorAction Stop
Write-Output "✅ Server reachable at $serverUrl (active sessions: $($health.activeSessions))"
} catch {
Write-Error "❌ Cannot reach server at $serverUrl. Check the URL."
return
}
Remove any existing tracker scripts (from previous versions) and install fresh copies from the plugin.
$trackerDir = Join-Path $env:USERPROFILE ".copilot\copilot-tracker"
# Clean out any existing scripts from previous installs
if (Test-Path $trackerDir) {
Get-ChildItem $trackerDir -Filter "*.ps1" | Remove-Item -Force
Get-ChildItem $trackerDir -Filter "*.psm1" | Remove-Item -Force
Write-Output "✅ Cleaned existing scripts from $trackerDir"
} else {
New-Item -ItemType Directory -Path $trackerDir -Force | Out-Null
}
# Find files relative to this plugin's install location
# The plugin structure is: <plugin-root>/skills/initialize-machine/SKILL.md
# Shared files are at: <plugin-root>/shared/
$skillDir = $PSScriptRoot
if (-not $skillDir) {
# Fallback: search for the installed plugin by name
$pluginRoot = Get-ChildItem "$env:USERPROFILE\.copilot\installed-plugins" -Directory -Recurse -Filter "copilot-session-tracker" -ErrorAction SilentlyContinue |
Where-Object { Test-Path (Join-Path $_.FullName "plugin.json") } |
Select-Object -First 1
if ($pluginRoot) {
$sharedDir = Join-Path $pluginRoot.FullName "shared"
$templateDir = Join-Path $pluginRoot.FullName "templates"
}
} else {
# Resolve from SKILL.md location: ../../shared/
$pluginRootDir = Split-Path (Split-Path $skillDir)
$sharedDir = Join-Path $pluginRootDir "shared"
$templateDir = Join-Path $pluginRootDir "templates"
}
# Fallback to repo source if running from repo directory
if (-not $sharedDir -or -not (Test-Path $sharedDir)) {
$repoShared = Join-Path $PWD "plugins\copilot-session-tracker\shared"
$repoTemplates = Join-Path $PWD "plugins\copilot-session-tracker\templates"
if (Test-Path $repoShared) {
$sharedDir = $repoShared
$templateDir = $repoTemplates
} else {
Write-Error "❌ Cannot find module files. Run from the copilot-tracker repo or ensure the plugin is installed."
return
}
}
# Install fresh copies
Copy-Item -Path (Join-Path $sharedDir "CopilotTracker.psm1") -Destination $trackerDir -Force
Copy-Item -Path (Join-Path $sharedDir "Start-TrackerSession.ps1") -Destination $trackerDir -Force
Write-Output "✅ Module installed to $trackerDir"
Write the tracker config JSON. The PowerShell module reads this on every session startup.
$config = @{
serverUrl = $serverUrl
tenantId = $tenantId
resourceId = $resourceId
} | ConvertTo-Json
$configPath = Join-Path $env:USERPROFILE ".copilot\copilot-tracker-config.json"
$config | Set-Content -Path $configPath -Encoding UTF8
Write-Output "✅ Config written: $configPath"
Read the template and inject into the user's copilot-instructions.md. This is idempotent: running again replaces the existing section.
$templatePath = Join-Path $templateDir "copilot-instructions-snippet.md"
if (-not (Test-Path $templatePath)) {
Write-Error "❌ Cannot find copilot-instructions-snippet.md template."
return
}
$snippet = Get-Content $templatePath -Raw
$instructionsPath = Join-Path $env:USERPROFILE ".copilot\copilot-instructions.md"
$beginMarker = "<!-- BEGIN COPILOT SESSION TRACKER -->"
$endMarker = "<!-- END COPILOT SESSION TRACKER -->"
if (Test-Path $instructionsPath) {
$existing = Get-Content $instructionsPath -Raw
if ($existing -match [regex]::Escape($beginMarker)) {
$pattern = "(?s)$([regex]::Escape($beginMarker)).*?$([regex]::Escape($endMarker))"
$existingSection = [regex]::Match($existing, $pattern).Value
if ($existingSection.Trim() -eq $snippet.Trim()) {
Write-Output "✅ copilot-instructions.md already up to date."
} else {
$updated = $existing -replace $pattern, $snippet
$updated | Set-Content -Path $instructionsPath -Encoding UTF8
Write-Output "✅ Updated tracker instructions in copilot-instructions.md"
}
} else {
"`n`n$snippet" | Add-Content -Path $instructionsPath -Encoding UTF8
Write-Output "✅ Appended tracker instructions to copilot-instructions.md"
}
} else {
$snippet | Set-Content -Path $instructionsPath -Encoding UTF8
Write-Output "✅ Created copilot-instructions.md with tracker instructions."
}
Test the full chain without creating real sessions.
$modulePath = Join-Path $env:USERPROFILE ".copilot\copilot-tracker\CopilotTracker.psm1"
try {
Import-Module $modulePath -Force
Write-Output "✅ Module loaded successfully."
} catch {
Write-Error "❌ Failed to load module: $_"
return
}
# Verify auth by testing token acquisition (non-destructive)
try {
$token = az account get-access-token --resource $resourceId --tenant $tenantId --query accessToken -o tsv 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Output "✅ Authentication working."
} else {
Write-Warning "⚠️ Could not acquire auth token. Run: az login --tenant $tenantId"
Write-Warning " If you see a consent_required error, the Azure CLI (04b07795-8ddb-461a-bbee-02f9e1bf7b46)"
Write-Warning " may need to be pre-authorized in the Entra app registration."
}
} catch {
Write-Warning "⚠️ Auth verification failed: $_"
}
# Verify server connectivity (non-destructive, uses anonymous health endpoint)
try {
$health = Invoke-RestMethod -Uri "$serverUrl/api/health" -ErrorAction Stop
Write-Output "✅ Server connectivity verified."
} catch {
Write-Warning "⚠️ Server connectivity check failed: $_"
}
Write-Output @"
✅ Machine Initialized!
Machine: $env:COMPUTERNAME
Module installed: $env:USERPROFILE\.copilot\copilot-tracker\
Instructions: $env:USERPROFILE\.copilot\copilot-instructions.md (updated)
Server: $serverUrl
Tenant: $tenantId
Resource ID: $resourceId
Copilot CLI will now automatically track sessions on this machine.
To test: start a new Copilot CLI session and check the dashboard.
"@
$env:USERPROFILE and Windows-style separators.shared/ directory.BEGIN/END markers ensure idempotent updates.--tenant on az account get-access-token so your active subscription doesn't matter./api/health endpoint, no test sessions created.04b07795-8ddb-461a-bbee-02f9e1bf7b46) listed as a pre-authorized application. The deploy script (deploy/scripts/setup-app-registration.ps1) does this automatically. If you see a consent_required or invalid_resource error during token acquisition, this is the cause.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub aef123/copilot-tracker --plugin copilot-session-tracker