|
1 | 1 | package commands |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
4 | 5 | "fmt" |
5 | 6 | "os" |
6 | 7 | "os/exec" |
@@ -69,6 +70,13 @@ func registerDisplayCommands(r *Registry) { |
69 | 70 | "/explain", "explain code in path", cmdExplain, |
70 | 71 | "/view", "view file with line numbers", cmdView, |
71 | 72 | ) |
| 73 | + r.Register(Command{ |
| 74 | + Name: "/chain", |
| 75 | + Aliases: []string{}, |
| 76 | + Description: "run prompts sequentially, separated by ;; (e.g. /chain fix tests ;; commit the changes)", |
| 77 | + Category: "mode", |
| 78 | + Handler: cmdChain, |
| 79 | + }) |
72 | 80 | registerDisplayNavCommands(r) |
73 | 81 | } |
74 | 82 |
|
@@ -283,7 +291,7 @@ func cmdSummarize(ctx Context) Result { |
283 | 291 | "what was implemented, and any decisions made. Be brief.\n\n"+ |
284 | 292 | "(Conversation has %d messages)", len(msgs)) |
285 | 293 | if ctx.REPL.StreamAndPrint != nil { |
286 | | - ctx.REPL.StreamAndPrint(nil, ctx.Agent, prompt, ctx.RepoPath) |
| 294 | + ctx.REPL.StreamAndPrint(context.Background(), ctx.Agent, prompt, ctx.RepoPath) |
287 | 295 | } else { |
288 | 296 | PrintError("agent stream not available") |
289 | 297 | } |
@@ -542,3 +550,40 @@ func cmdRender(ctx Context) Result { |
542 | 550 | } |
543 | 551 | return Result{Handled: true} |
544 | 552 | } |
| 553 | + |
| 554 | +// cmdChain runs multiple prompts sequentially, separated by ";;". |
| 555 | +// Example: /chain write tests for auth.go ;; run the tests ;; fix any failures |
| 556 | +func cmdChain(ctx Context) Result { |
| 557 | + if ctx.REPL.StreamAndPrint == nil || ctx.Agent == nil { |
| 558 | + PrintError("agent not available") |
| 559 | + return Result{Handled: true} |
| 560 | + } |
| 561 | + |
| 562 | + raw := ctx.Args() |
| 563 | + if raw == "" { |
| 564 | + fmt.Printf("%sUsage: /chain prompt1 ;; prompt2 ;; prompt3%s\n", ColorDim, ColorReset) |
| 565 | + fmt.Printf("%sEach step runs after the previous one completes.%s\n\n", ColorDim, ColorReset) |
| 566 | + return Result{Handled: true} |
| 567 | + } |
| 568 | + |
| 569 | + steps := strings.Split(raw, ";;") |
| 570 | + var prompts []string |
| 571 | + for _, s := range steps { |
| 572 | + s = strings.TrimSpace(s) |
| 573 | + if s != "" { |
| 574 | + prompts = append(prompts, s) |
| 575 | + } |
| 576 | + } |
| 577 | + if len(prompts) == 0 { |
| 578 | + PrintError("no prompts found — separate them with ;;") |
| 579 | + return Result{Handled: true} |
| 580 | + } |
| 581 | + |
| 582 | + fmt.Printf("%s── Chain: %d steps ──────────────────────%s\n\n", ColorDim, len(prompts), ColorReset) |
| 583 | + for i, prompt := range prompts { |
| 584 | + fmt.Printf("%s[%d/%d]%s %s%s%s\n\n", ColorDim, i+1, len(prompts), ColorReset, ColorYellow, prompt, ColorReset) |
| 585 | + ctx.REPL.StreamAndPrint(context.Background(), ctx.Agent, prompt, ctx.RepoPath) |
| 586 | + } |
| 587 | + fmt.Printf("%s── Chain complete ───────────────────────%s\n\n", ColorLime, ColorReset) |
| 588 | + return Result{Handled: true} |
| 589 | +} |
0 commit comments