Skip to content

Commit 46d3697

Browse files
Mpdreamzclaude
andauthored
feat(cli-reference): improve intent pills, add shortcut/alias support (#3361)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 0464e10 commit 46d3697

19 files changed

Lines changed: 363 additions & 49 deletions

File tree

src/Elastic.Documentation.Configuration/Toc/CliReference/CliSchema.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public record CliSchema(
2222
string[]? Tags = null,
2323
bool? RequiresAuth = null,
2424
string[]? AuthCommands = null,
25-
CliEnvironmentSchema? Environment = null
25+
CliEnvironmentSchema? Environment = null,
26+
List<CliShortcutSchema>? Shortcuts = null
2627
)
2728
{
2829
public static CliSchema Load(IFileInfo schemaFile)
@@ -33,6 +34,8 @@ public static CliSchema Load(IFileInfo schemaFile)
3334
}
3435
}
3536

37+
public record CliShortcutSchema(string From, string[] To);
38+
3639
public record CliCommandSchema(
3740
string[] Path,
3841
string Name,
@@ -55,10 +58,10 @@ public record CliNamespaceSchema(
5558
string Segment,
5659
string? Summary,
5760
string? Notes,
58-
List<CliParamSchema> Options,
61+
List<CliParamSchema>? Options,
5962
CliDefaultSchema? DefaultCommand,
60-
List<CliCommandSchema> Commands,
61-
List<CliNamespaceSchema> Namespaces
63+
List<CliCommandSchema>? Commands,
64+
List<CliNamespaceSchema>? Namespaces
6265
);
6366

6467
public record CliParamSchema(

src/Elastic.Documentation.Navigation/Isolated/Node/DocumentationSetNavigation.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,14 @@ INavigationHomeAccessor homeAccessor
484484
children.Add(childNav);
485485
}
486486

487-
// All root commands + namespaces from the schema always follow
487+
// Shortcut alias pages first, then commands and namespaces
488+
foreach (var shortcut in schema.Shortcuts ?? [])
489+
{
490+
var aliasNav = MakeFileLeaf(docSourceDir, virtualRoot, [shortcut.From], isNamespace: true, childIndex++, folderNavigation, homeAccessor, context);
491+
if (aliasNav is not null)
492+
children.Add(aliasNav);
493+
}
494+
488495
foreach (var cmd in schema.Commands)
489496
{
490497
var cmdNav = MakeFileLeaf(docSourceDir, virtualRoot, [cmd.Name], isNamespace: false, childIndex++, folderNavigation, homeAccessor, context);
@@ -532,7 +539,7 @@ IDocumentationSetContext context
532539
children.Add(nsIndexNav);
533540

534541
// Namespace commands
535-
foreach (var cmd in ns.Commands)
542+
foreach (var cmd in ns.Commands ?? [])
536543
{
537544
var cmdSegments = segments.Append(cmd.Name).ToArray();
538545
var cmdNav = MakeFileLeaf(docSourceDir, virtualRoot, cmdSegments, isNamespace: false, childIndex++, nsFolderNav, homeAccessor, context);
@@ -541,7 +548,7 @@ IDocumentationSetContext context
541548
}
542549

543550
// Sub-namespaces
544-
foreach (var subNs in ns.Namespaces)
551+
foreach (var subNs in ns.Namespaces ?? [])
545552
{
546553
var subSegments = segments.Append(subNs.Segment).ToArray();
547554
var subNav = BuildNamespaceNavigation(docSourceDir, virtualRoot, subNs, subSegments, childIndex++, nsFolderNav, homeAccessor, context);

src/Elastic.Documentation.Site/Assets/markdown/cli-modifiers.css

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
@layer components {
22
.cli-modifiers {
3-
@apply flex flex-wrap gap-2 pb-4;
3+
@apply mt-4 mb-4 flex flex-wrap gap-2;
44

55
.cli-modifier {
6-
@apply inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium;
6+
@apply relative inline-flex cursor-help items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium;
77

88
svg {
99
@apply size-3.5 shrink-0;
1010
}
11+
12+
/* CSS tooltip via data-tooltip attribute */
13+
&[data-tooltip]::after {
14+
content: attr(data-tooltip);
15+
@apply pointer-events-none absolute bottom-full left-1/2 z-50 mb-2 w-max max-w-64 -translate-x-1/2 rounded px-2 py-1 text-xs text-white opacity-0 transition-opacity;
16+
background: #1e293b;
17+
}
18+
&[data-tooltip]:hover::after,
19+
&[data-tooltip]:focus-visible::after {
20+
@apply opacity-100;
21+
}
1122
}
1223

1324
.cli-modifier--destructive {

src/Elastic.Documentation.Site/Navigation/_TocTreeNav.cshtml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@
1111
{
1212
if (raw.StartsWith("[ns]", StringComparison.Ordinal)) return ("ns", raw[4..]);
1313
if (raw.StartsWith("[cmd]", StringComparison.Ordinal)) return ("cmd", raw[5..]);
14+
if (raw.StartsWith("[alias]", StringComparison.Ordinal)) return ("alias", raw[7..]);
1415
return (null, raw);
1516
}
1617

1718
// Inline styles to avoid Tailwind purge — very muted tints, subtle border for definition
18-
const string NsStyle = "background:#f5f3ff;color:#7c3aed;border:1px solid #ddd6fe;";
19-
const string CmdStyle = "background:#fffbeb;color:#b45309;border:1px solid #fde68a;";
19+
const string NsStyle = "background:#f5f3ff;color:#7c3aed;border:1px solid #ddd6fe;";
20+
const string CmdStyle = "background:#fffbeb;color:#b45309;border:1px solid #fde68a;";
21+
const string AliasStyle = "background:#f0f9ff;color:#0369a1;border:1px solid #bae6fd;";
2022

21-
static string BadgeStyle(string? badge) => badge == "ns" ? NsStyle : badge == "cmd" ? CmdStyle : "";
23+
static string BadgeStyle(string? badge) => badge switch { "ns" => NsStyle, "cmd" => CmdStyle, "alias" => AliasStyle, _ => "" };
2224
}
2325
@if (isTopLevel && !Model.IsGlobalAssemblyBuild && !Model.IsPrimaryNavEnabled && !Model.SubTree.Index.Hidden)
2426
{
@@ -56,6 +58,7 @@
5658
<span>@groupLabel</span>
5759
@if (groupBadge == "ns") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@NsStyle">ns</span> }
5860
else if (groupBadge == "cmd") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@CmdStyle">cmd</span> }
61+
else if (groupBadge == "alias") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@AliasStyle">alias</span> }
5962
</a>
6063
</li>
6164
}
@@ -73,6 +76,7 @@
7376
<span>@folderLabel</span>
7477
@if (folderBadge == "ns") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@NsStyle">ns</span> }
7578
else if (folderBadge == "cmd") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@CmdStyle">cmd</span> }
79+
else if (folderBadge == "alias") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@AliasStyle">alias</span> }
7680
</a>
7781
@if (!allHidden)
7882
{
@@ -125,6 +129,7 @@
125129
<span>@leafLabel</span>
126130
@if (leafBadge == "ns") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@NsStyle">ns</span> }
127131
else if (leafBadge == "cmd") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@CmdStyle">cmd</span> }
132+
else if (leafBadge == "alias") { <span class="ml-auto inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold shrink-0" style="@AliasStyle">alias</span> }
128133
</a>
129134
</li>
130135
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.IO.Abstractions;
6+
using Elastic.Documentation.Configuration;
7+
using Elastic.Documentation.Configuration.Toc.CliReference;
8+
using Elastic.Markdown.Myst;
9+
using Markdig.Syntax;
10+
11+
namespace Elastic.Markdown.Extensions.CliReference;
12+
13+
public record CliAliasFile : IO.MarkdownFile
14+
{
15+
private readonly CliShortcutSchema _shortcut;
16+
private readonly string _binaryName;
17+
private readonly string _canonicalRelativePath;
18+
19+
public CliAliasFile(
20+
IFileInfo sourceFile,
21+
IDirectoryInfo rootPath,
22+
MarkdownParser parser,
23+
BuildContext build,
24+
CliShortcutSchema shortcut,
25+
string binaryName,
26+
string canonicalRelativePath
27+
) : base(sourceFile, rootPath, parser, build)
28+
{
29+
_shortcut = shortcut;
30+
_binaryName = binaryName;
31+
_canonicalRelativePath = canonicalRelativePath;
32+
Title = shortcut.From;
33+
}
34+
35+
public override string NavigationTitle => $"[alias]{_shortcut.From}";
36+
37+
public override string? RedirectUrl => _canonicalRelativePath;
38+
39+
protected override Task<MarkdownDocument> GetMinimalParseDocumentAsync(Cancel ctx)
40+
{
41+
Title = _shortcut.From;
42+
var markdown = BuildMarkdown();
43+
return Task.FromResult(MarkdownParser.MinimalParseStringAsync(markdown, SourceFile, null));
44+
}
45+
46+
protected override Task<MarkdownDocument> GetParseDocumentAsync(Cancel ctx)
47+
{
48+
var markdown = BuildMarkdown();
49+
return Task.FromResult(MarkdownParser.ParseStringAsync(markdown, SourceFile, null));
50+
}
51+
52+
private string BuildMarkdown() =>
53+
CliMarkdownGenerator.AliasPage(_shortcut, _binaryName, _canonicalRelativePath);
54+
}

src/Elastic.Markdown/Extensions/CliReference/CliCommandFile.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public record CliCommandFile : IO.MarkdownFile
1717
private readonly string? _binaryName;
1818
private readonly string[] _fullPath;
1919
private readonly string[]? _reservedMetaCommands;
20+
private readonly IReadOnlyList<(string Segment, List<CliParamSchema>? Options)>? _ancestorNamespaceOptions;
21+
private readonly List<CliParamSchema>? _globalOptions;
22+
private readonly List<CliShortcutSchema>? _shortcuts;
2023

2124
public CliCommandFile(
2225
IFileInfo sourceFile,
@@ -27,14 +30,20 @@ public CliCommandFile(
2730
IFileInfo? supplementalDoc,
2831
string[]? fullPath = null,
2932
string? binaryName = null,
30-
string[]? reservedMetaCommands = null
33+
string[]? reservedMetaCommands = null,
34+
IReadOnlyList<(string Segment, List<CliParamSchema>? Options)>? ancestorNamespaceOptions = null,
35+
List<CliParamSchema>? globalOptions = null,
36+
List<CliShortcutSchema>? shortcuts = null
3137
) : base(sourceFile, rootPath, parser, build)
3238
{
3339
_command = command;
3440
_supplementalDoc = supplementalDoc;
3541
_fullPath = fullPath ?? [command.Name];
3642
_binaryName = binaryName;
3743
_reservedMetaCommands = reservedMetaCommands;
44+
_ancestorNamespaceOptions = ancestorNamespaceOptions;
45+
_globalOptions = globalOptions;
46+
_shortcuts = shortcuts;
3847
Title = command.Name;
3948
}
4049

@@ -60,6 +69,7 @@ private string BuildMarkdown()
6069
: null;
6170
var supplemental = CliSupplementalDoc.Parse(rawSupplemental);
6271
return CliMarkdownGenerator.CommandPage(_command, supplemental, _fullPath, _binaryName, _reservedMetaCommands,
63-
error => Collector.EmitError(_supplementalDoc ?? SourceFile, error));
72+
error => Collector.EmitError(_supplementalDoc ?? SourceFile, error),
73+
_ancestorNamespaceOptions, _globalOptions, _shortcuts);
6474
}
6575
}

0 commit comments

Comments
 (0)