@@ -37,6 +37,34 @@ function flagsToInlineCode(text: string): string {
3737 return text . replaceAll ( FLAGS_RE , "`$&`" ) ;
3838}
3939
40+ /**
41+ * Parse the usage string to extract the value type.
42+ * Examples:
43+ * "--config <FILE>" → "FILE"
44+ * "--fail-fast[=<N>]" → "N"
45+ * "--coverage[=<DIR>]" → "DIR"
46+ * "--no-check[=<NO_CHECK_TYPE>]" → "NO_CHECK_TYPE"
47+ * "--no-run" → null (boolean flag)
48+ */
49+ function parseValueType ( usage : string ) : string | null {
50+ const match = usage . match ( / < ( [ ^ > ] + ) > / ) ;
51+ if ( ! match ) return null ;
52+
53+ const raw = match [ 1 ] ;
54+ // Clean up common patterns
55+ return raw
56+ . replace ( / \. \. \. $ / , "" )
57+ . trim ( ) ;
58+ }
59+
60+ /**
61+ * Determine if a flag is boolean (no value) or takes a value.
62+ * Optional values like `--flag[=<VAL>]` are marked as optional.
63+ */
64+ function isOptionalValue ( usage : string ) : boolean {
65+ return usage . includes ( "[=<" ) || usage . includes ( "[<" ) ;
66+ }
67+
4068export default function renderCommand (
4169 commandName : string ,
4270 helpers : Lume . Helpers ,
@@ -47,7 +75,7 @@ export default function renderCommand(
4775
4876 const toc : TableOfContentsItem_ [ ] = [ ] ;
4977
50- // Add null check for command.about
78+ // Process the about text (description from CLI help)
5179 let about = "" ;
5280 if ( command . about ) {
5381 about = command . about . replaceAll (
@@ -102,7 +130,7 @@ export default function renderCommand(
102130 ) ;
103131 }
104132
105- const args = [ ] ;
133+ // Separate args into positional args and grouped options
106134 const options : Record < string , ArgType [ ] > = { } ;
107135
108136 for ( const arg of command . args ) {
@@ -113,21 +141,35 @@ export default function renderCommand(
113141 if ( arg . long ) {
114142 const key = arg . help_heading ?? "Options" ;
115143 options [ key ] ??= [ ] ;
116- options [ key ] . push ( arg ) ;
117- } else {
118- args . push ( arg ) ;
144+ options [ key ] . push ( arg as ArgType ) ;
119145 }
120146 }
121147
122148 const rendered = (
123149 < div >
150+ < div class = "bg-transparent mt-4 mb-12 relative pl-2 border-l border-background-tertiary" >
151+ < div class = "text-xs font-bold mb-1" >
152+ Command line usage:
153+ </ div >
154+ < div >
155+ < pre class = "!mb-0 !p-6" >
156+ < code >
157+ { command . usage . replaceAll ( ANSI_RE , "" ) . slice ( "usage: " . length ) }
158+ </ code >
159+ </ pre >
160+ </ div >
161+ </ div >
162+
163+ { about && (
164+ < div
165+ class = "flex flex-col gap-4"
166+ dangerouslySetInnerHTML = { { __html : helpers . md ( about ) } }
167+ />
168+ ) }
169+
124170 { Object . entries ( options ) . map ( ( [ heading , flags ] ) => {
125171 const id = heading . toLowerCase ( ) . replace ( / \s / g, "-" ) ;
126172
127- const renderedFlags = flags . toSorted ( ( a : ArgType , b : ArgType ) =>
128- a . long . localeCompare ( b . long )
129- ) . map ( ( flag : ArgType ) => renderOption ( id , flag , helpers ) ) ;
130-
131173 toc . push ( {
132174 text : heading ,
133175 slug : id ,
@@ -139,7 +181,13 @@ export default function renderCommand(
139181 < h2 id = { id } >
140182 { heading } < HeaderAnchor id = { id } />
141183 </ h2 >
142- { renderedFlags }
184+ < div class = "flex flex-col gap-8 mt-4" >
185+ { flags
186+ . toSorted ( ( a : ArgType , b : ArgType ) =>
187+ a . long . localeCompare ( b . long )
188+ )
189+ . map ( ( flag : ArgType ) => renderOption ( id , flag , helpers ) ) }
190+ </ div >
143191 </ >
144192 ) ;
145193 } ) }
@@ -154,9 +202,11 @@ export default function renderCommand(
154202
155203function renderOption ( group : string , arg : ArgType , helpers : Lume . Helpers ) {
156204 const id = `${ group } -${ arg . long } ` ;
205+ const valueType = parseValueType ( arg . usage ) ;
206+ const optional = isOptionalValue ( arg . usage ) ;
157207
158- let docsLink = null ;
159- // Add null check for arg.help
208+ // Extract docs link from help text if present
209+ let docsLink : string | null = null ;
160210 let help = arg . help ? arg . help . replaceAll ( ANSI_RE , "" ) : "" ;
161211 if ( help ) {
162212 const helpLines = help . split ( "\n" ) ;
@@ -171,24 +221,33 @@ function renderOption(group: string, arg: ArgType, helpers: Lume.Helpers) {
171221 }
172222 }
173223
224+ // Build the flag display: --long, -short
225+ const longFlag = "--" + arg . long ;
226+ const flagDisplay = arg . short ? `${ longFlag } , -${ arg . short } ` : longFlag ;
227+
174228 return (
175- < >
176- < h3 id = { id } >
177- < code >
178- { docsLink
179- ? < a href = { docsLink } > { "--" + arg . long } </ a >
180- : ( "--" + arg . long ) }
181- </ code > { " " }
229+ < div id = { id } >
230+ < div class = "flex items-baseline justify-between gap-4 flex-wrap" >
231+ < div class = "flex items-baseline gap-2" >
232+ < code class = "text-sm font-semibold" >
233+ { docsLink ? < a href = { docsLink } > { flagDisplay } </ a > : flagDisplay }
234+ </ code >
235+ { valueType && (
236+ < span class = "text-xs text-foreground-secondary" >
237+ { "<" }
238+ { valueType }
239+ { ">" }
240+ { optional && (
241+ < span class = "text-foreground-tertiary ml-1" > optional</ span >
242+ ) }
243+ </ span >
244+ ) }
245+ </ div >
182246 < HeaderAnchor id = { id } />
183- </ h3 >
184- { arg . short && (
185- < p class = "text-sm" >
186- Short flag: < code > -{ arg . short } </ code >
187- </ p >
188- ) }
189- { arg . help && (
247+ </ div >
248+ { help && (
190249 < div
191- class = "block !whitespace-pre-line"
250+ class = "mt-2 text-sm !whitespace-pre-line"
192251 dangerouslySetInnerHTML = { {
193252 __html : helpers . md (
194253 flagsToInlineCode ( help ) +
@@ -197,6 +256,6 @@ function renderOption(group: string, arg: ArgType, helpers: Lume.Helpers) {
197256 } }
198257 />
199258 ) }
200- </ >
259+ </ div >
201260 ) ;
202261}
0 commit comments