376 lines
18 KiB
Go
376 lines
18 KiB
Go
package term
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
)
|
|
|
|
type CmdConfig struct {
|
|
Cmd string
|
|
Alias string
|
|
Desc string
|
|
Repl bool
|
|
}
|
|
|
|
var CliCommands = []CmdConfig{
|
|
{"", "", "start the Plandex REPL", false},
|
|
|
|
// {"--full", "", fmt.Sprintf("start the Plandex REPL with auto-mode %s", "'full'"), false},
|
|
// {"--semi", "", fmt.Sprintf("start the Plandex REPL with auto-mode %s", "'semi'"), false},
|
|
// {"--plus", "", fmt.Sprintf("start the Plandex REPL with auto-mode %s", "'plus'"), false},
|
|
// {"--basic", "", fmt.Sprintf("start the Plandex REPL with auto-mode %s", "'basic'"), false},
|
|
// {"--none", "", fmt.Sprintf("start the Plandex REPL with auto-mode %s", "'none'"), false},
|
|
|
|
// {"--daily", "", fmt.Sprintf("start the Plandex REPL with %s model pack", "'daily-driver'"), false},
|
|
// {"--strong", "", fmt.Sprintf("start the Plandex REPL with %s model pack", "'strong'"), false},
|
|
// {"--cheap", "", fmt.Sprintf("start the Plandex REPL with %s model pack", "'cheap'"), false},
|
|
// {"--oss", "", fmt.Sprintf("start the Plandex REPL with %s model pack", "'oss'"), false},
|
|
|
|
{"new", "", "start a new plan", true},
|
|
|
|
{"new --full", "", fmt.Sprintf("start a new plan with auto-mode %s", "'full'"), true},
|
|
{"new --semi", "", fmt.Sprintf("start a new plan with auto-mode %s", "'semi'"), true},
|
|
{"new --plus", "", fmt.Sprintf("start a new plan with auto-mode %s", "'plus'"), true},
|
|
{"new --basic", "", fmt.Sprintf("start a new plan with auto-mode %s", "'basic'"), true},
|
|
{"new --none", "", fmt.Sprintf("start a new plan with auto-mode %s", "'none'"), true},
|
|
|
|
{"new --daily", "", fmt.Sprintf("start a new plan with %s model pack", "'daily-driver'"), true},
|
|
{"new --reasoning", "", fmt.Sprintf("start a new plan with %s model pack", "'reasoning'"), true},
|
|
{"new --strong", "", fmt.Sprintf("start a new plan with %s model pack", "'strong'"), true},
|
|
{"new --cheap", "", fmt.Sprintf("start a new plan with %s model pack", "'cheap'"), true},
|
|
{"new --oss", "", fmt.Sprintf("start a new plan with %s model pack", "'oss'"), true},
|
|
{"new --gemini-planner", "", fmt.Sprintf("start a new plan with %s model pack", "'gemini-planner'"), true},
|
|
{"new --o3-planner", "", fmt.Sprintf("start a new plan with %s model pack", "'o3-planner'"), true},
|
|
{"new --r1-planner", "", fmt.Sprintf("start a new plan with %s model pack", "'r1-planner'"), true},
|
|
{"new --perplexity-planner", "", fmt.Sprintf("start a new plan with %s model pack", "'perplexity-planner'"), true},
|
|
{"new --opus-planner", "", fmt.Sprintf("start a new plan with %s model pack", "'opus-planner'"), true},
|
|
|
|
{"plans", "pl", "list plans", true},
|
|
{"cd", "", "set current plan by name or index", true},
|
|
{"current", "cu", "show current plan", true},
|
|
{"rename", "", "rename the current plan", true},
|
|
{"delete-plan", "dp", "delete plan by name or index", true},
|
|
|
|
{"config", "", "show current plan config", true},
|
|
{"set-config", "", "update current plan config", true},
|
|
{"config default", "", "show the default config for new plans", true},
|
|
{"set-config default", "", "update the default config for new plans", true},
|
|
|
|
{"set-auto", "", "update auto-mode (autonomy level) for current plan", true},
|
|
{"set-auto none", "", fmt.Sprintf("set auto-mode to %s", "'none'"), true},
|
|
{"set-auto basic", "", fmt.Sprintf("set auto-mode to %s", "'basic'"), true},
|
|
{"set-auto plus", "", fmt.Sprintf("set auto-mode to %s", "'plus'"), true},
|
|
{"set-auto semi", "", fmt.Sprintf("set auto-mode to %s", "'semi'"), true},
|
|
{"set-auto full", "", fmt.Sprintf("set auto-mode to %s", "'full'"), true},
|
|
|
|
{"set-auto default", "", "set the default auto-mode for new plans", true},
|
|
|
|
{"tell", "t", "describe a task to complete", false},
|
|
{"chat", "ch", "ask a question or chat", false},
|
|
|
|
{"load", "l", "load files/dirs/urls/notes/images or pipe data into context", true},
|
|
{"ls", "", "list everything in context", true},
|
|
{"rm", "", "remove context by index, range, name, or glob", true},
|
|
{"clear", "", "remove all context", true},
|
|
{"update", "u", "update outdated context", true},
|
|
{"show", "", "show current context by name or index", true},
|
|
|
|
{"diff --ui", "", "review pending changes in a browser UI", true},
|
|
{"diff", "", "review pending changes in 'git diff' format", true},
|
|
{"diff --plain", "", "review pending changes in 'git diff' format with no color formatting", false},
|
|
{"summary", "", "show the latest summary of the current plan", true},
|
|
|
|
{"apply", "ap", "apply pending changes to project files", true},
|
|
{"reject", "rj", "reject pending changes to one or more project files", true},
|
|
|
|
{"log", "", "show log of plan updates", true},
|
|
{"rewind", "rw", "rewind to a previous state", true},
|
|
|
|
{"continue", "c", "continue the plan", true},
|
|
{"debug", "db", "repeatedly run a command and auto-apply fixes until it succeeds", true},
|
|
{"build", "b", "build any pending changes", true},
|
|
|
|
{"convo", "", "show plan conversation", true},
|
|
{"convo 1", "", "show a specific message in the conversation", false},
|
|
{"convo 2-5", "", "show a range of messages in the conversation", false},
|
|
{"convo --plain", "", "show conversation in plain text", false},
|
|
|
|
{"branches", "br", "list plan branches", true},
|
|
{"checkout", "co", "checkout or create a branch", true},
|
|
{"delete-branch", "dlb", "delete a branch by name or index", true},
|
|
|
|
{"plans --archived", "", "list archived plans", true},
|
|
{"archive", "arc", "archive a plan", true},
|
|
{"unarchive", "unarc", "unarchive a plan", true},
|
|
|
|
{"models", "", "show current plan model settings", true},
|
|
{"models default", "", "show the default model settings for new plans", true},
|
|
|
|
{"models available", "", "show all available models", true},
|
|
{"models available --custom", "", "show available custom models only", true},
|
|
|
|
{"models custom", "", "manage custom models, providers, and model packs", true},
|
|
|
|
{"providers", "", "show all available model providers", true},
|
|
{"providers --custom", "", "show available custom model providers only", true},
|
|
|
|
{"model-packs", "", "show all available model packs", true},
|
|
|
|
{"model-packs --custom", "", "show custom model packs only", true},
|
|
{"model-packs show", "", "show a built-in or custom model pack's settings", true},
|
|
|
|
{"set-model", "", "update current plan model settings", true},
|
|
{"set-model default", "", "update the default model settings for new plans", true},
|
|
|
|
{"set-model daily", "", fmt.Sprintf("Use %s model pack", "'daily-driver'"), true},
|
|
{"set-model reasoning", "", fmt.Sprintf("Use %s model pack", "'reasoning'"), true},
|
|
{"set-model strong", "", fmt.Sprintf("Use %s model pack", "'strong'"), true},
|
|
{"set-model cheap", "", fmt.Sprintf("Use %s model pack", "'cheap'"), true},
|
|
{"set-model oss", "", fmt.Sprintf("Use %s model pack", "'oss'"), true},
|
|
{"set-model gemini-planner", "", fmt.Sprintf("Use %s model pack", "'gemini-planner'"), true},
|
|
{"set-model o3-planner", "", fmt.Sprintf("Use %s model pack", "'o3-planner'"), true},
|
|
{"set-model r1-planner", "", fmt.Sprintf("Use %s model pack", "'r1-planner'"), true},
|
|
{"set-model perplexity-planner", "", fmt.Sprintf("Use %s model pack", "'perplexity-planner'"), true},
|
|
{"set-model opus-planner", "", fmt.Sprintf("Use %s model pack", "'opus-planner'"), true},
|
|
|
|
{"ps", "", "list active and recently finished plan streams", true},
|
|
{"stop", "", "stop an active plan stream", true},
|
|
{"connect", "conn", "connect to an active plan stream", true},
|
|
|
|
{"sign-in", "", "sign in, accept an invite, or create an account", true},
|
|
{"invite", "", "invite a user to join your org", true},
|
|
{"revoke", "", "revoke an invite or remove a user from your org", true},
|
|
{"users", "", "list users and pending invites in your org", true},
|
|
|
|
{"connect-claude", "", "connect your Claude Pro or Max subscription", true},
|
|
{"disconnect-claude", "", "disconnect your Claude Pro or Max subscription", true},
|
|
{"claude-status", "", "status of your Claude Pro or Max subscription connection", true},
|
|
|
|
{"usage", "", "show Plandex Cloud current balance and usage report", true},
|
|
{"usage --today", "", "show Plandex Cloud usage for the day so far", true},
|
|
{"usage --month", "", "show Plandex Cloud usage for the current billing month", true},
|
|
{"usage --plan", "", "show Plandex Cloud usage for the current plan", true},
|
|
|
|
{"usage --log", "", "show Plandex Cloud transaction log", true},
|
|
|
|
{"billing", "", "show Plandex Cloud billing settings", true},
|
|
}
|
|
|
|
var CmdDesc = map[string]CmdConfig{}
|
|
|
|
func init() {
|
|
for _, cmd := range CliCommands {
|
|
CmdDesc[cmd.Cmd] = cmd
|
|
}
|
|
}
|
|
|
|
func PrintCmds(prefix string, cmds ...string) {
|
|
printCmds(os.Stderr, prefix, []color.Attribute{color.Bold, color.FgHiWhite, color.BgCyan, color.FgHiWhite}, cmds...)
|
|
}
|
|
|
|
func PrintCmdsWithColors(prefix string, colors []color.Attribute, cmds ...string) {
|
|
printCmds(os.Stderr, prefix, colors, cmds...)
|
|
}
|
|
|
|
func printCmds(w io.Writer, prefix string, colors []color.Attribute, cmds ...string) {
|
|
if os.Getenv("PLANDEX_DISABLE_SUGGESTIONS") != "" {
|
|
return
|
|
}
|
|
|
|
for _, cmd := range cmds {
|
|
config, ok := CmdDesc[cmd]
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
if IsRepl && !config.Repl {
|
|
continue
|
|
}
|
|
|
|
alias := config.Alias
|
|
desc := config.Desc
|
|
|
|
if alias != "" {
|
|
if IsRepl {
|
|
cmd = fmt.Sprintf("%s (\\%s)", cmd, alias)
|
|
} else {
|
|
containsFull := strings.Contains(cmd, alias)
|
|
|
|
if containsFull {
|
|
cmd = strings.Replace(cmd, alias, fmt.Sprintf("(%s)", alias), 1)
|
|
} else {
|
|
cmd = fmt.Sprintf("%s (%s)", cmd, alias)
|
|
}
|
|
}
|
|
|
|
// desc += color.New(color.FgWhite).Sprintf(" • alias → %s", fmt.Sprint(a'lias'))
|
|
}
|
|
|
|
var styled string
|
|
if IsRepl {
|
|
styled = color.New(colors...).Sprintf(" \\%s ", cmd)
|
|
} else if cmd == "" { // special case for the repl
|
|
styled = color.New(colors...).Sprintf(" plandex ")
|
|
} else {
|
|
styled = color.New(colors...).Sprintf(" plandex %s ", cmd)
|
|
}
|
|
|
|
fmt.Fprintf(w, "%s%s 👉 %s\n", prefix, styled, desc)
|
|
}
|
|
|
|
}
|
|
|
|
func PrintCustomCmd(prefix, cmd, alias, desc string) {
|
|
cmd = strings.Replace(cmd, alias, fmt.Sprintf("(%s)", alias), 1)
|
|
// desc += color.New(color.FgWhite).Sprintf(" • alias → %s", fmt.Sprint(a'lias'))
|
|
styled := color.New(color.Bold, color.FgHiWhite, color.BgCyan, color.FgHiWhite).Sprintf(" plandex %s ", cmd)
|
|
fmt.Printf("%s%s 👉 %s\n", prefix, styled, desc)
|
|
}
|
|
|
|
// PrintCustomHelp prints the custom help output for the Plandex CLI
|
|
func PrintCustomHelp(all bool) {
|
|
builder := &strings.Builder{}
|
|
|
|
color.New(color.Bold, color.BgGreen, color.FgHiWhite).Fprintln(builder, " Usage ")
|
|
color.New(color.Bold).Fprintln(builder, " plandex [command] [flags]")
|
|
color.New(color.Bold).Fprintln(builder, " pdx [command] [flags]")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgGreen, color.FgHiWhite).Fprintln(builder, " Help ")
|
|
color.New(color.Bold).Fprintln(builder, " plandex help # show basic usage")
|
|
color.New(color.Bold).Fprintln(builder, " plandex help --all # show all commands")
|
|
color.New(color.Bold).Fprintln(builder, " plandex [command] --help")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgMagenta, color.FgHiWhite).Fprintln(builder, " Getting Started ")
|
|
fmt.Fprintln(builder)
|
|
fmt.Fprintf(builder, " 🚀 Start the Plandex REPL in a project directory with %s or %s\n", color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" plandex "), color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" pdx "))
|
|
fmt.Fprintln(builder)
|
|
fmt.Fprintf(builder, " 💻 You can also use any command outside the REPL with %s or %s\n", color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" plandex [command] "), color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" pdx [command] "))
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgMagenta, color.FgHiWhite).Fprintln(builder, " REPL Options ")
|
|
fmt.Fprintln(builder)
|
|
// Add REPL startup flags
|
|
fmt.Fprintln(builder, color.New(color.Bold, color.FgHiBlue).Sprint(" Mode "))
|
|
fmt.Fprintln(builder, " --chat, -c Start in chat mode (for conversation without making changes)")
|
|
fmt.Fprintln(builder, " --tell, -t Start in tell mode (for implementation)")
|
|
fmt.Fprintln(builder)
|
|
|
|
fmt.Fprintln(builder, color.New(color.Bold, color.FgHiBlue).Sprint(" Autonomy "))
|
|
fmt.Fprintln(builder, " --no-auto None → step-by-step, no automation")
|
|
fmt.Fprintln(builder, " --basic Basic → auto-continue plans")
|
|
fmt.Fprintln(builder, " --plus Plus → auto-update context, smart context, auto-commit changes")
|
|
fmt.Fprintln(builder, " --semi Semi-Auto → auto-load context")
|
|
fmt.Fprintln(builder, " --full Full-Auto → auto-apply, auto-exec, auto-debug")
|
|
fmt.Fprintln(builder)
|
|
|
|
fmt.Fprintln(builder, color.New(color.Bold, color.FgHiBlue).Sprint(" Models "))
|
|
fmt.Fprintln(builder, " --daily Daily driver pack")
|
|
fmt.Fprintln(builder, " --reasoning Reasoning pack")
|
|
fmt.Fprintln(builder, " --strong Strong pack")
|
|
fmt.Fprintln(builder, " --cheap Cheap pack")
|
|
fmt.Fprintln(builder, " --oss Open source pack")
|
|
|
|
fmt.Fprintln(builder)
|
|
|
|
if all {
|
|
fmt.Print(builder.String())
|
|
PrintHelpAllCommands()
|
|
} else {
|
|
fmt.Print(builder.String())
|
|
// in the same style as 'getting started' section, output See All Commands
|
|
|
|
color.New(color.Bold, color.BgHiBlue, color.FgHiWhite).Fprintln(builder, " Use 'plandex help --all' or 'plandex help -a' for a list of all commands ")
|
|
fmt.Fprintln(builder)
|
|
|
|
fmt.Print(builder.String())
|
|
}
|
|
|
|
}
|
|
|
|
func PrintHelpAllCommands() {
|
|
builder := &strings.Builder{}
|
|
|
|
color.New(color.Bold, color.BgMagenta, color.FgHiWhite).Fprintln(builder, " Key Commands ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, color.FgHiMagenta}, "new", "load", "tell", "diff", "diff --ui", "apply", "reject", "debug", "chat")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Plans ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "new", "plans", "cd", "current", "delete-plan", "rename", "archive", "plans --archived", "unarchive")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Changes ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "diff", "diff --ui", "diff --plain", "apply", "reject")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Context ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "load", "ls", "rm", "update", "clear")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Branches ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "branches", "checkout", "delete-branch")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " History ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "log", "rewind", "convo", "convo 1", "convo 2-5", "convo --plain", "summary")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Control ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "tell", "continue", "build", "debug", "chat")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Streams ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "ps", "connect", "stop")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Config ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "config", "set-config", "config default", "set-config default")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Autonomy ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "set-auto", "set-auto default", "set-auto full", "set-auto semi", "set-auto plus", "set-auto basic", "set-auto none")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " AI Models ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "models", "models default", "model-packs", "set-model", "set-model daily", "set-model reasoning", "set-model strong", "set-model cheap", "set-model oss", "set-model default")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Custom Models ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan},
|
|
"models custom", "models available", "models available --custom", "providers", "providers --custom", "model-packs", "model-packs --custom", "model-packs show")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Accounts ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "sign-in", "invite", "revoke", "users")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Integrations ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "connect-claude", "disconnect-claude", "claude-status")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Cloud ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "usage", "usage --today", "usage --month", "usage --plan", "usage --log", "billing")
|
|
fmt.Fprintln(builder)
|
|
|
|
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " New Plan Shortcuts ")
|
|
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "new --full", "new --semi", "new --plus", "new --basic", "new --none", "new --daily", "new --reasoning", "new --strong", "new --cheap", "new --oss", "new --gemini-planner", "new --o3-planner", "new --r1-planner", "new --perplexity-planner", "new --opus-planner")
|
|
fmt.Fprintln(builder)
|
|
|
|
fmt.Print(builder.String())
|
|
}
|
|
|
|
func ShowCmd(cmd string) string {
|
|
if IsRepl {
|
|
cmd = fmt.Sprintf("\\%s", cmd)
|
|
} else {
|
|
cmd = fmt.Sprintf("plandex %s", cmd)
|
|
}
|
|
|
|
return color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprintf(" %s ", cmd)
|
|
}
|