diff --git a/scripts/test_update_cli_nav.py b/scripts/test_update_cli_nav.py
new file mode 100644
index 0000000..4eb40cb
--- /dev/null
+++ b/scripts/test_update_cli_nav.py
@@ -0,0 +1,49 @@
+import json
+import os
+import subprocess
+import tempfile
+
+
+def _write(path, frontmatter):
+ with open(path, "w", encoding="utf-8") as f:
+ f.write("---\n" + frontmatter + "\n---\n\nbody\n")
+
+
+def test_nav_skips_hidden_and_has_no_deprecated_group():
+ with tempfile.TemporaryDirectory() as d:
+ docs_dir = os.path.join(d, "client_reference")
+ os.makedirs(docs_dir)
+ _write(os.path.join(docs_dir, "overview.md"), 'title: "Overview"')
+ _write(os.path.join(docs_dir, "output_and_verbosity.md"), 'title: "Output"')
+ _write(os.path.join(docs_dir, "kosli_attest_generic.md"), 'title: "kosli attest generic"')
+ _write(os.path.join(docs_dir, "kosli_report_approval.md"),
+ 'title: "kosli report approval"\ntag: "DEPRECATED"')
+ _write(os.path.join(docs_dir, "kosli_attest_decision.md"),
+ 'title: "kosli attest decision"\ntag: "BETA"\nhidden: true')
+
+ nav_path = os.path.join(d, "navigation.json")
+ with open(nav_path, "w", encoding="utf-8") as f:
+ json.dump({"tabs": [{"tab": "Reference", "menu": [
+ {"item": "CLI Reference", "icon": "terminal", "groups": []}]}]}, f)
+
+ subprocess.run(
+ ["python", os.path.join(os.path.dirname(__file__), "update-cli-nav.py"),
+ "--docs-dir", docs_dir, "--nav-file", nav_path],
+ check=True,
+ )
+
+ with open(nav_path, encoding="utf-8") as f:
+ nav = json.load(f)
+ groups = nav["tabs"][0]["menu"][0]["groups"]
+ all_pages = [p for g in groups for p in g["pages"]]
+ group_names = [g["group"] for g in groups]
+
+ assert "client_reference/kosli_attest_decision" not in all_pages, "hidden page must be skipped"
+ assert "client_reference/kosli_attest_generic" in all_pages
+ assert "client_reference/kosli_report_approval" in all_pages, "deprecated page stays in its family group"
+ assert "Deprecated" not in group_names, "separate Deprecated group must be removed"
+
+
+if __name__ == "__main__":
+ test_nav_skips_hidden_and_has_no_deprecated_group()
+ print("PASS")
diff --git a/scripts/update-cli-nav.py b/scripts/update-cli-nav.py
index aafd59b..57daa74 100644
--- a/scripts/update-cli-nav.py
+++ b/scripts/update-cli-nav.py
@@ -15,11 +15,10 @@
def get_command_info(filepath):
- """Extract command name and deprecated status from a CLI reference file."""
+ """Extract command title and hidden status from a CLI reference file."""
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
- # Parse front matter
match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
if not match:
return None
@@ -32,19 +31,9 @@ def get_command_info(filepath):
if not fm or 'title' not in fm:
return None
- title = fm['title']
- deprecated = fm.get('deprecated', False)
-
- # Check for deprecated warning in body (for converted files that don't have
- # the deprecated field but have a Warning about deprecation)
- if not deprecated:
- body = content[match.end():]
- if re.search(r'is deprecated', body[:500], re.IGNORECASE):
- deprecated = True
-
return {
- 'title': title,
- 'deprecated': deprecated,
+ 'title': fm['title'],
+ 'hidden': bool(fm.get('hidden', False)),
}
@@ -96,14 +85,18 @@ def get_command_group(title):
def build_nav_groups(docs_dir):
- """Scan CLI reference files and build navigation groups."""
+ """Scan CLI reference files and build navigation groups.
+
+ Hidden pages (hidden: true) are excluded from navigation; they remain
+ reachable by direct URL. Lifecycle tags (BETA/DEPRECATED) render as sidebar
+ pills automatically from each page's front matter, so there is no separate
+ Deprecated group.
+ """
commands = []
for filename in sorted(os.listdir(docs_dir)):
if not filename.endswith('.md'):
continue
- # Skip manually-maintained intro pages; they are inserted into the
- # General group below in a fixed order.
if filename in ('overview.md', 'output_and_verbosity.md'):
continue
@@ -111,31 +104,19 @@ def build_nav_groups(docs_dir):
info = get_command_info(filepath)
if info is None:
continue
+ if info['hidden']:
+ continue
- page_path = f'client_reference/{filename[:-3]}' # Remove .md
+ page_path = f'client_reference/{filename[:-3]}'
commands.append({
'page': page_path,
- 'title': info['title'],
- 'deprecated': info['deprecated'],
'group': get_command_group(info['title']),
})
- # Separate active and deprecated commands
- active = [c for c in commands if not c['deprecated']]
- deprecated = [c for c in commands if c['deprecated']]
-
- # Group active commands
groups_dict = {}
- for cmd in active:
- group = cmd['group']
- if group not in groups_dict:
- groups_dict[group] = []
- groups_dict[group].append(cmd['page'])
-
- # Build ordered navigation groups.
- # 1. General — manually-maintained intro pages, fixed order.
- # 2. Top-level commands — auto-generated single-word kosli commands.
- # 3. Remaining command families in alphabetical order, prefixed 'kosli '.
+ for cmd in commands:
+ groups_dict.setdefault(cmd['group'], []).append(cmd['page'])
+
nav_groups = [
{
'group': 'General',
@@ -153,19 +134,11 @@ def build_nav_groups(docs_dir):
})
for group_name in sorted(groups_dict.keys()):
- display_name = f'kosli {group_name}'
nav_groups.append({
- 'group': display_name,
+ 'group': f'kosli {group_name}',
'pages': groups_dict[group_name],
})
- # Add deprecated group if there are deprecated commands
- if deprecated:
- nav_groups.append({
- 'group': 'Deprecated',
- 'pages': [c['page'] for c in deprecated],
- })
-
return nav_groups
diff --git a/snippets/cli-beta-notice.mdx b/snippets/cli-beta-notice.mdx
new file mode 100644
index 0000000..c9dad92
--- /dev/null
+++ b/snippets/cli-beta-notice.mdx
@@ -0,0 +1,6 @@
+
+This is a beta feature. Beta features provide early access to product
+functionality. These features may change between releases without warning, or
+can be removed in a future release. Please contact us to enable this feature
+for your organization.
+
diff --git a/snippets/cli-deprecated-notice.mdx b/snippets/cli-deprecated-notice.mdx
new file mode 100644
index 0000000..b373606
--- /dev/null
+++ b/snippets/cli-deprecated-notice.mdx
@@ -0,0 +1,4 @@
+
+This command is deprecated. Deprecated commands will be removed in a future
+release.
+