chore(commands): more commands for suggestions (#10)

## What's new
- color completion message command green
https://github.com/versenilvis/IRIS/pull/10/commits/6e141f5e6909fad1ec42725cce38d51729acf399
- new flat command folder structure
https://github.com/versenilvis/IRIS/pull/10/commits/87026a854a529ec5d5baed967d5f7a7f0085a24b
- fix some linter problems
https://github.com/versenilvis/IRIS/pull/10/commits/536de790cefda912f50bf4022e40ce2b965db2e2
- fix some gemini fix suggestions
This commit is contained in:
VERSE
2026-06-23 10:27:26 +07:00
committed by GitHub
parent 3d76a3ee88
commit a2972f61f1
42 changed files with 2406 additions and 245 deletions
+57
View File
@@ -0,0 +1,57 @@
package sys
import (
"os"
"strings"
"github.com/versenilvis/iris/commands/core"
)
func envVarGenerator(tokens []string, _ string, _ string) []core.Suggestion {
var results []core.Suggestion
for _, env := range os.Environ() {
parts := strings.SplitN(env, "=", 2)
name := parts[0]
val := ""
if len(parts) == 2 {
val = parts[1]
// truncate long values
if len(val) > 60 {
val = val[:57] + "..."
}
}
results = append(results, core.Suggestion{Cmd: name, Desc: val})
}
return results
}
func init() {
core.Register(&core.Spec{
Name: "export",
Description: "set environment variable",
Generator: envVarGenerator,
})
core.Register(&core.Spec{
Name: "env",
Description: "print environment",
Generator: envVarGenerator,
Options: []core.Option{
{Name: "-i", Description: "start with empty env"},
{Name: "-u", Description: "unset variable"},
{Name: "-0", Description: "null delimited"},
},
})
core.Register(&core.Spec{
Name: "printenv",
Description: "print environment variables",
Generator: envVarGenerator,
})
core.Register(&core.Spec{
Name: "unset",
Description: "unset variable",
Generator: envVarGenerator,
})
}
+156
View File
@@ -0,0 +1,156 @@
package sys
import (
"github.com/versenilvis/iris/commands/core"
)
func init() {
core.Register(&core.Spec{
Name: "curl",
Description: "transfer data via URL",
Generator: core.FileGenerator(),
Options: []core.Option{
{Name: "-X", Description: "request method (GET/POST/PUT/DELETE)"},
{Name: "-H", Description: "request header"},
{Name: "-d", Description: "request body data"},
{Name: "-o", Description: "output to file"},
{Name: "-O", Description: "save with remote filename"},
{Name: "-s", Description: "silent mode"},
{Name: "-S", Description: "show error in silent"},
{Name: "-L", Description: "follow redirects"},
{Name: "-k", Description: "insecure (skip TLS verify)"},
{Name: "-I", Description: "fetch headers only"},
{Name: "-v", Description: "verbose"},
{Name: "-u", Description: "user:password"},
{Name: "-b", Description: "send cookie"},
{Name: "-c", Description: "save cookie to file"},
{Name: "-F", Description: "multipart form data"},
{Name: "--json", Description: "send JSON body"},
{Name: "--compressed", Description: "request compressed response"},
{Name: "--max-time", Description: "max time in seconds"},
{Name: "--retry", Description: "retry count"},
{Name: "-A", Description: "custom user-agent"},
{Name: "--proxy", Description: "use proxy"},
{Name: "-T", Description: "upload file"},
},
})
core.Register(&core.Spec{
Name: "wget",
Description: "non-interactive downloader",
Generator: core.FileGenerator(),
Options: []core.Option{
{Name: "-O", Description: "output filename"},
{Name: "-q", Description: "quiet"},
{Name: "-v", Description: "verbose"},
{Name: "-r", Description: "recursive"},
{Name: "-P", Description: "output directory"},
{Name: "-c", Description: "continue download"},
{Name: "--no-check-certificate", Description: "skip TLS verify"},
{Name: "-b", Description: "background"},
{Name: "--limit-rate", Description: "limit rate"},
{Name: "-U", Description: "custom user-agent"},
{Name: "--spider", Description: "check URL only"},
{Name: "-np", Description: "no parent directories"},
{Name: "-nH", Description: "no host directories"},
},
})
core.Register(&core.Spec{
Name: "nc",
Description: "netcat - TCP/UDP tool",
Options: []core.Option{
{Name: "-l", Description: "listen mode"},
{Name: "-p", Description: "local port"},
{Name: "-z", Description: "port scan mode"},
{Name: "-v", Description: "verbose"},
{Name: "-u", Description: "UDP mode"},
{Name: "-n", Description: "no DNS"},
{Name: "-w", Description: "timeout"},
},
})
core.Register(&core.Spec{
Name: "ping",
Description: "test network connectivity",
Options: []core.Option{
{Name: "-c", Description: "packet count"},
{Name: "-i", Description: "interval"},
{Name: "-t", Description: "TTL"},
{Name: "-s", Description: "packet size"},
{Name: "-q", Description: "quiet output"},
},
})
core.Register(&core.Spec{
Name: "dig",
Description: "DNS lookup",
Options: []core.Option{
{Name: "+short", Description: "short output"},
{Name: "+noall", Description: "no output flags"},
{Name: "+answer", Description: "answer section only"},
{Name: "-t", Description: "record type"},
{Name: "@", Description: "nameserver"},
},
})
core.Register(&core.Spec{
Name: "nslookup",
Description: "query DNS",
})
core.Register(&core.Spec{
Name: "ifconfig",
Description: "configure network interface",
Options: []core.Option{
{Name: "-a", Description: "all interfaces"},
},
})
core.Register(&core.Spec{
Name: "ip",
Description: "show/manage network",
Subcommands: []core.Subcommand{
{Name: "addr", Description: "address management"},
{Name: "link", Description: "network device management"},
{Name: "route", Description: "routing table management"},
{Name: "neigh", Description: "ARP table"},
{Name: "rule", Description: "routing policy"},
},
Options: []core.Option{
{Name: "-4", Description: "IPv4 only"},
{Name: "-6", Description: "IPv6 only"},
{Name: "-br", Description: "brief output"},
{Name: "-c", Description: "colorize"},
},
})
core.Register(&core.Spec{
Name: "netstat",
Description: "network statistics",
Options: []core.Option{
{Name: "-t", Description: "TCP connections"},
{Name: "-u", Description: "UDP connections"},
{Name: "-l", Description: "listening only"},
{Name: "-n", Description: "numeric addresses"},
{Name: "-p", Description: "show PID"},
{Name: "-r", Description: "routing table"},
{Name: "-s", Description: "statistics"},
},
})
core.Register(&core.Spec{
Name: "ss",
Description: "socket statistics",
Options: []core.Option{
{Name: "-t", Description: "TCP"},
{Name: "-u", Description: "UDP"},
{Name: "-l", Description: "listening"},
{Name: "-n", Description: "numeric"},
{Name: "-p", Description: "show process"},
{Name: "-a", Description: "all"},
{Name: "-4", Description: "IPv4"},
{Name: "-6", Description: "IPv6"},
},
})
}
+109
View File
@@ -0,0 +1,109 @@
package sys
import (
"context"
"os/exec"
"strings"
"time"
"github.com/versenilvis/iris/commands/core"
)
func processGenerator(tokens []string, _ string, _ string) []core.Suggestion {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// output: "pid command"
cmd := exec.CommandContext(ctx, "ps", "-eo", "pid,comm")
out, err := cmd.Output()
if err != nil {
return nil
}
seen := make(map[string]bool)
var results []core.Suggestion
for _, line := range strings.Split(string(out), "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
parts := strings.Fields(line)
if len(parts) < 2 {
continue
}
pid := parts[0]
if pid[0] < '0' || pid[0] > '9' {
continue
}
name := parts[1]
// suggest both PID and process name
if !seen[pid] {
seen[pid] = true
results = append(results, core.Suggestion{Cmd: pid, Desc: name})
}
}
return results
}
func init() {
core.Register(&core.Spec{
Name: "ps",
Description: "report processes",
Options: []core.Option{
{Name: "-e", Description: "all processes"},
{Name: "-f", Description: "full format"},
{Name: "-u", Description: "by user"},
{Name: "aux", Description: "all + user + x"},
{Name: "-o", Description: "custom format"},
{Name: "--pid", Description: "filter by PID"},
{Name: "--sort", Description: "sort by field"},
},
})
core.Register(&core.Spec{
Name: "kill",
Description: "send signal to process",
Generator: processGenerator,
Options: []core.Option{
{Name: "-9", Description: "SIGKILL (force)"},
{Name: "-15", Description: "SIGTERM (graceful)"},
{Name: "-2", Description: "SIGINT"},
{Name: "-HUP", Description: "SIGHUP (reload)"},
{Name: "-l", Description: "list signal names"},
},
})
core.Register(&core.Spec{
Name: "killall",
Description: "kill by process name",
Generator: processGenerator,
Options: []core.Option{
{Name: "-9", Description: "SIGKILL"},
{Name: "-s", Description: "specify signal"},
{Name: "-u", Description: "only for user"},
{Name: "-i", Description: "confirm each"},
},
})
core.Register(&core.Spec{
Name: "pkill",
Description: "kill by pattern",
Options: []core.Option{
{Name: "-9", Description: "SIGKILL"},
{Name: "-f", Description: "match full command"},
{Name: "-u", Description: "match by user"},
},
})
core.Register(&core.Spec{
Name: "pgrep",
Description: "find process by pattern",
Options: []core.Option{
{Name: "-l", Description: "list name and PID"},
{Name: "-f", Description: "match full command"},
{Name: "-u", Description: "match by user"},
{Name: "-a", Description: "list command line"},
},
})
}