Claude-skill-registry gentleman-system
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/gentleman-system" ~/.claude/skills/majiayu000-claude-skill-registry-gentleman-system && rm -rf "$T"
manifest:
skills/data/gentleman-system/SKILL.mdsource content
When to Use
Use this skill when:
- Adding support for new operating systems
- Modifying OS detection logic
- Working with command execution (sudo, brew, pkg)
- Adding new system checks
- Implementing backup/restore functionality
Critical Patterns
Pattern 1: OSType Enum
All OS types are defined in
detect.go:
type OSType int const ( OSMac OSType = iota OSLinux OSArch OSDebian // Debian-based (Debian, Ubuntu) OSTermux // Termux on Android OSUnknown )
Pattern 2: SystemInfo Structure
Detection results in
SystemInfo struct:
type SystemInfo struct { OS OSType OSName string IsWSL bool IsARM bool IsTermux bool HomeDir string HasBrew bool HasPkg bool // Termux package manager HasXcode bool UserShell string Prefix string // Termux $PREFIX or empty }
Pattern 3: OS Detection Priority
Termux is checked FIRST (runs on Linux but is special):
func Detect() *SystemInfo { info := &SystemInfo{...} // Check Termux FIRST if isTermux() { info.OS = OSTermux info.IsTermux = true info.HasPkg = checkPkg() return info } // Then check standard OS switch runtime.GOOS { case "darwin": info.OS = OSMac case "linux": if isArchLinux() { info.OS = OSArch } else if isDebian() { info.OS = OSDebian } } return info }
Pattern 4: Command Execution Functions
Use the right function for each context:
// Basic command (no sudo, no logs) system.Run("git clone ...", nil) // With real-time logs system.RunWithLogs("git clone ...", nil, func(line string) { SendLog(stepID, line) }) // Homebrew commands system.RunBrewWithLogs("install fish", nil, logFunc) // Sudo commands (password prompt) system.RunSudo("apt-get install -y git", nil) system.RunSudoWithLogs("pacman -S git", nil, logFunc) // Termux pkg commands (no sudo needed) system.RunPkgInstall("fish git", nil, logFunc) system.RunPkgWithLogs("update", nil, logFunc)
Decision Tree
Adding new OS support? ├── Add OSType constant in detect.go ├── Add detection function (isNewOS()) ├── Update Detect() with priority order ├── Update SystemInfo if new fields needed └── Add OS case in installer.go steps Running a command? ├── Needs sudo? → RunSudo() or RunSudoWithLogs() ├── Needs brew? → RunBrewWithLogs() ├── On Termux? → RunPkgInstall() or RunPkgWithLogs() ├── Needs logs? → RunWithLogs() └── Simple exec? → Run() Checking if tool exists? ├── Use CommandExists("toolname") └── Returns bool
Code Examples
Example 1: Termux Detection
func isTermux() bool { // Check TERMUX_VERSION environment variable if os.Getenv("TERMUX_VERSION") != "" { return true } // Check PREFIX contains termux path prefix := os.Getenv("PREFIX") if strings.Contains(prefix, "com.termux") { return true } // Check for Termux-specific paths if _, err := os.Stat("/data/data/com.termux"); err == nil { return true } return false }
Example 2: Platform-Specific Execution
func installTool(m *Model) error { var result *system.ExecResult switch { case m.SystemInfo.IsTermux: // Termux: use pkg (no sudo) result = system.RunPkgInstall("tool", nil, logFunc) case m.SystemInfo.OS == system.OSArch: // Arch: use pacman with sudo result = system.RunSudoWithLogs("pacman -S --noconfirm tool", nil, logFunc) case m.SystemInfo.OS == system.OSMac: // macOS: use Homebrew result = system.RunBrewWithLogs("install tool", nil, logFunc) case m.SystemInfo.OS == system.OSDebian: // Debian/Ubuntu: use Homebrew (installed by us) result = system.RunBrewWithLogs("install tool", nil, logFunc) default: return fmt.Errorf("unsupported OS: %v", m.SystemInfo.OS) } return result.Error }
Example 3: Homebrew Prefix Detection
func GetBrewPrefix() string { if runtime.GOOS == "darwin" { // Apple Silicon uses /opt/homebrew // Intel uses /usr/local if runtime.GOARCH == "arm64" { return "/opt/homebrew" } return "/usr/local" } return "/home/linuxbrew/.linuxbrew" }
Example 4: File Operations
// Ensure directory exists if err := system.EnsureDir(filepath.Join(homeDir, ".config/tool")); err != nil { return err } // Copy single file if err := system.CopyFile(src, dst); err != nil { return err } // Copy directory contents if err := system.CopyDir("Gentleman.Dots/Config/*", destDir+"/"); err != nil { return err }
ExecResult Structure
type ExecResult struct { Output string // stdout Stderr string // stderr ExitCode int // exit code Error error // error if any } // Usage result := system.Run("command", nil) if result.Error != nil { // Handle error } if result.ExitCode != 0 { // Non-zero exit }
Commands
cd installer && go test ./internal/system/... # Run system tests cd installer && go test -run TestDetect # Test OS detection cd installer && go test -run TestExec # Test command execution
Resources
- Detection: See
for OS detectioninstaller/internal/system/detect.go - Execution: See
for command runninginstaller/internal/system/exec.go - Backup: See
for backup/restoreinstaller/internal/system/backup.go - Tests: See
for patternsinstaller/internal/system/*_test.go