2026-05-02 01:12:55 +03:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/zemenawi/zutils/pkg/colors"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type CommandHelp struct {
|
|
|
|
|
Name string
|
|
|
|
|
Help string
|
|
|
|
|
Examples []string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var readHelp = CommandHelp{
|
|
|
|
|
Name: "read",
|
|
|
|
|
Help: "Read and display file with smart detection.\n" +
|
|
|
|
|
"Automatically detects file type:\n" +
|
|
|
|
|
" - Markdown (.md) - Renders with colored headings, lists, code blocks\n" +
|
|
|
|
|
" - Code files - Syntax highlighting with line numbers\n" +
|
|
|
|
|
" - Other files - Plain text display",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z read README.md # Read markdown file",
|
|
|
|
|
"z read main.go # Read code with syntax highlighting",
|
|
|
|
|
"z read package.json # Read JSON file",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var sysHelp = CommandHelp{
|
|
|
|
|
Name: "sys",
|
|
|
|
|
Help: "Show system overview including CPU, memory, disk usage, and top processes.\n" +
|
|
|
|
|
"Useful for quick system diagnostics.",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z sys # Show full system overview",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var findHelp = CommandHelp{
|
|
|
|
|
Name: "find",
|
|
|
|
|
Help: "Find files matching criteria.\n" +
|
|
|
|
|
"Supports glob patterns, size filters, modification time, and depth limits.",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z find . -name '*.go' # Find all Go files",
|
|
|
|
|
"z find . -mtime 7 # Files modified in last 7 days",
|
|
|
|
|
"z find . -size +1m # Files larger than 1MB",
|
|
|
|
|
"z find . -type d # Directories only",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var searchHelp = CommandHelp{
|
|
|
|
|
Name: "search",
|
|
|
|
|
Help: "Search for a pattern in files.\n" +
|
|
|
|
|
"A user-friendly alternative to grep with colored output.",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z search func cmd/ # Search for 'func' in cmd directory",
|
|
|
|
|
"z search -i 'error' . # Case-insensitive search",
|
|
|
|
|
"z search -w 'import' *.go # Whole word match",
|
|
|
|
|
"z search -C 2 'TODO' . # Show 2 lines of context",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var usageHelp = CommandHelp{
|
|
|
|
|
Name: "usage",
|
|
|
|
|
Help: "Show resource usage (CPU, memory) for processes matching a name.\n" +
|
|
|
|
|
"Useful for monitoring specific applications or services.",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z usage cron # Show cron process usage",
|
|
|
|
|
"z usage mongod # Show MongoDB usage",
|
|
|
|
|
"z usage chrome # Show all Chrome processes",
|
|
|
|
|
"z usage postgres # Show PostgreSQL usage",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
feat: add permission interpreter, junks, ports, usages, network commands
New Commands:
- z network: Show IP addresses, public IP, DNS servers, active connections
- z ports: List listening ports with process/PID info
- z usages: All processes sorted by resource usage with filtering
- z junks: Find and clean junk files (caches, temporary files)
Enhancements:
- Permission interpreter in z info file - shows human-readable permissions
e.g. -rw-rw-r-- → "Owner can read, write; Group can read, write; Other can read"
- z usages now supports filtering: z usages chrome -m -n=50
- Summary section shows total CPU/memory when filtering by name
- Added help entries for all new commands
2026-05-02 01:53:36 +03:00
|
|
|
var junksHelp = CommandHelp{
|
|
|
|
|
Name: "junks",
|
|
|
|
|
Help: "Find and clean junk files (caches, temporary files).\n" +
|
|
|
|
|
"Shows storage taken by build outputs, caches, and temporary files.\n" +
|
|
|
|
|
"Safe to clean: build outputs, caches, temporary files.\n" +
|
|
|
|
|
"Not cleanable: runtime version files (require manual cleanup).",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z junks # List junk files and space usage",
|
|
|
|
|
"z junks clean # Preview what will be cleaned",
|
|
|
|
|
"z junks clean --force # Actually clean junk files",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var portsHelp = CommandHelp{
|
|
|
|
|
Name: "ports",
|
|
|
|
|
Help: "Show all listening ports and the processes using them.\n" +
|
|
|
|
|
"Useful for debugging network services and finding port conflicts.",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z ports # Show listening ports",
|
|
|
|
|
"z ports -a # Show all ports (including established)",
|
|
|
|
|
"z ports 8080 # Filter by specific port",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var usagesHelp = CommandHelp{
|
|
|
|
|
Name: "usages",
|
|
|
|
|
Help: "Show all running processes sorted by resource usage.\n" +
|
|
|
|
|
"By default sorts by CPU usage. Use -m to sort by memory.",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z usages # Top processes by CPU",
|
|
|
|
|
"z usages -m # Top processes by memory",
|
|
|
|
|
"z usages -n=50 # Show top 50 processes",
|
|
|
|
|
"z usages chrome # Filter processes by name",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var networkHelp = CommandHelp{
|
|
|
|
|
Name: "network",
|
|
|
|
|
Help: "Show network information including:\n" +
|
|
|
|
|
" - Local IP addresses\n" +
|
|
|
|
|
" - Public IP\n" +
|
|
|
|
|
" - DNS servers\n" +
|
|
|
|
|
" - Active network connections",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z network # Show network overview",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 02:10:14 +03:00
|
|
|
var treeHelp = CommandHelp{
|
|
|
|
|
Name: "tree",
|
|
|
|
|
Help: "Display directory tree with file sizes and gitignore support.\n" +
|
|
|
|
|
"Shows [ignored by git] label for gitignored files.\n" +
|
|
|
|
|
"File sizes shown in parentheses for regular files.",
|
|
|
|
|
Examples: []string{
|
|
|
|
|
"z tree # Show current directory tree",
|
|
|
|
|
"z tree /path/to/dir # Show specific directory",
|
|
|
|
|
"z tree -a # Show hidden files",
|
|
|
|
|
"z tree -i # Show gitignored files",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 01:12:55 +03:00
|
|
|
func PrintErrorAndHelp(name string, err error) {
|
|
|
|
|
help := getHelpForCommand(name)
|
|
|
|
|
|
|
|
|
|
fmt.Printf("\n %s✖ Error: %s%s\n\n", colors.Red, err, colors.Reset)
|
|
|
|
|
|
|
|
|
|
if help != nil {
|
|
|
|
|
fmt.Printf(" %sUsage:%s z %s %s\n\n", colors.Bold, colors.Reset, help.Name, getUsageHint(help.Name))
|
|
|
|
|
|
|
|
|
|
if help.Help != "" {
|
|
|
|
|
fmt.Printf(" %sDescription:%s\n", colors.Bold, colors.Reset)
|
|
|
|
|
lines := splitIntoLines(help.Help, 60)
|
|
|
|
|
for _, line := range lines {
|
|
|
|
|
fmt.Printf(" %s%s%s\n", colors.Reset, line, colors.Reset)
|
|
|
|
|
}
|
|
|
|
|
fmt.Printf("\n")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(help.Examples) > 0 {
|
|
|
|
|
fmt.Printf(" %sExamples:%s\n", colors.Bold, colors.Reset)
|
|
|
|
|
for _, ex := range help.Examples {
|
|
|
|
|
fmt.Printf(" %s%s%s\n", colors.Green, ex, colors.Reset)
|
|
|
|
|
}
|
|
|
|
|
fmt.Printf("\n")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getHelpForCommand(name string) *CommandHelp {
|
|
|
|
|
switch name {
|
|
|
|
|
case "read":
|
|
|
|
|
return &readHelp
|
|
|
|
|
case "sys":
|
|
|
|
|
return &sysHelp
|
|
|
|
|
case "find":
|
|
|
|
|
return &findHelp
|
|
|
|
|
case "search":
|
|
|
|
|
return &searchHelp
|
|
|
|
|
case "usage":
|
|
|
|
|
return &usageHelp
|
feat: add permission interpreter, junks, ports, usages, network commands
New Commands:
- z network: Show IP addresses, public IP, DNS servers, active connections
- z ports: List listening ports with process/PID info
- z usages: All processes sorted by resource usage with filtering
- z junks: Find and clean junk files (caches, temporary files)
Enhancements:
- Permission interpreter in z info file - shows human-readable permissions
e.g. -rw-rw-r-- → "Owner can read, write; Group can read, write; Other can read"
- z usages now supports filtering: z usages chrome -m -n=50
- Summary section shows total CPU/memory when filtering by name
- Added help entries for all new commands
2026-05-02 01:53:36 +03:00
|
|
|
case "junks":
|
|
|
|
|
return &junksHelp
|
|
|
|
|
case "ports":
|
|
|
|
|
return &portsHelp
|
|
|
|
|
case "usages":
|
|
|
|
|
return &usagesHelp
|
|
|
|
|
case "network":
|
|
|
|
|
return &networkHelp
|
2026-05-02 02:10:14 +03:00
|
|
|
case "tree":
|
|
|
|
|
return &treeHelp
|
2026-05-02 01:12:55 +03:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getUsageHint(name string) string {
|
|
|
|
|
switch name {
|
|
|
|
|
case "read":
|
|
|
|
|
return "<file>"
|
|
|
|
|
case "sys":
|
|
|
|
|
return ""
|
|
|
|
|
case "find":
|
|
|
|
|
return "[path] [options]"
|
|
|
|
|
case "search":
|
|
|
|
|
return "<pattern> [path]"
|
|
|
|
|
case "usage":
|
|
|
|
|
return "<process-name>"
|
feat: add permission interpreter, junks, ports, usages, network commands
New Commands:
- z network: Show IP addresses, public IP, DNS servers, active connections
- z ports: List listening ports with process/PID info
- z usages: All processes sorted by resource usage with filtering
- z junks: Find and clean junk files (caches, temporary files)
Enhancements:
- Permission interpreter in z info file - shows human-readable permissions
e.g. -rw-rw-r-- → "Owner can read, write; Group can read, write; Other can read"
- z usages now supports filtering: z usages chrome -m -n=50
- Summary section shows total CPU/memory when filtering by name
- Added help entries for all new commands
2026-05-02 01:53:36 +03:00
|
|
|
case "junks":
|
|
|
|
|
return "[clean]"
|
|
|
|
|
case "ports":
|
|
|
|
|
return "[-a] [port]"
|
|
|
|
|
case "usages":
|
|
|
|
|
return "[-m] [-n=N]"
|
|
|
|
|
case "network":
|
|
|
|
|
return ""
|
2026-05-02 02:10:14 +03:00
|
|
|
case "tree":
|
|
|
|
|
return "[path] [-a] [-i]"
|
2026-05-02 01:12:55 +03:00
|
|
|
case "info":
|
|
|
|
|
return "<file|dir|network>"
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func splitIntoLines(text string, maxLen int) []string {
|
|
|
|
|
var lines []string
|
|
|
|
|
paragraphs := splitIntoParagraphs(text)
|
|
|
|
|
|
|
|
|
|
for _, para := range paragraphs {
|
|
|
|
|
if para == "" {
|
|
|
|
|
lines = append(lines, "")
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
words := strings.Fields(para)
|
|
|
|
|
currentLine := ""
|
|
|
|
|
|
|
|
|
|
for _, word := range words {
|
|
|
|
|
if currentLine == "" {
|
|
|
|
|
currentLine = word
|
|
|
|
|
} else if len(currentLine)+len(word)+1 <= maxLen {
|
|
|
|
|
currentLine += " " + word
|
|
|
|
|
} else {
|
|
|
|
|
lines = append(lines, currentLine)
|
|
|
|
|
currentLine = word
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if currentLine != "" {
|
|
|
|
|
lines = append(lines, currentLine)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return lines
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func splitIntoParagraphs(text string) []string {
|
|
|
|
|
var paragraphs []string
|
|
|
|
|
lines := strings.Split(text, "\n")
|
|
|
|
|
|
|
|
|
|
current := ""
|
|
|
|
|
for _, line := range lines {
|
|
|
|
|
trimmed := strings.TrimSpace(line)
|
|
|
|
|
if trimmed == "" {
|
|
|
|
|
if current != "" {
|
|
|
|
|
paragraphs = append(paragraphs, current)
|
|
|
|
|
current = ""
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if current != "" {
|
|
|
|
|
current += " "
|
|
|
|
|
}
|
|
|
|
|
current += trimmed
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if current != "" {
|
|
|
|
|
paragraphs = append(paragraphs, current)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return paragraphs
|
|
|
|
|
}
|