From 107130d2c2aa99d627c44bdb55d577b9f3bcc183 Mon Sep 17 00:00:00 2001 From: Gurney Buchanan Date: Wed, 21 Oct 2026 11:19:18 -0400 Subject: [PATCH] Make cobra help output respect the terminal width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Help was the last unwrapped surface: cobra's default template emits flag usages via FlagUsages, which never wraps, so long descriptions hard-wrapped at the terminal's right edge with continuations at column zero while the flags themselves sat indented mid-line. Long descriptions rendered verbatim, and cobra's built-in completion summaries overflowed narrow terminals. The usage template is now patched in place (not copied, so it tracks cobra's default) to use pflag's FlagUsagesWrapped at the measured width, which aligns continuations under each description. Long descriptions re-wrap at runtime, the trailing use-hint breaks below 78 columns, the completion commands are hidden from the list (still invocable), command summaries were shortened to fit the list column, and the init --forge default URL moved out of the flag line β€” an unbreakable token that cannot fit pflag's description column at narrow widths. Verified by capturing every help screen in a PTY at 60 and 80 columns and measuring display widths: zero over-width lines, continuations aligned. πŸ’˜ Generated with Crush Assisted-by: Crush:rits/zai-org/glm-5-3 --- CHANGELOG.md | 7 +++++++ cmd/env.go | 2 +- cmd/init.go | 12 ++++++++++-- cmd/ledger.go | 2 +- cmd/root.go | 43 +++++++++++++++++++++++++++++++++++++++++++ cmd/run.go | 2 +- 6 files changed, 63 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59713cb..b9eac61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,3 +69,10 @@ Initial implementation. - Interactive screens now gate on a real terminal check (ioctl) instead of "is a character device": `traust-cli skills < /dev/null` used to open the picker and hang forever, because /dev/null is a character device. +- Cobra help output respects the terminal width: flag usages wrap with + continuations aligned under each description (FlagUsagesWrapped at the + measured width), Long descriptions re-wrap, the trailing use-hint breaks + on narrow terminals, cobra's built-in completion commands are hidden from + the command list (still invocable), over-long command summaries were + shortened, and the init --forge default URL moved out of the flag line + (an unbreakable token that could not fit pflag's description column). diff --git a/cmd/env.go b/cmd/env.go index de564a2..19d9ad2 100644 --- a/cmd/env.go +++ b/cmd/env.go @@ -12,7 +12,7 @@ var envJSON bool var envCmd = &cobra.Command{ Use: "env", - Short: "Print the environment the CLI injects into child processes", + Short: "Print the injected child environment", Long: `The CLI does not write to your shell profile. It injects the harness venv PATH, TRAUST_CONFIG_HOME and HARNESS_BIN_DIR into every process it spawns. This command prints that environment β€” source it if you want the diff --git a/cmd/init.go b/cmd/init.go index 823cf38..2057ae1 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -46,7 +46,7 @@ TRAUST_CONFIG_HOME and the venv PATH into the processes it spawns. Pass func init() { rootCmd.AddCommand(initCmd) initCmd.Flags().StringVar(&initOpts.workspace, "workspace", "", "managed workspace root (default ~/.traust)") - initCmd.Flags().StringVar(&initOpts.forge, "forge", bootstrap.DefaultForge, "git URL to clone traust from") + initCmd.Flags().StringVar(&initOpts.forge, "forge", "", "git URL to clone traust from (default: the public traust repository)") initCmd.Flags().StringVar(&initOpts.ref, "ref", "latest", "tag or branch to pin (or \"latest\" for the newest stable tag)") initCmd.Flags().StringVar(&initOpts.configHome, "config-home", "", "TRAUST_CONFIG_HOME (default /config)") initCmd.Flags().StringVar(&initOpts.toolchain, "toolchain", "none", "scanner toolchain profile (none, secure-code-audit, vuln-scan, triage, …)") @@ -56,6 +56,14 @@ func init() { initCmd.Flags().BoolVarP(&initOpts.yes, "yes", "y", false, "non-interactive: accept all defaults") } +// defaultForge is the wizard's placeholder for the forge URL. +func defaultForge() string { + if initOpts.forge != "" { + return initOpts.forge + } + return bootstrap.DefaultForge +} + func runInit(cmd *cobra.Command, args []string) { ctx := context.Background() styles := theme.Default() @@ -79,7 +87,7 @@ func runInit(cmd *cobra.Command, args []string) { if defaultHarness == "" { defaultHarness = "claude" } - answers, err := tui.RunInitWizard(workspace, initOpts.forge, detected, defaultHarness) + answers, err := tui.RunInitWizard(workspace, defaultForge(), detected, defaultHarness) if err != nil { fatalf(1, "init wizard: %v", err) } diff --git a/cmd/ledger.go b/cmd/ledger.go index a3366b1..044903b 100644 --- a/cmd/ledger.go +++ b/cmd/ledger.go @@ -40,7 +40,7 @@ var ledgerWhoamiCmd = &cobra.Command{ var ledgerFindingsCmd = &cobra.Command{ Use: "findings [layer-id]", - Short: "List resolved finding dispositions (one layer or all)", + Short: "List resolved finding dispositions", Run: func(cmd *cobra.Command, args []string) { v := newLedgerViews() layer := "" diff --git a/cmd/root.go b/cmd/root.go index b43a513..bf57e47 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -37,6 +37,7 @@ journals.`, // Execute runs the root command. func Execute() { + installWrappedUsageTemplate() if err := rootCmd.Execute(); err != nil { styles := theme.Default() fmt.Fprintln(os.Stderr, styles.Err.Render("error: "+err.Error())) @@ -44,6 +45,48 @@ func Execute() { } } +// installWrappedUsageTemplate makes cobra's help respect the terminal width. +// The default template emits flag usages unwrapped, so long descriptions +// hard-wrap at the terminal's right edge with continuations at column zero +// while the flags themselves are indented. pflag already knows how to wrap +// (FlagUsagesWrapped aligns continuations under each description); the +// template is patched in place rather than copied, so it tracks cobra's +// default. Long descriptions and the trailing use-hint are wrapped the same +// way, and cobra's built-in completion commands are hidden (their summaries +// are too long for narrow terminals and they remain invocable). Templates +// inherit from the root, so every subcommand is covered. +func installWrappedUsageTemplate() { + width := tui.TerminalWidth() + if width < 60 { + width = 60 + } + tmpl := rootCmd.UsageTemplate() + patched := strings.ReplaceAll(tmpl, + ".FlagUsages | trimTrailingWhitespaces", + fmt.Sprintf(".FlagUsagesWrapped %d | trimTrailingWhitespaces", width)) + if width < 78 { + patched = strings.ReplaceAll(patched, + "for more information about a command.", + "for more\ninformation about a command.") + } + if patched != tmpl { + rootCmd.SetUsageTemplate(patched) + } + rootCmd.CompletionOptions.HiddenDefaultCmd = true + wrapCommandLongs(rootCmd, width) +} + +// wrapCommandLongs re-wraps every command's Long description to the current +// width; cobra renders them verbatim. +func wrapCommandLongs(cmd *cobra.Command, width int) { + if cmd.Long != "" { + cmd.Long = tui.Wrap(cmd.Long, width) + } + for _, sub := range cmd.Commands() { + wrapCommandLongs(sub, width) + } +} + func init() { rootCmd.SetVersionTemplate(theme.Default().App.Render(" traust-cli ") + " {{.Version}}\n") } diff --git a/cmd/run.go b/cmd/run.go index e2b66cc..6e96ae3 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -32,7 +32,7 @@ var runFlags struct { var runCmd = &cobra.Command{ Use: "run [args…]", - Short: "Execute a skill headlessly through your agent harness", + Short: "Run a skill headlessly through your harness", Long: `Composes the skill's SKILL.md into a prompt, resolves the model-floor default from the registry, and drives the harness of your choice in headless mode. The agent always runs from the harness root β€” never inside the audit