<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>leodido.dev - Viper</title>
    <subtitle>Leo&#x27;s take on security, eBPF, Linux, kernel, and whatever tech he meets</subtitle>
    <link rel="self" type="application/atom+xml" href="https://leodido.dev/tags/viper/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://leodido.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-02-12T00:00:00+00:00</updated>
    <id>https://leodido.dev/tags/viper/atom.xml</id>
    <entry xml:lang="en">
        <title>structcli</title>
        <published>2024-02-12T00:00:00+00:00</published>
        <updated>2024-02-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://leodido.dev/projects/structcli/"/>
        <id>https://leodido.dev/projects/structcli/</id>
        
        <content type="html" xml:base="https://leodido.dev/projects/structcli/">&lt;p&gt;Declare your CLI contract once in Go structs. &lt;code&gt;structcli&lt;&#x2F;code&gt; turns it into flags, env vars, config-file loading, validation, organized help, and machine-readable contracts for agents.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Less Cobra&#x2F;Viper boilerplate&lt;&#x2F;li&gt;
&lt;li&gt;Better CLIs for humans&lt;&#x2F;li&gt;
&lt;li&gt;Better contracts for automation and LLMs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Stop writing plumbing. Start shipping commands.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zap-quick-start&quot;&gt;⚡ Quick Start&lt;a class=&quot;zola-anchor&quot; href=&quot;#zap-quick-start&quot; aria-label=&quot;Anchor link for: zap-quick-start&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;app.ona.com&#x2F;#https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ona.com&#x2F;build-with-ona.svg&quot; alt=&quot;Build with Ona&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Start with a plain Go struct:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;package&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&amp;quot;fmt&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&amp;quot;log&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&amp;quot;github.com&#x2F;leodido&#x2F;structcli&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&amp;quot;github.com&#x2F;spf13&#x2F;cobra&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&amp;quot;go.uber.org&#x2F;zap&#x2F;zapcore&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Options&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	LogLevel&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; zapcore&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Level&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Port&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt;     int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	opts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; := &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Options&lt;&#x2F;span&gt;&lt;span&gt;{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; := &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;Use&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;myapp&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Define&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;cli&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; opts&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;		log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Fatalln&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;err&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	cli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PreRunE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Unmarshal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; opts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	cli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;RunE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;		fmt&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;opts&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; cli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Execute&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;		log&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Fatalln&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;err&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That single &lt;code&gt;Define&lt;&#x2F;code&gt; call creates the CLI surface from your struct, and &lt;code&gt;Unmarshal&lt;&#x2F;code&gt; hydrates it back from flags, env vars, config, and defaults.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go run examples&#x2F;minimal&#x2F;main.go&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Usage:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   myapp [flags]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --loglevel zapcore.Level    {debug,info,warn,error,dpanic,panic,fatal} (default info)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --port int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add tags when you want aliases, env vars, shorthand, defaults, and descriptions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Options&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	LogLevel&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; zapcore&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Level&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;level&amp;quot; flagdescr:&amp;quot;Set logging level&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Port&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt;     int&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;           `flagshort:&amp;quot;p&amp;quot; flagdescr:&amp;quot;Server port&amp;quot; flagenv:&amp;quot;true&amp;quot; default:&amp;quot;3000&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go run examples&#x2F;simple&#x2F;main.go&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; -h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Usage:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   myapp [flags]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --level zapcore.Level   Set logging level {debug,info,warn,error,dpanic,panic,fatal} (default info)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   -p, --port int              Server port (default 3000)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; MYAPP_LOGLEVEL=debug go run examples&#x2F;simple&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# &amp;amp;{debug 3000}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; MYAPP_LOGLEVEL=error MYAPP_PORT=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;9000&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go run examples&#x2F;simple&#x2F;main.go&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --level&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; dpanic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# &amp;amp;{dpanic 9000}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Built-in types like &lt;code&gt;zapcore.Level&lt;&#x2F;code&gt; are validated automatically too.&lt;&#x2F;p&gt;
&lt;p&gt;Out of the box, your CLI supports:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;📝 Command-line flags (&lt;code&gt;--level info&lt;&#x2F;code&gt;, &lt;code&gt;-p 8080&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;🌍 Environment variables (&lt;code&gt;MYAPP_PORT=8080&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;💦 Options precedence (flags &amp;gt; env vars &amp;gt; config file &amp;gt; defaults)&lt;&#x2F;li&gt;
&lt;li&gt;✅ Automatic validation and type conversion&lt;&#x2F;li&gt;
&lt;li&gt;📚 Beautiful help output with proper grouping&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Add the AI-native wiring below and it also gains machine-readable JSON Schema, structured JSON errors, semantic exit codes, and optional MCP tool-server mode for agents.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build-ai-native-clis&quot;&gt;Build AI-Native CLIs&lt;a class=&quot;zola-anchor&quot; href=&quot;#build-ai-native-clis&quot; aria-label=&quot;Anchor link for: build-ai-native-clis&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;structcli&lt;&#x2F;code&gt; does not just generate flags for humans. It can make your CLI legible to agents too.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of scraping &lt;code&gt;--help&lt;&#x2F;code&gt; and guessing, an agent can discover the contract, call the command correctly, and recover from structured failures.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SetupJSONSchema&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; jsonschema&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Options&lt;&#x2F;span&gt;&lt;span&gt;{})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SetupFlagErrors&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; Optional, but recommended for typed flag-parse errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SetupMCP&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; mcp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Options&lt;&#x2F;span&gt;&lt;span&gt;{})&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; Optional, exposes the CLI as an MCP server over stdio&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ExecuteOrExit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With that wiring:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--jsonschema&lt;&#x2F;code&gt; exposes flags, defaults, required inputs, enums, and env bindings across the command tree&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;HandleError&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;ExecuteOrExit&lt;&#x2F;code&gt; emit structured JSON errors instead of forcing callers to parse human-oriented output&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--mcp&lt;&#x2F;code&gt; exposes the same command tree as MCP tools over stdio, with typed inputs and structured tool-call failures&lt;&#x2F;li&gt;
&lt;li&gt;semantic exit codes tell the caller whether it should fix input, fix config, retry, or escalate to a human&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The same contract spans flags, env vars, config, validation, and enum constraints.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; mycli srv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --jsonschema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-support z-function&quot;&gt;  &amp;quot;properties&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-support z-function&quot;&gt;    &amp;quot;port&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-support z-function&quot;&gt;      &amp;quot;type&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;integer&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-support z-function&quot;&gt;      &amp;quot;default&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 3000,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-support z-function&quot;&gt;      &amp;quot;x-structcli-env-vars&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;MYCLI_SRV_PORT&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;No &lt;code&gt;--help&lt;&#x2F;code&gt; parsing. No guessing what failed. Just a CLI that can explain itself and fail in machine-actionable ways.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;code&gt;exitcode.Category(code)&lt;&#x2F;code&gt; and &lt;code&gt;exitcode.IsRetryable(code)&lt;&#x2F;code&gt; to decide what to do next. See &lt;code&gt;jsonschema.WithFullTree()&lt;&#x2F;code&gt; and &lt;code&gt;jsonschema.WithEnumInDescription()&lt;&#x2F;code&gt; for schema customization, and pass the same schema options through &lt;code&gt;SetupJSONSchema&lt;&#x2F;code&gt; with &lt;code&gt;jsonschema.Options{SchemaOpts: ...}&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For CLIs that capture output streams during command construction, configure &lt;code&gt;mcp.Options.CommandFactory&lt;&#x2F;code&gt; so each MCP tool call builds a fresh command with the tool-call stdout and stderr writers. This keeps MCP protocol output separate from command output while preserving the existing command tree schema. If the command constructor requires stdin, the factory can wire a non-interactive reader such as &lt;code&gt;strings.NewReader(&quot;&quot;)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For build-time discovery, &lt;code&gt;generate.WriteAll&lt;&#x2F;code&gt; produces SKILL.md, llms.txt, and AGENTS.md from the same struct definitions — wire it into &lt;code&gt;&#x2F;&#x2F;go:generate&lt;&#x2F;code&gt; and the files stay in sync automatically.&lt;&#x2F;p&gt;
&lt;p&gt;Read the full &lt;a href=&quot;https:&#x2F;&#x2F;leodido.dev&#x2F;projects&#x2F;structcli&#x2F;docs&#x2F;ai-native.md&quot;&gt;AI-native guide&lt;&#x2F;a&gt; or walk through the runnable &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;structerr&#x2F;README.md&quot;&gt;structured error example&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;v-install&quot;&gt;⬇️ Install&lt;a class=&quot;zola-anchor&quot; href=&quot;#v-install&quot; aria-label=&quot;Anchor link for: v-install&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;go&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; get github.com&#x2F;leodido&#x2F;structcli&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;package-key-features&quot;&gt;📦 Key Features&lt;a class=&quot;zola-anchor&quot; href=&quot;#package-key-features&quot; aria-label=&quot;Anchor link for: package-key-features&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;jigsaw-declarative-flags-definition&quot;&gt;🧩 Declarative Flags Definition&lt;a class=&quot;zola-anchor&quot; href=&quot;#jigsaw-declarative-flags-definition&quot; aria-label=&quot;Anchor link for: jigsaw-declarative-flags-definition&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Define flags once using Go struct tags.&lt;&#x2F;p&gt;
&lt;p&gt;No more boilerplate for &lt;code&gt;Flags().StringVarP&lt;&#x2F;code&gt;, &lt;code&gt;Flags().IntVar&lt;&#x2F;code&gt;, &lt;code&gt;viper.BindPFlag&lt;&#x2F;code&gt;, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, you can &lt;em&gt;nest&lt;&#x2F;em&gt; structs too.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; ServerOptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Basic flags&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Host&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;host&amp;quot; flagdescr:&amp;quot;Server host&amp;quot; default:&amp;quot;localhost&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Port&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    `flagshort:&amp;quot;p&amp;quot; flagdescr:&amp;quot;Server port&amp;quot; flagrequired:&amp;quot;true&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Environment variable binding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	APIKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flagenv:&amp;quot;true&amp;quot; flagdescr:&amp;quot;API authentication key&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Network contracts using net families&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	BindIP&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;        net&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;IP&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     `flag:&amp;quot;bind-ip&amp;quot; flaggroup:&amp;quot;Network&amp;quot; flagdescr:&amp;quot;Bind interface IP&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	BindMask&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;      net&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;IPMask&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;bind-mask&amp;quot; flaggroup:&amp;quot;Network&amp;quot; flagdescr:&amp;quot;Bind interface mask&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	AdvertiseCIDR&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; net&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;IPNet&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  `flag:&amp;quot;advertise-cidr&amp;quot; flaggroup:&amp;quot;Network&amp;quot; flagdescr:&amp;quot;Advertised service subnet (CIDR)&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	TrustedPeers&lt;&#x2F;span&gt;&lt;span&gt;  []&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;net&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;IP&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   `flag:&amp;quot;trusted-peers&amp;quot; flaggroup:&amp;quot;Network&amp;quot; flagdescr:&amp;quot;Trusted peer IPs (comma separated)&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Flag grouping for organized help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	LogLevel&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; zapcore&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Level&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;log-level&amp;quot; flaggroup:&amp;quot;Logging&amp;quot; flagdescr:&amp;quot;Set log level&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	LogFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;  string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;        `flag:&amp;quot;log-file&amp;quot; flaggroup:&amp;quot;Logging&amp;quot; flagdescr:&amp;quot;Log file path&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Nested structs for organization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Database&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; DatabaseConfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flaggroup:&amp;quot;Database&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Custom type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	TargetEnv&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flagcustom:&amp;quot;true&amp;quot; flag:&amp;quot;target-env&amp;quot; flagdescr:&amp;quot;Set the target environment&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; DatabaseConfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	URL&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;      string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;db-url&amp;quot; flagdescr:&amp;quot;Database connection URL&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	MaxConns&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    `flagdescr:&amp;quot;Max database connections&amp;quot; default:&amp;quot;10&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;full&#x2F;cli&#x2F;cli.go&quot;&gt;full example&lt;&#x2F;a&gt; for more details.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tools-automatic-environment-variable-binding&quot;&gt;🛠️ Automatic Environment Variable Binding&lt;a class=&quot;zola-anchor&quot; href=&quot;#tools-automatic-environment-variable-binding&quot; aria-label=&quot;Anchor link for: tools-automatic-environment-variable-binding&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Automatically generate environment variables binding them to configuration files (YAML, JSON, TOML, etc.) and flags.&lt;&#x2F;p&gt;
&lt;p&gt;From the previous options struct, you get the following env vars automatically:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_PORT&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_APIKEY&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_BIND_IP&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_BIND_MASK&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_ADVERTISE_CIDR&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_TRUSTED_PEERS&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_DATABASE_MAXCONNS&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL_SRV_LOGFILE&lt;&#x2F;code&gt;, &lt;code&gt;FULL_SRV_LOG_FILE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Every struct field with the &lt;code&gt;flagenv:&quot;true&quot;&lt;&#x2F;code&gt; tag gets an environment variable (two if the struct field also has the &lt;code&gt;flag:&quot;...&quot;&lt;&#x2F;code&gt; tag, see struct field &lt;code&gt;LogFile&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The prefix of the environment variable name is the CLI name plus the command name to which those options are attached to.&lt;&#x2F;p&gt;
&lt;p&gt;Environment variables are command-scoped for command-local options.
For example, if &lt;code&gt;Port&lt;&#x2F;code&gt; is attached to the &lt;code&gt;srv&lt;&#x2F;code&gt; command, &lt;code&gt;FULL_SRV_PORT&lt;&#x2F;code&gt; is used (not &lt;code&gt;FULL_PORT&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gear-configuration-file-support&quot;&gt;⚙️ Configuration File Support&lt;a class=&quot;zola-anchor&quot; href=&quot;#gear-configuration-file-support&quot; aria-label=&quot;Anchor link for: gear-configuration-file-support&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Easily set up configuration file discovery (flag, environment variable, and fallback paths) with a single line of code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SetupConfig&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; config&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Options&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;AppName&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;full&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Enable strict config-key validation with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SetupConfig&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; config&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Options&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  AppName&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;      &amp;quot;full&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  ValidateKeys&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; opt-in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When enabled, &lt;code&gt;Unmarshal&lt;&#x2F;code&gt; fails if command-relevant config contains unknown keys.&lt;&#x2F;p&gt;
&lt;p&gt;Call &lt;code&gt;SetupConfig&lt;&#x2F;code&gt; before attaching&#x2F;defining options when you rely on app-prefixed environment variables, so the env prefix is initialized before env annotations are generated.&lt;&#x2F;p&gt;
&lt;p&gt;The line above:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;creates &lt;code&gt;--config&lt;&#x2F;code&gt; global flag&lt;&#x2F;li&gt;
&lt;li&gt;creates &lt;code&gt;FULL_CONFIG&lt;&#x2F;code&gt; env var&lt;&#x2F;li&gt;
&lt;li&gt;sets &lt;code&gt;&#x2F;etc&#x2F;full&#x2F;&lt;&#x2F;code&gt;, &lt;code&gt;$HOME&#x2F;.full&#x2F;&lt;&#x2F;code&gt;, &lt;code&gt;$PWD&#x2F;.full&#x2F;&lt;&#x2F;code&gt; as fallback paths for &lt;code&gt;config.yaml&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Magic, isn&#x27;t it?&lt;&#x2F;p&gt;
&lt;p&gt;What&#x27;s left? Tell your CLI to load the configuration file (if any).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;rootC&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PersistentPreRunE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	_&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; configMessage&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; configErr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;UseConfigSimple&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; configErr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; configErr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; configMessage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;		c&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;configMessage&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;UseConfigSimple(c)&lt;&#x2F;code&gt; loads config into the root config scope and merges only the relevant section into &lt;code&gt;c&lt;&#x2F;code&gt;&#x27;s effective scope.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;brain-viper-model-scopes&quot;&gt;🧠 Viper Model Scopes&lt;a class=&quot;zola-anchor&quot; href=&quot;#brain-viper-model-scopes&quot; aria-label=&quot;Anchor link for: brain-viper-model-scopes&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;structcli&lt;&#x2F;code&gt; uses two different viper scopes on purpose:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;structcli.GetConfigViper(rootOrLeafCmd)&lt;&#x2F;code&gt; -&amp;gt; root-scoped &lt;strong&gt;config source&lt;&#x2F;strong&gt; (config file data tree)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;structcli.GetViper(cmd)&lt;&#x2F;code&gt; -&amp;gt; command-scoped &lt;strong&gt;effective values&lt;&#x2F;strong&gt; (flags&#x2F;env&#x2F;defaults + command-relevant config)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This separation keeps config-file loading isolated from runtime command state.&lt;&#x2F;p&gt;
&lt;p&gt;If you need imperative values in tests or application code, write to the right scope:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; 1) Effective override for one command context&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;GetViper&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;cmd&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;timeout&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; 2) Config-tree style injection (top-level + command section)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;GetConfigViper&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;srv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; map&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;any&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;  &amp;quot;port&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8443&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Global &lt;code&gt;viper.Set(...)&lt;&#x2F;code&gt; is not used by &lt;code&gt;structcli.Unmarshal(...)&lt;&#x2F;code&gt; resolution.
Use &lt;code&gt;GetViper&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;GetConfigViper&lt;&#x2F;code&gt; instead.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;scroll-configuration-is-first-class-citizen&quot;&gt;📜 Configuration Is First-Class Citizen&lt;a class=&quot;zola-anchor&quot; href=&quot;#scroll-configuration-is-first-class-citizen&quot; aria-label=&quot;Anchor link for: scroll-configuration-is-first-class-citizen&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;Configuration can mirror your command hierarchy.&lt;&#x2F;p&gt;
&lt;p&gt;Settings can be global (at the top level) or specific to a command or subcommand. The most specific section always takes precedence.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Global settings apply to all commands unless overridden by a specific section.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# `dryrun` matches the `DryRun` struct field name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;dryrun&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;verbose&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; # A default verbosity level for all commands.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Config for the `srv` command (`full srv`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;srv&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # `port` matches the `Port` field name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  port&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8433&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # Network options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  bind-ip&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;10.20.0.10&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  bind-mask&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ffffff00&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  advertise-cidr&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;10.20.0.0&#x2F;24&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  trusted-peers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;10.20.0.11,10.20.0.12&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # `log-level` matches the `flag:&amp;quot;log-level&amp;quot;` tag.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  log-level&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;warn&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # `logfile` matches the `LogFile` field name.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  logfile&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &#x2F;var&#x2F;log&#x2F;mysrv.log&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # Flattened keys can set options in nested structs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # `db-url` (from `flag:&amp;quot;db-url&amp;quot;` tag) maps to ServerOptions.Database.URL.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  db-url&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;postgres:&#x2F;&#x2F;user:pass@db&#x2F;prod&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # Nested keys are also supported.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  database&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    # Struct field key style&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    url&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;postgres:&#x2F;&#x2F;user:pass@db&#x2F;prod&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    # Alias key style (from `flag:&amp;quot;db-url&amp;quot;`)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    db-url&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;postgres:&#x2F;&#x2F;user:pass@db&#x2F;prod&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Config for the `usr` command group.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;usr&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # This nested section matches the `usr add` command (`full usr add`).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  # Its settings are ONLY applied to &amp;#39;usr add&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  add&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Config User&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;config.user@example.com&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    age&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    # Command specific override&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    dry&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# NOTE: Per the library&amp;#39;s design, there is no other fallback other than from the top-level.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# A command like &amp;#39;usr delete&amp;#39; would ONLY use the global keys above (if those keys&#x2F;flags are attached to it),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# as an exact &amp;#39;usr.delete&amp;#39; section is not defined.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This configuration system supports:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hierarchical Structure&lt;&#x2F;strong&gt;: Nest keys to match your command path (e.g., &lt;code&gt;usr: { add: { ... } }&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Strict Precedence&lt;&#x2F;strong&gt;: Only settings from the global scope and the exact command path section are merged. There is no automatic fallback to parent command sections.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Flexible Keys&lt;&#x2F;strong&gt;: You can use struct field names and aliases (&lt;code&gt;flag:&quot;...&quot;&lt;&#x2F;code&gt;) in both flattened and nested forms.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Supported Forms for Nested Fields&lt;&#x2F;strong&gt;: &lt;code&gt;db-url&lt;&#x2F;code&gt;, &lt;code&gt;database.url&lt;&#x2F;code&gt;, &lt;code&gt;database: { url: ... }&lt;&#x2F;code&gt;, and &lt;code&gt;database: { db-url: ... }&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;white-check-mark-built-in-validation-transformation&quot;&gt;✅ Built-in Validation &amp;amp; Transformation&lt;a class=&quot;zola-anchor&quot; href=&quot;#white-check-mark-built-in-validation-transformation&quot; aria-label=&quot;Anchor link for: white-check-mark-built-in-validation-transformation&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Supports validation, transformation, and custom flag type definitions through simple interfaces.&lt;&#x2F;p&gt;
&lt;p&gt;Your struct must implement &lt;code&gt;Options&lt;&#x2F;code&gt; (via &lt;code&gt;Attach&lt;&#x2F;code&gt;) and can optionally implement &lt;code&gt;ValidatableOptions&lt;&#x2F;code&gt; and &lt;code&gt;TransformableOptions&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; UserConfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Email&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;email&amp;quot; flagdescr:&amp;quot;User email&amp;quot; validate:&amp;quot;email&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Age&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt;   int&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    `flag:&amp;quot;age&amp;quot; flagdescr:&amp;quot;User age&amp;quot; validate:&amp;quot;min=18,max=120&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;  string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;name&amp;quot; flagdescr:&amp;quot;User name&amp;quot; mod:&amp;quot;trim,title&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ServerOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Validate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ctx&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; context&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span&gt;) []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; Automatic validation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ServerOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Transform&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ctx&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; context&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; Automatic transformation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;See a full working example &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;full&#x2F;cli&#x2F;cli.go&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;construction-automatic-debugging-support&quot;&gt;🚧 Automatic Debugging Support&lt;a class=&quot;zola-anchor&quot; href=&quot;#construction-automatic-debugging-support&quot; aria-label=&quot;Anchor link for: construction-automatic-debugging-support&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Create a &lt;code&gt;--debug-options&lt;&#x2F;code&gt; flag (plus a &lt;code&gt;FULL_DEBUG_OPTIONS&lt;&#x2F;code&gt; env var) for troubleshooting config&#x2F;env&#x2F;flags resolution.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SetupDebug&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;rootCmd&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; debug&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Options&lt;&#x2F;span&gt;&lt;span&gt;{})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go run examples&#x2F;full&#x2F;main.go srv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --debug-options --config&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; examples&#x2F;full&#x2F;config.yaml&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3333&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Aliases:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string]string{&amp;quot;database.url&amp;quot;:&amp;quot;db-url&amp;quot;, &amp;quot;logfile&amp;quot;:&amp;quot;log-file&amp;quot;, &amp;quot;loglevel&amp;quot;:&amp;quot;log-level&amp;quot;, &amp;quot;targetenv&amp;quot;:&amp;quot;target-env&amp;quot;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Override:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string]interface {}{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# PFlags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string]viper.FlagValue{&amp;quot;apikey&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x14000109ea0)}, &amp;quot;database.maxconns&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x140002181e0)}, &amp;quot;db-url&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x14000218140)}, &amp;quot;host&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x14000109d60)}, &amp;quot;log-file&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x140002180a0)}, &amp;quot;log-level&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x14000218000)}, &amp;quot;port&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x14000109e00)}, &amp;quot;target-env&amp;quot;:viper.pflagValue{flag:(*pflag.Flag)(0x14000218320)}}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Env:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string][]string{&amp;quot;apikey&amp;quot;:[]string{&amp;quot;SRV_APIKEY&amp;quot;}, &amp;quot;database.maxconns&amp;quot;:[]string{&amp;quot;SRV_DATABASE_MAXCONNS&amp;quot;}, &amp;quot;log-file&amp;quot;:[]string{&amp;quot;SRV_LOGFILE&amp;quot;, &amp;quot;SRV_LOG_FILE&amp;quot;}}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Key&#x2F;Value Store:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string]interface {}{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Config:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string]interface {}{&amp;quot;apikey&amp;quot;:&amp;quot;secret-api-key&amp;quot;, &amp;quot;database&amp;quot;:map[string]interface {}{&amp;quot;maxconns&amp;quot;:3}, &amp;quot;db-url&amp;quot;:&amp;quot;postgres:&#x2F;&#x2F;user:pass@localhost&#x2F;mydb&amp;quot;, &amp;quot;host&amp;quot;:&amp;quot;production-server&amp;quot;, &amp;quot;log-file&amp;quot;:&amp;quot;&#x2F;var&#x2F;log&#x2F;mysrv.log&amp;quot;, &amp;quot;log-level&amp;quot;:&amp;quot;debug&amp;quot;, &amp;quot;port&amp;quot;:8443}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Defaults:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string]interface {}{&amp;quot;database&amp;quot;:map[string]interface {}{&amp;quot;maxconns&amp;quot;:&amp;quot;10&amp;quot;}, &amp;quot;host&amp;quot;:&amp;quot;localhost&amp;quot;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Values:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# map[string]interface {}{&amp;quot;apikey&amp;quot;:&amp;quot;secret-api-key&amp;quot;, &amp;quot;database&amp;quot;:map[string]interface {}{&amp;quot;maxconns&amp;quot;:3, &amp;quot;url&amp;quot;:&amp;quot;postgres:&#x2F;&#x2F;user:pass@localhost&#x2F;mydb&amp;quot;}, &amp;quot;db-url&amp;quot;:&amp;quot;postgres:&#x2F;&#x2F;user:pass@localhost&#x2F;mydb&amp;quot;, &amp;quot;host&amp;quot;:&amp;quot;production-server&amp;quot;, &amp;quot;log-file&amp;quot;:&amp;quot;&#x2F;var&#x2F;log&#x2F;mysrv.log&amp;quot;, &amp;quot;log-level&amp;quot;:&amp;quot;debug&amp;quot;, &amp;quot;logfile&amp;quot;:&amp;quot;&#x2F;var&#x2F;log&#x2F;mysrv.log&amp;quot;, &amp;quot;loglevel&amp;quot;:&amp;quot;debug&amp;quot;, &amp;quot;port&amp;quot;:3333, &amp;quot;target-env&amp;quot;:&amp;quot;dev&amp;quot;, &amp;quot;targetenv&amp;quot;:&amp;quot;dev&amp;quot;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;sharing-options-between-commands&quot;&gt;↪️ Sharing Options Between Commands&lt;a class=&quot;zola-anchor&quot; href=&quot;#sharing-options-between-commands&quot; aria-label=&quot;Anchor link for: sharing-options-between-commands&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;In complex CLIs, multiple commands often need access to the same global configuration and shared resources (like a logger or a database connection). &lt;code&gt;structcli&lt;&#x2F;code&gt; provides a powerful pattern using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;contract.go&quot;&gt;ContextOptions&lt;&#x2F;a&gt; interface to achieve this without resorting to global variables, by propagating a single &quot;source of truth&quot; through the command context.&lt;&#x2F;p&gt;
&lt;p&gt;The pattern allows you to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Populate a shared options struct once from flags, environment variables, or a config file.&lt;&#x2F;li&gt;
&lt;li&gt;Initialize &quot;computed state&quot; (like a logger) based on those options.&lt;&#x2F;li&gt;
&lt;li&gt;Share this single, fully-prepared &quot;source of truth&quot; with any subcommand that needs it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;doughnut-in-a-nutshell&quot;&gt;🍩 In a Nutshell&lt;a class=&quot;zola-anchor&quot; href=&quot;#doughnut-in-a-nutshell&quot; aria-label=&quot;Anchor link for: doughnut-in-a-nutshell&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;Create a shared struct that implements the &lt;code&gt;ContextOptions&lt;&#x2F;code&gt; interface. This struct will hold both the configuration flags and the computed state (e.g., the logger).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; This struct holds our shared state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; CommonOptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    LogLevel&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; zapcore&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Level&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;loglevel&amp;quot; flagdescr:&amp;quot;Logging level&amp;quot; default:&amp;quot;info&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    Logger&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;   *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;zap&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Logger&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   `flagignore:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; This field is computed, not a flag.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; The Context&#x2F;FromContext methods enable the propagation pattern.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CommonOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Context&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ctx&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; context&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; context&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;* ... *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CommonOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; FromContext&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ctx&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; context&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;* ... *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; Initialize is a custom method to create the computed state.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CommonOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Initialize&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;* ... *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Initialize the state in the root command. Use a &lt;code&gt;PersistentPreRunE&lt;&#x2F;code&gt; hook on your root command to populate your struct and initialize any resources.
Invoking &lt;code&gt;structcli.Unmarshal&lt;&#x2F;code&gt; will automatically inject the prepared object into the context for all subcommands to use.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;rootC&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PersistentPreRunE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Populate the master `commonOpts` from flags, env, and config file.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Unmarshal&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commonOpts&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Use the populated values to initialize the computed state (the logger).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; commonOpts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Initialize&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Finally, retrieve the state in subcommands. In your subcommand&#x27;s &lt;code&gt;RunE&lt;&#x2F;code&gt;, simply call &lt;code&gt;.FromContext()&lt;&#x2F;code&gt; to retrieve the shared, initialized object.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; Create a receiver and retrieve the master state from the context.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    config&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; := &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CommonOptions&lt;&#x2F;span&gt;&lt;span&gt;{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; config&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;FromContext&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    config&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;Logger&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Info&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Executing subcommand...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This pattern ensures that subcommands remain decoupled while having access to a consistent, centrally-managed state.&lt;&#x2F;p&gt;
&lt;p&gt;For a complete, runnable implementation of this pattern, see the loginsvc example located in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;loginsvc&#x2F;&quot;&gt;&#x2F;examples&#x2F;loginsvc&lt;&#x2F;a&gt; directory.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;boomerang-custom-type-handlers&quot;&gt;🪃 Custom Type Handlers&lt;a class=&quot;zola-anchor&quot; href=&quot;#boomerang-custom-type-handlers&quot; aria-label=&quot;Anchor link for: boomerang-custom-type-handlers&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Declare options (flags, env vars, config file keys) with custom types by implementing methods on your options struct.&lt;&#x2F;p&gt;
&lt;p&gt;Implement these methods on your options structs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Define&amp;lt;FieldName&amp;gt;&lt;&#x2F;code&gt;: return a &lt;code&gt;pflag.Value&lt;&#x2F;code&gt; that knows how to handle your custom type, along with an enhanced description.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Decode&amp;lt;FieldName&amp;gt;&lt;&#x2F;code&gt;: decode the input into your custom type.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Complete&amp;lt;FieldName&amp;gt;&lt;&#x2F;code&gt; (optional): provide shell completion candidates for the generated flag value. &lt;code&gt;structcli.Define()&lt;&#x2F;code&gt; auto-registers it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-storage z-type z-string z-go&quot;&gt; Environment string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;	EnvDevelopment&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;dev&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;	EnvStaging&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;     Environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;staging&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;	EnvProduction&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  Environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;prod&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; ServerOptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; Custom type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	TargetEnv&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flagcustom:&amp;quot;true&amp;quot; flag:&amp;quot;target-env&amp;quot; flagdescr:&amp;quot;Set the target environment&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; DefineTargetEnv returns a pflag.Value for the custom Environment type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ServerOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; DefineTargetEnv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; short&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; descr&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; structField&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; reflect&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StructField&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fieldValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; reflect&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;pflag&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    enhancedDesc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; descr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot; {dev,staging,prod}&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    fieldPtr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fieldValue&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Addr&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;().(*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Environment&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    *&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;fieldPtr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;dev&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; Set default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; structclivalues&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;NewString&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;((*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;)(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;fieldPtr&lt;&#x2F;span&gt;&lt;span&gt;)),&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; enhancedDesc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; DecodeTargetEnv converts the string input to the Environment type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ServerOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; DecodeTargetEnv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; any&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;any&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;	&#x2F;&#x2F; ... (validation and conversion logic)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; EnvDevelopment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; CompleteTargetEnv provides shell completion for --target-env.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ServerOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; CompleteTargetEnv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;cmd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; args&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; toComplete&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;) ([]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ShellCompDirective&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;dev&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;staging&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;prod&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ShellCompDirectiveNoFileComp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;o &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ServerOptions&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Attach&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;cobra&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-error z-go&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; structcli&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Define&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; o&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;Complete&amp;lt;FieldName&amp;gt;&lt;&#x2F;code&gt; works for any field that becomes a flag (not only &lt;code&gt;flagcustom:&quot;true&quot;&lt;&#x2F;code&gt; fields).&lt;&#x2F;p&gt;
&lt;p&gt;Completion precedence:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If a completion function is already registered on a flag before &lt;code&gt;structcli.Define()&lt;&#x2F;code&gt;, structcli preserves it.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;structcli.Define()&lt;&#x2F;code&gt; auto-registers &lt;code&gt;Complete&amp;lt;FieldName&amp;gt;&lt;&#x2F;code&gt;, a later manual &lt;code&gt;RegisterFlagCompletionFunc&lt;&#x2F;code&gt; on the same flag returns Cobra&#x27;s &lt;code&gt;already registered&lt;&#x2F;code&gt; error.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;values&#x2F;values.go&quot;&gt;values&lt;&#x2F;a&gt; we provide &lt;code&gt;pflag.Value&lt;&#x2F;code&gt; implementations for standard types.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;full&#x2F;cli&#x2F;cli.go&quot;&gt;full example&lt;&#x2F;a&gt; for more details.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bricks-built-in-custom-types&quot;&gt;🧱 Built-in Custom Types&lt;a class=&quot;zola-anchor&quot; href=&quot;#bricks-built-in-custom-types&quot; aria-label=&quot;Anchor link for: bricks-built-in-custom-types&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Type&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;th&gt;Example Values&lt;&#x2F;th&gt;&lt;th&gt;Special Features&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;zapcore.Level&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Zap logging levels&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;debug&lt;&#x2F;code&gt;, &lt;code&gt;info&lt;&#x2F;code&gt;, &lt;code&gt;warn&lt;&#x2F;code&gt;, &lt;code&gt;error&lt;&#x2F;code&gt;, &lt;code&gt;dpanic&lt;&#x2F;code&gt;, &lt;code&gt;panic&lt;&#x2F;code&gt;, &lt;code&gt;fatal&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Enum validation&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;slog.Level&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Standard library logging levels&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;debug&lt;&#x2F;code&gt;, &lt;code&gt;info&lt;&#x2F;code&gt;, &lt;code&gt;warn&lt;&#x2F;code&gt;, &lt;code&gt;error&lt;&#x2F;code&gt;, &lt;code&gt;error+2&lt;&#x2F;code&gt;, ...&lt;&#x2F;td&gt;&lt;td&gt;Level offsets: &lt;code&gt;ERROR+2&lt;&#x2F;code&gt;, &lt;code&gt;INFO-4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;time.Duration&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Time durations&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;30s&lt;&#x2F;code&gt;, &lt;code&gt;5m&lt;&#x2F;code&gt;, &lt;code&gt;2h&lt;&#x2F;code&gt;, &lt;code&gt;1h30m&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Go duration parsing&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;[]time.Duration&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Duration slices&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;30s,5m&lt;&#x2F;code&gt;, &lt;code&gt;1s,2m30s&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Comma-separated &#x2F; repeated flags&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;[]bool&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Boolean slices&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;true,false,true&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Comma-separated &#x2F; repeated flags&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;[]uint&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Unsigned integer slices&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1,2,3,42&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Comma-separated &#x2F; repeated flags&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;[]byte&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Raw textual bytes&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;hello&lt;&#x2F;code&gt;, &lt;code&gt;abc123&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Raw textual input&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;structcli.Hex&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Hex-decoded textual input&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;68656c6c6f&lt;&#x2F;code&gt;, &lt;code&gt;48656c6c6f&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Hex decoding&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;structcli.Base64&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Base64-decoded textual input&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;aGVsbG8=&lt;&#x2F;code&gt;, &lt;code&gt;YWJjMTIz&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Base64 decoding&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;net.IP&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;IP address&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;127.0.0.1&lt;&#x2F;code&gt;, &lt;code&gt;10.42.0.10&lt;&#x2F;code&gt;, &lt;code&gt;2001:db8::1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;IP parsing&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;net.IPMask&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;IPv4 mask&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;255.255.255.0&lt;&#x2F;code&gt;, &lt;code&gt;ffffff00&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Dotted or hex mask parsing&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;net.IPNet&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;CIDR subnet&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;10.42.0.0&#x2F;24&lt;&#x2F;code&gt;, &lt;code&gt;2001:db8::&#x2F;64&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;CIDR parsing&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;[]net.IP&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;IP slices&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;10.0.0.1,10.0.0.2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Comma-separated &#x2F; repeated flags&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;[]string&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;String slices&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;item1,item2,item3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Comma-separated&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;[]int&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Integer slices&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;1,2,3,42&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Comma-separated&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;map[string]string&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;String maps&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;env=prod,team=platform&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;key=value&lt;&#x2F;code&gt; pairs&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;map[string]int&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Integer maps&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;cpu=2,memory=4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;key=value&lt;&#x2F;code&gt; pairs with int parsing&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;map[string]int64&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;64-bit integer maps&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;ok=1,fail=2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;key=value&lt;&#x2F;code&gt; pairs with int64 parsing&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Note on JSON output: &lt;code&gt;net.IPMask&lt;&#x2F;code&gt; is a byte slice under the hood, so Go&#x27;s &lt;code&gt;encoding&#x2F;json&lt;&#x2F;code&gt;
renders it as base64 (for example &lt;code&gt;255.255.255.0&lt;&#x2F;code&gt; appears as &lt;code&gt;&#x2F;&#x2F;&#x2F;&#x2F;AA==&lt;&#x2F;code&gt;). This is expected.&lt;&#x2F;p&gt;
&lt;p&gt;All built-in types support:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Command-line flags with validation and help text&lt;&#x2F;li&gt;
&lt;li&gt;Environment variables with automatic binding&lt;&#x2F;li&gt;
&lt;li&gt;Configuration files (YAML, JSON, TOML)&lt;&#x2F;li&gt;
&lt;li&gt;Type validation with helpful error messages&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Slices and maps use the same contract across flags, env vars, and config.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;collections&#x2F;main.go&quot;&gt;examples&#x2F;collections&#x2F;main.go&lt;&#x2F;a&gt; for a runnable version of this example.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AdvancedOptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Retries&lt;&#x2F;span&gt;&lt;span&gt;   []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;          `flag:&amp;quot;retries&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Backoffs&lt;&#x2F;span&gt;&lt;span&gt;  []&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;time&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Duration&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;backoffs&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	FeatureOn&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-boolean z-go&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;          `flag:&amp;quot;feature-on&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;    map&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `flag:&amp;quot;labels&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Limits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;    map&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    `flag:&amp;quot;limits&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	Counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;    map&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-go&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-numeric z-go&quot;&gt;int64&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  `flag:&amp;quot;counts&amp;quot; flagenv:&amp;quot;true&amp;quot;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; myapp&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --retries&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 1,2,3&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --backoffs&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 1s,5s&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option z-constant z-language&quot;&gt; --feature-on true&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-constant z-other z-option&quot;&gt;false --labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; env=prod,team=platform&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --limits&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cpu=8,memory=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;16&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ok=10,fail=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; MYAPP_RETRIES=1,2,3 MYAPP_BACKOFFS=1s,5s MYAPP_FEATURE_ON=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;false&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; MYAPP_LABELS=env=prod,team=platform MYAPP_LIMITS=cpu=8,memory=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;16&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; MYAPP_COUNTS=ok=10,fail=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; myapp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go run examples&#x2F;collections&#x2F;main.go&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --config&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; examples&#x2F;collections&#x2F;config.yaml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;retries&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;1,2,3&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;backoffs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 1s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 5s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;feature-on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;true,false&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  env&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; prod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  team&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; platform&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;limits&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  cpu&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  memory&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;counts&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ok=10,fail=3&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;art-beautiful-organized-help-output&quot;&gt;🎨 Beautiful, Organized Help Output&lt;a class=&quot;zola-anchor&quot; href=&quot;#art-beautiful-organized-help-output&quot; aria-label=&quot;Anchor link for: art-beautiful-organized-help-output&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Organize your &lt;code&gt;--help&lt;&#x2F;code&gt; output into logical groups for better readability.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go run examples&#x2F;full&#x2F;main.go&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# A demonstration of the structcli library with beautiful CLI features&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Usage:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   full [flags]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   full [command]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Available Commands:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   completion  Generate the autocompletion script for the specified shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   help        Help about any command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   srv         Start the server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   usr         User management&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Global Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --config string   config file (fallbacks to: {&#x2F;etc&#x2F;full,{executable_dir}&#x2F;.full,$HOME&#x2F;.full}&#x2F;config.{yaml,json,toml})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --debug-options   enable debug output for options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Utility Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --dry-run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   -v, --verbose count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; go run examples&#x2F;full&#x2F;main.go srv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-option&quot;&gt; --help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Start the server with the specified configuration&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Usage:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   full srv [flags]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   full srv [command]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Available Commands:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   version     Print version information&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --apikey string       API authentication key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --host string         Server host (default &amp;quot;localhost&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#   -p, --port int            Server port&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --target-env string   Set the target environment {dev,staging,prod} (default &amp;quot;dev&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Database Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --database.maxconns int   Max database connections (default 10)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --db-url string           Database connection URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Logging Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --log-file string           Log file path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --log-level zapcore.Level   Set log level {debug,info,warn,error,dpanic,panic,fatal} (default info)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Network Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --advertise-cidr ipNet      Advertised service subnet (CIDR) (default 127.0.0.0&#x2F;24)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --bind-ip ip                Bind interface IP (default 127.0.0.1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --bind-mask ipMask          Bind interface mask (default ffffff00)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --trusted-peers ipSlice     Trusted peer IPs (comma separated) (default [127.0.0.2,127.0.0.3])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Global Flags:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --config string   config file (fallbacks to: {&#x2F;etc&#x2F;full,{executable_dir}&#x2F;.full,$HOME&#x2F;.full}&#x2F;config.{yaml,json,toml})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#       --debug-options   enable debug output for options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# Use &amp;quot;full srv [command] --help&amp;quot; for more information about a command.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;label-available-struct-tags&quot;&gt;🏷️ Available Struct Tags&lt;a class=&quot;zola-anchor&quot; href=&quot;#label-available-struct-tags&quot; aria-label=&quot;Anchor link for: label-available-struct-tags&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Use these tags in your struct fields to control the behavior:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Tag&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;th&gt;Example&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flag&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Sets a custom name for the flag (otherwise, generated from the field name)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flag:&quot;log-level&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagpreset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Defines CLI-only preset aliases for this field&#x27;s flag. Each preset is &lt;code&gt;&amp;lt;alias-flag-name&amp;gt;=&amp;lt;value-for-this-field-flag&amp;gt;&lt;&#x2F;code&gt;. No env&#x2F;config keys are created.&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagpreset:&quot;logeverything=5;logquiet=0&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagshort&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Sets a single-character shorthand for the flag&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagshort:&quot;l&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagdescr&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Provides the help text for the flag&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagdescr:&quot;Logging level&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;default&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Sets the default value for the flag&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;default:&quot;info&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagenv&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Enables binding to an environment variable (&lt;code&gt;&quot;true&quot;&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;&quot;false&quot;&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagenv:&quot;true&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagrequired&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Marks the flag as required (&lt;code&gt;&quot;true&quot;&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;&quot;false&quot;&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagrequired:&quot;true&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flaghidden&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Hides the flag from help&#x2F;usage output and machine-readable schemas while keeping it fully functional (&lt;code&gt;&quot;true&quot;&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;&quot;false&quot;&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flaghidden:&quot;true&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flaggroup&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Assigns the flag to a group in the help message&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flaggroup:&quot;Database&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagignore&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Skips creating a flag for this field (&lt;code&gt;&quot;true&quot;&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;&quot;false&quot;&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagignore:&quot;true&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagcustom&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Uses a custom &lt;code&gt;Define&amp;lt;FieldName&amp;gt;&lt;&#x2F;code&gt; method for advanced flag creation and a custom &lt;code&gt;Decode&amp;lt;FieldName&amp;gt;&lt;&#x2F;code&gt; method for advanced value decoding&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagcustom:&quot;true&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flagtype&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Specifies a special flag type. Currently supports &lt;code&gt;count&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;flagtype:&quot;count&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;code&gt;flagpreset&lt;&#x2F;code&gt; is syntactic sugar: it creates alias flags that set the canonical flag value.
Format: &lt;code&gt;&amp;lt;alias&amp;gt;=&amp;lt;value&amp;gt;&lt;&#x2F;code&gt;; multiple entries can be separated by &lt;code&gt;;&lt;&#x2F;code&gt; or &lt;code&gt;,&lt;&#x2F;code&gt;.
Example: &lt;code&gt;flagpreset:&quot;logeverything=5;logquiet=0&quot;&lt;&#x2F;code&gt; makes &lt;code&gt;--logeverything&lt;&#x2F;code&gt; behave like &lt;code&gt;--loglevel=5&lt;&#x2F;code&gt;.
If both alias and canonical flags are passed, the last assignment in argv wins.
It does not bypass transform&#x2F;validate flow.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;book-documentation&quot;&gt;📖 Documentation&lt;a class=&quot;zola-anchor&quot; href=&quot;#book-documentation&quot; aria-label=&quot;Anchor link for: book-documentation&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For comprehensive documentation and advanced usage patterns, visit the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;github.com&#x2F;leodido&#x2F;structcli&quot;&gt;documentation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Start here for repo-local guides:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;docs&#x2F;ai-native.md&quot;&gt;AI-Native CLIs guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;structerr&#x2F;README.md&quot;&gt;Structured error example walkthrough&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;leodido&#x2F;structcli&#x2F;tree&#x2F;main&#x2F;examples&#x2F;&quot;&gt;Examples directory&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;handshake-contributing&quot;&gt;🤝 Contributing&lt;a class=&quot;zola-anchor&quot; href=&quot;#handshake-contributing&quot; aria-label=&quot;Anchor link for: handshake-contributing&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Contributions are welcome!&lt;&#x2F;p&gt;
&lt;p&gt;Please feel free to submit a Pull Request.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
