[object Object]

← back to Cli Printing Press

feat(templates): add --human-friendly flag and NDJSON pagination events

c266b6fb9de9f8c22e6f076a0edf41635d9add03 · 2026-03-25 11:00:36 -0700 · Matt Van Horn

Inspired by ElevenLabs CLI v0.5.0 agent-first update:
- Default output is now color-free (agent-safe). Colors only activate
  with --human-friendly flag. Prevents ANSI codes in PTY-based agents.
- Paginated commands emit NDJSON events to stderr for agent progress
  tracking: {"event":"page_fetch","page":1}
- --no-color preserved as backwards-compatible override
- README and scorecard updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files touched

Diff

commit c266b6fb9de9f8c22e6f076a0edf41635d9add03
Author: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Date:   Wed Mar 25 11:00:36 2026 -0700

    feat(templates): add --human-friendly flag and NDJSON pagination events
    
    Inspired by ElevenLabs CLI v0.5.0 agent-first update:
    - Default output is now color-free (agent-safe). Colors only activate
      with --human-friendly flag. Prevents ANSI codes in PTY-based agents.
    - Paginated commands emit NDJSON events to stderr for agent progress
      tracking: {"event":"page_fetch","page":1}
    - --no-color preserved as backwards-compatible override
    - README and scorecard updated
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
 internal/generator/templates/helpers.go.tmpl | 18 ++++++++++++++++--
 internal/generator/templates/readme.md.tmpl  |  2 ++
 internal/generator/templates/root.go.tmpl    |  1 +
 internal/pipeline/scorecard.go               |  4 ++++
 4 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/internal/generator/templates/helpers.go.tmpl b/internal/generator/templates/helpers.go.tmpl
index 60932312..5d8c97e0 100644
--- a/internal/generator/templates/helpers.go.tmpl
+++ b/internal/generator/templates/helpers.go.tmpl
@@ -20,10 +20,16 @@ var As = errors.As
 // noColor is set by the --no-color flag
 var noColor bool
 
+// humanFriendly is set by the --human-friendly flag; colors are off by default (agent-safe)
+var humanFriendly bool
+
 func colorEnabled() bool {
 	if noColor {
 		return false
 	}
+	if !humanFriendly {
+		return false
+	}
 	if os.Getenv("NO_COLOR") != "" {
 		return false
 	}
@@ -153,7 +159,11 @@ func paginatedGet(c interface {
 	page := 0
 	for {
 		page++
-		fmt.Fprintf(os.Stderr, "fetching page %d...\n", page)
+		if humanFriendly {
+			fmt.Fprintf(os.Stderr, "fetching page %d...\n", page)
+		} else {
+			fmt.Fprintf(os.Stderr, `{"event":"page_fetch","page":%d}`+"\n", page)
+		}
 
 		data, err := c.Get(path, clean)
 		if err != nil {
@@ -208,7 +218,11 @@ func paginatedGet(c interface {
 		break
 	}
 
-	fmt.Fprintf(os.Stderr, "fetched %d items across %d pages\n", len(allItems), page)
+	if humanFriendly {
+		fmt.Fprintf(os.Stderr, "fetched %d items across %d pages\n", len(allItems), page)
+	} else {
+		fmt.Fprintf(os.Stderr, `{"event":"complete","total":%d,"pages":%d}`+"\n", len(allItems), page)
+	}
 	result, _ := json.Marshal(allItems)
 	return json.RawMessage(result), nil
 }
diff --git a/internal/generator/templates/readme.md.tmpl b/internal/generator/templates/readme.md.tmpl
index 04c92f0e..f7b0af2d 100644
--- a/internal/generator/templates/readme.md.tmpl
+++ b/internal/generator/templates/readme.md.tmpl
@@ -83,6 +83,8 @@ This CLI is designed for AI agent consumption:
 - **Confirmable** - `--yes` for explicit confirmation of destructive actions
 - **Piped input** - `echo '{"key":"value"}' | {{.Name}}-cli <resource> create --stdin`
 - **Cacheable** - GET responses cached for 5 minutes, bypass with `--no-cache`
+- **Agent-safe by default** - no colors or formatting unless `--human-friendly` is set
+- **Progress events** - paginated commands emit NDJSON events to stderr in default mode
 
 Exit codes: `0` success, `2` usage error, `3` not found, `4` auth error, `5` API error, `7` rate limited, `10` config error.
 
diff --git a/internal/generator/templates/root.go.tmpl b/internal/generator/templates/root.go.tmpl
index 8fe86301..bd83f85f 100644
--- a/internal/generator/templates/root.go.tmpl
+++ b/internal/generator/templates/root.go.tmpl
@@ -49,6 +49,7 @@ func Execute() error {
 	rootCmd.PersistentFlags().StringVar(&flags.selectFields, "select", "", "Comma-separated fields to include in output (e.g. --select id,name,status)")
 	rootCmd.PersistentFlags().BoolVar(&flags.yes, "yes", false, "Skip confirmation prompts (for agents and scripts)")
 	rootCmd.PersistentFlags().BoolVar(&noColor, "no-color", false, "Disable colored output")
+	rootCmd.PersistentFlags().BoolVar(&humanFriendly, "human-friendly", false, "Enable colored output and rich formatting")
 
 {{- range $name, $resource := .Resources}}
 	rootCmd.AddCommand(new{{camel $name}}Cmd(&flags)) {{/* FuncPrefix matches resource name for top-level */}}
diff --git a/internal/pipeline/scorecard.go b/internal/pipeline/scorecard.go
index 4cf6cfd8..20b58ec7 100644
--- a/internal/pipeline/scorecard.go
+++ b/internal/pipeline/scorecard.go
@@ -232,6 +232,10 @@ func scoreAgentNative(dir string) int {
 	if strings.Contains(helpersContent, "409") || strings.Contains(helpersContent, "already exists") {
 		score += 1
 	}
+	// Check for --human-friendly flag (agent-safe-by-default coloring)
+	if strings.Contains(combined, "human-friendly") || strings.Contains(combined, "humanFriendly") {
+		score += 1
+	}
 	if score > 10 {
 		score = 10
 	}

← b8c762c6 docs: rewrite README to reflect what the press actually does  ·  back to Cli Printing Press  ·  feat(scorecard): add breadth dimension + fix LLM runner + in 95e26838 →