190 lines
7.6 KiB
Plaintext
190 lines
7.6 KiB
Plaintext
|
|
#!/usr/bin/env nu
|
||
|
|
|
||
|
|
# Monitor Claude Code agents in real-time
|
||
|
|
# Usage: nu provisioning/tools/monitor-agents.nu [--mode dashboard|logs|reports]
|
||
|
|
|
||
|
|
def main [
|
||
|
|
--mode: string = "dashboard" # dashboard, logs, reports, files
|
||
|
|
--refresh: int = 2 # Refresh interval in seconds
|
||
|
|
--filter: string # Filter pattern for logs
|
||
|
|
] {
|
||
|
|
match $mode {
|
||
|
|
"dashboard" => { monitor_dashboard $refresh }
|
||
|
|
"logs" => { monitor_logs $refresh $filter }
|
||
|
|
"reports" => { monitor_reports $refresh }
|
||
|
|
"files" => { monitor_files $refresh }
|
||
|
|
_ => {
|
||
|
|
print "Unknown mode. Available modes: dashboard, logs, reports, files"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Dashboard view with all monitoring info
|
||
|
|
def monitor_dashboard [refresh: int] {
|
||
|
|
loop {
|
||
|
|
clear
|
||
|
|
print "╔══════════════════════════════════════════════════════════════╗"
|
||
|
|
print "║ Claude Code Agent Monitoring Dashboard ║"
|
||
|
|
print "╚══════════════════════════════════════════════════════════════╝"
|
||
|
|
print ""
|
||
|
|
|
||
|
|
# Recent reports in /tmp
|
||
|
|
print "📊 Recent Reports (Last 5):"
|
||
|
|
print "─────────────────────────────────────────────"
|
||
|
|
|
||
|
|
ls /tmp
|
||
|
|
| where name =~ "(report|summary|verification|migration)"
|
||
|
|
| where type == "file"
|
||
|
|
| sort-by modified -r
|
||
|
|
| first 5
|
||
|
|
| select name modified size
|
||
|
|
| each { |file|
|
||
|
|
let name = ($file.name | path basename)
|
||
|
|
let time = ($file.modified | format date "%H:%M:%S")
|
||
|
|
let size = ($file.size | into string)
|
||
|
|
$" • ($name) - ($time) \(($size) bytes\)"
|
||
|
|
}
|
||
|
|
| str join "\n"
|
||
|
|
| print
|
||
|
|
|
||
|
|
print ""
|
||
|
|
print "📝 Latest Report Content (last 20 lines):"
|
||
|
|
print "─────────────────────────────────────────────"
|
||
|
|
|
||
|
|
let latest = (ls /tmp
|
||
|
|
| where name =~ "report|summary"
|
||
|
|
| where type == "file"
|
||
|
|
| sort-by modified -r
|
||
|
|
| first 1)
|
||
|
|
|
||
|
|
if ($latest | is-not-empty) {
|
||
|
|
let file = ($latest.name | first)
|
||
|
|
print $" File: ($file | path basename)"
|
||
|
|
print ""
|
||
|
|
open $file | lines | last 20 | each { |line| $" ($line)" } | str join "\n" | print
|
||
|
|
} else {
|
||
|
|
print " No reports found yet..."
|
||
|
|
}
|
||
|
|
|
||
|
|
print ""
|
||
|
|
print $"🔄 Refreshing every ($refresh)s... \(Ctrl+C to exit\)"
|
||
|
|
sleep ($refresh * 1sec)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Monitor logs from /tmp
|
||
|
|
def monitor_logs [refresh: int, filter: string] {
|
||
|
|
loop {
|
||
|
|
clear
|
||
|
|
print "╔══════════════════════════════════════════════════════════════╗"
|
||
|
|
print "║ Claude Code Agent Logs Monitor ║"
|
||
|
|
print "╚══════════════════════════════════════════════════════════════╝"
|
||
|
|
print ""
|
||
|
|
|
||
|
|
# Find log files
|
||
|
|
let logs = (ls /tmp
|
||
|
|
| where name =~ "log|output|stdout|stderr"
|
||
|
|
| where type == "file"
|
||
|
|
| sort-by modified -r
|
||
|
|
| first 3)
|
||
|
|
|
||
|
|
if ($logs | is-not-empty) {
|
||
|
|
$logs | each { |log_file|
|
||
|
|
print $"📄 ($log_file.name | path basename)"
|
||
|
|
print "─────────────────────────────────────────────"
|
||
|
|
|
||
|
|
let content = (open $log_file | lines | last 30)
|
||
|
|
|
||
|
|
if ($filter | is-not-empty) {
|
||
|
|
$content | where { |line| $line =~ $filter } | each { |line| $" ($line)" } | str join "\n" | print
|
||
|
|
} else {
|
||
|
|
$content | each { |line| $" ($line)" } | str join "\n" | print
|
||
|
|
}
|
||
|
|
|
||
|
|
print ""
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
print "No log files found in /tmp"
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"🔄 Refreshing every ($refresh)s... \(Ctrl+C to exit\)"
|
||
|
|
sleep ($refresh * 1sec)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Monitor report files
|
||
|
|
def monitor_reports [refresh: int] {
|
||
|
|
loop {
|
||
|
|
clear
|
||
|
|
print "╔══════════════════════════════════════════════════════════════╗"
|
||
|
|
print "║ Claude Code Reports Monitor ║"
|
||
|
|
print "╚══════════════════════════════════════════════════════════════╝"
|
||
|
|
print ""
|
||
|
|
|
||
|
|
ls /tmp
|
||
|
|
| where name =~ "(report|summary|verification|stats)"
|
||
|
|
| where type == "file"
|
||
|
|
| sort-by modified -r
|
||
|
|
| first 10
|
||
|
|
| each { |file|
|
||
|
|
let name = ($file.name | path basename)
|
||
|
|
let time = ($file.modified | format date "%Y-%m-%d %H:%M:%S")
|
||
|
|
let size = ($file.size / 1024 | into int)
|
||
|
|
|
||
|
|
print $"📊 ($name)"
|
||
|
|
print $" Modified: ($time)"
|
||
|
|
print $" Size: ($size) KB"
|
||
|
|
print ""
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"🔄 Refreshing every ($refresh)s... \(Ctrl+C to exit\)"
|
||
|
|
sleep ($refresh * 1sec)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Monitor file changes
|
||
|
|
def monitor_files [refresh: int] {
|
||
|
|
let baseline = (ls /tmp | where type == "file" | select name modified)
|
||
|
|
|
||
|
|
loop {
|
||
|
|
clear
|
||
|
|
print "╔══════════════════════════════════════════════════════════════╗"
|
||
|
|
print "║ Claude Code File Changes Monitor ║"
|
||
|
|
print "╚══════════════════════════════════════════════════════════════╝"
|
||
|
|
print ""
|
||
|
|
|
||
|
|
let current = (ls /tmp | where type == "file" | select name modified)
|
||
|
|
|
||
|
|
# Find new or modified files
|
||
|
|
let changes = ($current
|
||
|
|
| each { |curr|
|
||
|
|
let prev = ($baseline | where name == $curr.name | first)
|
||
|
|
if ($prev | is-empty) {
|
||
|
|
{file: ($curr.name | path basename), status: "NEW", time: $curr.modified}
|
||
|
|
} else if $curr.modified > $prev.modified {
|
||
|
|
{file: ($curr.name | path basename), status: "MODIFIED", time: $curr.modified}
|
||
|
|
} else {
|
||
|
|
null
|
||
|
|
}
|
||
|
|
}
|
||
|
|
| where { |x| $x != null }
|
||
|
|
| sort-by time -r
|
||
|
|
| first 20)
|
||
|
|
|
||
|
|
if ($changes | is-not-empty) {
|
||
|
|
$changes | each { |change|
|
||
|
|
let icon = if $change.status == "NEW" { "🆕" } else { "✏️" }
|
||
|
|
let time = ($change.time | format date "%H:%M:%S")
|
||
|
|
print $"($icon) ($change.status): ($change.file) - ($time)"
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
print "No file changes detected..."
|
||
|
|
}
|
||
|
|
|
||
|
|
print ""
|
||
|
|
print $"🔄 Refreshing every ($refresh)s... \(Ctrl+C to exit\)"
|
||
|
|
sleep ($refresh * 1sec)
|
||
|
|
}
|
||
|
|
}
|