Skip to content

Commit

Permalink
summary --plain flag, better vim instructions, better help text, read…
Browse files Browse the repository at this point in the history
…me and docs updates, release notes
  • Loading branch information
danenania committed Jun 11, 2024
1 parent be49a6a commit 7c00ec3
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 56 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ Plandex Cloud follows best practices for network and data security. And whether
## Roadmap  🗺️

🧠  Support for open source models, Google Gemini, and Anthropic Claude in addition to OpenAI  ✅ released<br>
🖼️  Support for multi-modal models—add images and screenshots to context ✅ released<br>
🤝  Plan sharing and team collaboration<br>
🖼️  Support for multi-modal models—add images and screenshots to context<br>
🖥️  VSCode and JetBrains extensions<br>
📦  Community plugins and modules<br>
🔌  Github integration<br>
Expand Down
7 changes: 6 additions & 1 deletion app/cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/spf13/cobra"
)

var helpShowAll bool

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: `plandex [command] [flags]`,
Expand Down Expand Up @@ -36,9 +38,12 @@ func init() {
Short: "Display help for Plandex",
Long: `Display help for Plandex.`,
Run: func(cmd *cobra.Command, args []string) {
term.PrintCustomHelp()
term.PrintCustomHelp(helpShowAll)
},
}

RootCmd.AddCommand(helpCmd)

// add an --all/-a flag
helpCmd.Flags().BoolVarP(&helpShowAll, "all", "a", false, "Show all commands")
}
9 changes: 9 additions & 0 deletions app/cli/cmd/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/spf13/cobra"
)

var summaryPlain bool

var statusCmd = &cobra.Command{
Use: "summary",
Short: "Show the latest summary of the current plan",
Expand All @@ -18,6 +20,8 @@ var statusCmd = &cobra.Command{

func init() {
RootCmd.AddCommand(statusCmd)

statusCmd.Flags().BoolVarP(&summaryPlain, "plain", "p", false, "Output summary in plain text with no ANSI codes")
}

func status(cmd *cobra.Command, args []string) {
Expand All @@ -36,6 +40,11 @@ func status(cmd *cobra.Command, args []string) {
fmt.Println("🤷‍♂️ No summary available")
}

if summaryPlain {
fmt.Println(status)
return
}

md, err := term.GetMarkdown(status)

if err != nil {
Expand Down
4 changes: 1 addition & 3 deletions app/cli/cmd/tell.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ func prepareEditorCommand(editor string, filename string) *exec.Cmd {
}

func getEditorInstructions(editor string) string {

return "Write your prompt below, then save and exit to send it to Plandex.\n\n"

return "👉 Write your prompt below, then save and exit to send it to Plandex.\n• To save and exit, press ESC, then type :wq! and press ENTER.\n• To exit without saving, press ESC, then type :q! and press ENTER.\n\n\n"
}

func getEditorPrompt() string {
Expand Down
2 changes: 1 addition & 1 deletion app/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func main() {
// Manually check for help flags at the root level
if len(os.Args) == 2 && (os.Args[1] == "-h" || os.Args[1] == "--help") {
// Display your custom help here
term.PrintCustomHelp()
term.PrintCustomHelp(true)
os.Exit(0)
}

Expand Down
79 changes: 47 additions & 32 deletions app/cli/term/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func PrintCustomCmd(prefix, cmd, alias, desc string) {
}

// PrintCustomHelp prints the custom help output for the Plandex CLI
func PrintCustomHelp() {
func PrintCustomHelp(all bool) {
builder := &strings.Builder{}

color.New(color.Bold, color.BgGreen, color.FgHiWhite).Fprintln(builder, " Usage ")
Expand All @@ -120,51 +120,66 @@ func PrintCustomHelp() {

color.New(color.Bold, color.BgGreen, color.FgHiWhite).Fprintln(builder, " Help ")
color.New(color.Bold).Fprintln(builder, " plandex help")
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.Fprintf(builder, " Create a new plan in your project's root directory with %s\n\n", color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" plandex new "))

color.New(color.Bold, color.BgMagenta, color.FgHiWhite).Fprintln(builder, " Key Commands ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiMagenta}, "new", "load", "tell", "changes", "diffs", "apply", "reject")
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.Fprintf(builder, " 1 - Create a new plan in your project's root directory with %s\n", color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" plandex new "))
fmt.Fprintln(builder)

color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Changes ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "changes", "diff", "apply", "reject")
fmt.Fprintf(builder, " 2 - Load any relevant context with %s\n", color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" plandex load [file-path-or-url] "))
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.Fprintf(builder, " 3 - Describe a task, ask a question, or chat with %s\n", color.New(color.Bold, color.BgCyan, color.FgHiWhite).Sprint(" plandex tell "))
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)
if all {
color.New(color.Bold, color.BgMagenta, color.FgHiWhite).Fprintln(builder, " Key Commands ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiMagenta}, "new", "load", "tell", "changes", "diff", "apply", "reject")
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")
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, " Control ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "tell", "continue", "build")
fmt.Fprintln(builder)
color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Changes ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "changes", "diff", "apply", "reject")
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, " 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, " AI Models ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "models", "models default", "models available", "set-model", "set-model default", "models available --custom", "models add", "models delete", "model-packs", "model-packs --custom", "model-packs create", "model-packs delete")
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, " 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, " History ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "log", "rewind", "convo", "convo 1", "convo 2-5", "convo --plain")
fmt.Fprintln(builder)

color.New(color.Bold, color.BgCyan, color.FgHiWhite).Fprintln(builder, " Control ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "tell", "continue", "build")
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, " AI Models ")
printCmds(builder, " ", []color.Attribute{color.Bold, ColorHiCyan}, "models", "models default", "models available", "set-model", "set-model default", "models available --custom", "models add", "models delete", "model-packs", "model-packs --custom", "model-packs create", "model-packs delete")
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)
} else {

// 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.Print(builder.String())
}
7 changes: 6 additions & 1 deletion app/server/handlers/plans_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,12 @@ func RejectFilesHandler(w http.ResponseWriter, r *http.Request) {
return
}

msg := "🚫 Rejected pending changes to files:"
msg := "🚫 Rejected pending changes to file"
if len(req.Paths) > 1 {
msg += "s"
}
msg += ":"

for _, path := range req.Paths {
msg += fmt.Sprintf("\n • %s", path)
}
Expand Down
49 changes: 42 additions & 7 deletions guides/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,38 @@

## Provider API key(s)  🔑

By default, Plandex uses the OpenAI API. While you can now use Plandex with many different providers and models, for some functionality Plandex has requirements that only OpenAI models, for the time being, can satisfy. That means you'll need an OpenAI account to get started even if you plan to use other model providers.
By default, Plandex uses the OpenAI API. While you can use Plandex with many different providers and models, Plandex requires reliable function calling, which can still be a challenge to find in non-OpenAI models. For getting started, it's recommended to begin with OpenAI.

If you don't have an OpenAI account, first [sign up here.](https://platform.openai.com/signup)

Then [generate an API key here.](https://platform.openai.com/account/api-keys)

You'll also need API keys for any other providers you plan on using, like OpenRouter.ai (Anthropic, Gemini, and open source models), Together.ai (open source models), Replicate, Ollama, and more.

## New plan  🪄
## Environment variables  💻

```bash
cd your-project

export OPENAI_API_KEY=...
export OPENAI_API_BASE=... # optional e.g. https://<your-proxy>/v1
export OPENAI_ORG_ID=... # optional - set the OrgID if you have multiple OpenAI orgs

export OPENAI_API_BASE=... # optional - set a different base url for OpenAI calls e.g. https://<your-proxy>/v1
export OPENAI_ORG_ID=... # optional - set the OpenAI OrgID if you have multiple orgs

# optional - set api keys for any other providers you're using
export OPENROUTER_API_KEY=...
export TOGETHER_API_KEY...
```

## New plan  🪄

Now `cd` into your **project's directory.** Make a new directory first with `mkdir your-project-dir` if you're starting on a new project.

```bash
cd your-project-dir
```

Then **start your first plan** with `plandex new`.

```bash
plandex new
```

Expand All @@ -36,7 +47,7 @@ If you don't give your plan a name up front, it will be named 'draft' until you

## Loading context  📄

After creating a plan, load any relevant files, directories, directory layouts, urls, or other data into the plan context.
After creating a plan, load any relevant files, images, directories, directory layouts, urls, or other data into the plan context.

```bash
plandex load component.ts action.ts reducer.ts
Expand All @@ -46,8 +57,11 @@ plandex load . --tree # loads the layout of the current directory and its subdir
plandex load https://redux.js.org/usage/writing-tests # loads the text-only content of the url
npm test | plandex load # loads the output of `npm test`
plandex load -n 'add logging statements to all the code you generate.' # load a note into context
plandex load ui-mockup.png # load an image into context (GPT-4o only so far)
```

For loading images, png, jpeg, non-animated gif, and webp formats are supported. So far, this feature is only available with the default OpenAI GPT-4o model.

## Tasks  ⚡️

Now give the AI a task to do.
Expand Down Expand Up @@ -137,6 +151,7 @@ You can see the plan's current context with the `ls` command. You can remove con
plandex ls # list all context in current plan
plandex rm component.ts # remove by name
plandex rm 2 # remove by number in the `plandex ls` list
plandex rm 2-5 # remove a range of indices
plandex rm lib/**/*.js # remove by glob pattern
plandex rm lib # remove whole directory
plandex clear # remove all context
Expand Down Expand Up @@ -184,6 +199,20 @@ You can see the full conversation history with the `convo` command.
plandex convo # show the full conversation history
```

You can output the conversation in plain text with no ANSI codes with the `--plain` or `-p` flag.

```bash
plandex convo --plain
```

You can also show a specific message number or range of messages.

```bash
plandex convo 1 # show the initial prompt
plandex convo 1-5 # show messages 1 through 5
plandex convo 2- # show messages 2 through the end of the conversation
```

## Conversation summaries  🤏

Every time the AI model replies, Plandex will summarize the conversation so far in the background and store the summary in case it's needed later. When the conversation size in tokens exceeds the model's limit, Plandex will automatically replace some number of older messages with the corresponding summary. It will summarize as many messages as necessary to keep the conversation size under the limit.
Expand All @@ -194,6 +223,12 @@ You can see the latest summary with the `summary` command.
plandex summary # show the latest conversation summary
```

As with the `convo` command, you can output the summary in plain text with no ANSI codes with the `--plain` or `-p` flag.

```bash
plandex summary --plain
```

## Model settings  🧠

You can see the current AI models and model settings with the `models` command and change them with the `set-model` command.
Expand Down
10 changes: 0 additions & 10 deletions releases/cli/versions/1.0.2.md

This file was deleted.

59 changes: 59 additions & 0 deletions releases/cli/versions/1.1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## Support for loading images into context with gpt-4o 🖼️

- You can now load images into context with `plandex load path/to/image.png`. Supported image formats are png, jpeg, non-animated gif, and webp. So far, this feature is only available with the default OpenAI GPT-4o model.

![plandex-load-images](https://github.com/plandex-ai/plandex/blob/main/releases/images/cli/1.1.0/plandex-images.gif)

## No more hard OpenAI requirement for builder, verifier, and auto-fix roles 🧠

- Non-OpenAI models can now be used for *all* roles, including the builder, verifier, and auto-fix roles, since streaming function calls are no longer required for these roles.

- Note that reliable function calling is still required for these roles. In testing, it was difficult to find models that worked reliably enough for these roles, despite claimed support for function calling. For this reason, using non-OpenAI models for these roles should be considered experimental. Still, this provides a path forward for using open source, local, and other non-OpenAI models for these roles in the future as they improve.

## Reject pending changes with `plandex reject` 🚫

- You can now reject pending changes to one or more files with the `plandex reject` command. Running it with no arguments will reject all pending changes after confirmation. You can also reject changes to specific files by passing one or more file paths as arguments.

![plandex-reject](https://github.com/plandex-ai/plandex/blob/main/releases/images/cli/1.1.0/plandex-reject.gif)

## Summarization and auto-continue fixes 🛤 ️

- Fixes for summarization and auto-continue issues that could Plandex to lose track of where it is in the plan and repeat tasks or do tasks out of order, especially when using `tell` and `continue` after the initial `tell`.

## Verification and auto-fix improvements 🛠️

- Improvements to the verification and auto-fix step. Plandex is now more likely to catch and fix placeholder references like "// ... existing code ..." as well as incorrect removal or overwriting of code.

## Stale context fixes 🔄

- After a context file is updated, Plandex is less likely to use an old version of the code from earlier in the conversation--it now uses the latest version much more reliably.

## `plandex convo` command improvements 🗣️

- Added a `--plain / -p` flag to `plandex convo` and `plandex summary` that outputs the conversation/summary in plain text with no ANSI codes.
- `plandex convo` now accepts a message number or range of messages to display (e.g. `plandex convo 1`, `plandex convo 1-5`, `plandex convo 2-`). Use `plandex convo 1` to show the initial prompt.

## Context management improvements 📄

- Give notes added to context with `plandex load -n 'some note'` an auto-generated name in the `context ls` list.
- `plandex rm` can now accept a range of indices to remove (e.g. `plandex rm 1-5`)
- Better help text if `plandex load` is run with incorrect arguments
- Fix for `plandex load` issue loading paths that begin with `./`

## Better rate limit tolerance 🕰️

- Increase wait times when receiving rate limit errors from OpenAI API (common with new OpenAI accounts that haven't spent $50)

## Built-in model updates 🧠

- Removed 'gpt-4-turbo-preview' from list of built-in models and model packs

## Other fixes 🐞

- Fixes for some occasional rendering issues when streaming plans and build counts
- Fix for `plandex set-model` model selection showing built-in model options that aren't compatible with the selected role--now only compatible models are shown

## Help updates 📚

- `plandex help` now shows a brief overview on getting started with Plandex rather than the full command list
- `plandex help --all` or `plandex help -a` shows the full command list
Binary file added releases/images/cli/1.1.0/plandex-images.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added releases/images/cli/1.1.0/plandex-reject.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.

0 comments on commit 7c00ec3

Please sign in to comment.