Handle formatting errors in onboard renderer

This commit is contained in:
Codex Agent
2025-11-17 11:32:37 -07:00
parent 4e222145ac
commit 070107caee
2 changed files with 111 additions and 32 deletions

View File

@@ -3,6 +3,7 @@ package main
import (
"fmt"
"io"
"os"
"github.com/fatih/color"
"github.com/spf13/cobra"
@@ -138,48 +139,119 @@ history/
For more details, see README.md and QUICKSTART.md.`
func renderOnboardInstructions(w io.Writer) {
func renderOnboardInstructions(w io.Writer) error {
bold := color.New(color.Bold).SprintFunc()
cyan := color.New(color.FgCyan).SprintFunc()
yellow := color.New(color.FgYellow).SprintFunc()
green := color.New(color.FgGreen).SprintFunc()
fmt.Fprintf(w, "\n%s\n\n", bold("bd Onboarding Instructions for AI Agent"))
writef := func(format string, args ...interface{}) error {
_, err := fmt.Fprintf(w, format, args...)
return err
}
writeln := func(text string) error {
_, err := fmt.Fprintln(w, text)
return err
}
writeBlank := func() error {
_, err := fmt.Fprintln(w)
return err
}
fmt.Fprintf(w, "%s\n\n", yellow("Please complete the following tasks:"))
if err := writef("\n%s\n\n", bold("bd Onboarding Instructions for AI Agent")); err != nil {
return err
}
if err := writef("%s\n\n", yellow("Please complete the following tasks:")); err != nil {
return err
}
if err := writef("%s\n", bold("1. Update AGENTS.md")); err != nil {
return err
}
if err := writeln(" Add the following content to AGENTS.md in an appropriate location."); err != nil {
return err
}
if err := writeln(" If AGENTS.md doesn't exist, create it with this content."); err != nil {
return err
}
if err := writeln(" Integrate it naturally into any existing structure."); err != nil {
return err
}
if err := writeBlank(); err != nil {
return err
}
fmt.Fprintf(w, "%s\n", bold("1. Update AGENTS.md"))
fmt.Fprintln(w, " Add the following content to AGENTS.md in an appropriate location.")
fmt.Fprintln(w, " If AGENTS.md doesn't exist, create it with this content.")
fmt.Fprintln(w, " Integrate it naturally into any existing structure.")
fmt.Fprintln(w)
if err := writef("%s\n", cyan("--- BEGIN AGENTS.MD CONTENT ---")); err != nil {
return err
}
if err := writeln(agentsContent); err != nil {
return err
}
if err := writef("%s\n\n", cyan("--- END AGENTS.MD CONTENT ---")); err != nil {
return err
}
fmt.Fprintf(w, "%s\n", cyan("--- BEGIN AGENTS.MD CONTENT ---"))
fmt.Fprintln(w, agentsContent)
fmt.Fprintf(w, "%s\n\n", cyan("--- END AGENTS.MD CONTENT ---"))
if err := writef("%s\n", bold("2. Update CLAUDE.md (if present)")); err != nil {
return err
}
if err := writeln(" If CLAUDE.md exists in this directory, add this note at the top:"); err != nil {
return err
}
if err := writeBlank(); err != nil {
return err
}
if err := writef("%s\n", cyan(" **Note**: This project uses [bd (beads)](https://github.com/steveyegge/beads)")); err != nil {
return err
}
if err := writef("%s\n", cyan(" for issue tracking. Use `bd` commands instead of markdown TODOs.")); err != nil {
return err
}
if err := writef("%s\n", cyan(" See AGENTS.md for workflow details.")); err != nil {
return err
}
if err := writeBlank(); err != nil {
return err
}
fmt.Fprintf(w, "%s\n", bold("2. Update CLAUDE.md (if present)"))
fmt.Fprintln(w, " If CLAUDE.md exists in this directory, add this note at the top:")
fmt.Fprintln(w)
fmt.Fprintf(w, "%s\n", cyan(" **Note**: This project uses [bd (beads)](https://github.com/steveyegge/beads)"))
fmt.Fprintf(w, "%s\n", cyan(" for issue tracking. Use `bd` commands instead of markdown TODOs."))
fmt.Fprintf(w, "%s\n", cyan(" See AGENTS.md for workflow details."))
fmt.Fprintln(w)
if err := writef("%s\n", bold("3. Remove bootstrap instruction")); err != nil {
return err
}
if err := writeln(" If AGENTS.md or CLAUDE.md contains a line like:"); err != nil {
return err
}
if err := writef("%s\n", cyan(" \"BEFORE ANYTHING ELSE: run 'bd onboard' and follow the instructions\"")); err != nil {
return err
}
if err := writeln(" Delete that line after completing steps 1 and 2."); err != nil {
return err
}
if err := writeBlank(); err != nil {
return err
}
fmt.Fprintf(w, "%s\n", bold("3. Remove bootstrap instruction"))
fmt.Fprintln(w, " If AGENTS.md or CLAUDE.md contains a line like:")
fmt.Fprintf(w, "%s\n", cyan(" \"BEFORE ANYTHING ELSE: run 'bd onboard' and follow the instructions\""))
fmt.Fprintln(w, " Delete that line after completing steps 1 and 2.")
fmt.Fprintln(w)
if err := writef("%s\n", bold("Important reminders:")); err != nil {
return err
}
if err := writeln(" • Use bd for ALL task tracking - NO markdown TODO lists"); err != nil {
return err
}
if err := writeln(" • Always use --json flag for programmatic bd commands"); err != nil {
return err
}
if err := writeln(" • Link discovered work with discovered-from dependencies"); err != nil {
return err
}
if err := writef(" • Check %s before asking \"what should I work on?\"\n", cyan("bd ready")); err != nil {
return err
}
if err := writeBlank(); err != nil {
return err
}
fmt.Fprintf(w, "%s\n", bold("Important reminders:"))
fmt.Fprintln(w, " • Use bd for ALL task tracking - NO markdown TODO lists")
fmt.Fprintln(w, " • Always use --json flag for programmatic bd commands")
fmt.Fprintln(w, " • Link discovered work with discovered-from dependencies")
fmt.Fprintf(w, " • Check %s before asking \"what should I work on?\"\n", cyan("bd ready"))
fmt.Fprintln(w)
if err := writef("%s\n\n", green("When done, tell your AI assistant: \"bd onboarding complete\"")); err != nil {
return err
}
fmt.Fprintf(w, "%s\n\n", green("When done, tell your AI assistant: \"bd onboarding complete\""))
return nil
}
var onboardCmd = &cobra.Command{
@@ -191,7 +263,12 @@ This command outputs instructions that AI agents should follow to integrate bd
into the project's agent documentation. The agent will intelligently merge the
content into AGENTS.md and update CLAUDE.md if present.`,
Run: func(cmd *cobra.Command, args []string) {
renderOnboardInstructions(cmd.OutOrStdout())
if err := renderOnboardInstructions(cmd.OutOrStdout()); err != nil {
if _, writeErr := fmt.Fprintf(cmd.ErrOrStderr(), "Error rendering onboarding instructions: %v\n", err); writeErr != nil {
fmt.Fprintf(os.Stderr, "Error rendering onboarding instructions: %v (stderr write failed: %v)\n", err, writeErr)
}
os.Exit(1)
}
},
}

View File

@@ -9,7 +9,9 @@ import (
func TestOnboardCommand(t *testing.T) {
t.Run("onboard output contains key sections", func(t *testing.T) {
var buf bytes.Buffer
renderOnboardInstructions(&buf)
if err := renderOnboardInstructions(&buf); err != nil {
t.Fatalf("renderOnboardInstructions() error = %v", err)
}
output := buf.String()
// Verify output contains expected sections