Files
gastown/internal/cmd/root.go
Steve Yegge 62bd8739d6 feat: keepalive signal from gt commands
Every gt command now touches .gastown/keepalive.json with the last
command and timestamp. This enables smarter daemon backoff:
- Fresh (< 2 min): agent is working, skip heartbeat
- Stale (2-5 min): might be thinking, gentle poke
- Very stale (> 5 min): likely idle, safe to interrupt

Uses PersistentPreRun hook to capture all commands including subcommands.

Closes gt-bfd

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 20:24:51 -08:00

48 lines
1.3 KiB
Go

// Package cmd provides CLI commands for the gt tool.
package cmd
import (
"os"
"strings"
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/keepalive"
)
var rootCmd = &cobra.Command{
Use: "gt",
Short: "Gas Town - Multi-agent workspace manager",
Long: `Gas Town (gt) manages multi-agent workspaces called rigs.
It coordinates agent spawning, work distribution, and communication
across distributed teams of AI agents working on shared codebases.`,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// Signal agent activity by touching keepalive file
// Build command path: gt status, gt mail send, etc.
cmdPath := buildCommandPath(cmd)
keepalive.TouchWithArgs(cmdPath, args)
},
}
// Execute runs the root command
func Execute() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}
func init() {
// Global flags can be added here
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
}
// buildCommandPath walks the command hierarchy to build the full command path.
// For example: "gt mail send", "gt status", etc.
func buildCommandPath(cmd *cobra.Command) string {
var parts []string
for c := cmd; c != nil; c = c.Parent() {
parts = append([]string{c.Name()}, parts...)
}
return strings.Join(parts, " ")
}