On this page
Detect strictcli usage, extract CLI structure via AST, generate Markdown CLI reference pages, and preserve handwritten frontmatter descriptions.
#selfdoc.strictcli_support
#selfdoc.strictcli_support
First-class support for strictcli-based projects.
Reads .strictcli/schema.json (generated by <app> --dump-schema) for CLI structure (App, commands, flags, args, groups), and produces Markdown documentation pages.
#_normalize_cli_description
def _normalize_cli_description(value)Strip surrounding whitespace and one layer of matching quotes.
#compute_default_cli_description
def compute_default_cli_description(kind, name, app_name, help_text)Return the machine-default description for a CLI page.
kind is "index", "command", or "group". When the page's help text is long enough (>= 50 chars) the default is the first sentence of the help; otherwise a long-form template naming the app and command is used. The index default is always the fixed long-form template.
#is_default_cli_description
def is_default_cli_description(value, *, kind, name=None, app_name='', help_text=None)Return True if value is a machine-generated default CLI description.
Recognizes every historical machine form so machine residue is reseeded rather than frozen as handwritten:
- the current first-sentence form (help >= 50 chars), or
- the long-form default template (help < 50 chars, or the index), or
- the historical
help[:155]truncation (with/without a trailing
ellipsis), or
- a >= 100-char prefix of the raw help (a truncated default from any
prior cut point).
An empty value counts as a machine default (a blank machine placeholder the caller should reseed). CLI machine text is derivable from the schema, so this is a live recompute -- no static set can cover the truncated prefix family.
#uses_strictcli
def uses_strictcli(source_paths, base_dir)Return True if the project has a .strictcli/schema.json file.
The source_paths parameter is accepted for call-site compatibility but is not used -- detection is purely based on the schema file.
#SchemaDiscoveryError
Raised when .strictcli/schema.json discovery fails or is ambiguous.
A hard error (exit 1). Subclasses RuntimeError so the CLI's existing RuntimeError handlers surface it with a clean message and non-zero exit.
#discover_schema_dirs
def discover_schema_dirs(base_dir)Discover directories containing a .strictcli/schema.json file.
Walks base_dir, pruning vendored/build directories and hidden directories (leading .). For every visited directory, checks whether it holds a .strictcli/schema.json and records its path relative to base_dir (the project root uses ".").
Returns a sorted list of relative directory paths (each is the directory that contains the .strictcli folder, i.e. the value a schema-dir attribute would take).
#read_schema_json
def read_schema_json(base_dir, source_paths=None)Read .strictcli/schema.json and translate to the internal format.
Returns a dict with app_name, app_version, app_help, global_flags (list), infra (dict), deprecated (dict), commands (list), and groups (list) -- or None if the schema file does not exist.
The translation preserves new fields from the schema (choices, hidden, deprecated, variadic, passthrough, repeatable, negatable) so downstream consumers can use them, plus the effects-regime per-command fields (effect, consequential, grants, dry_run_supported, dry_run_unsupported_reason), which pass through untouched.
strictcli omits the app-level global_flags/infra/deprecated keys when they are empty, and some emitters write an explicit null; both normalize to empty containers so renderers can truth-test them.
#_translate_command
def _translate_command(name, cmd)Translate a schema command dict to the internal format.
#_translate_group
def _translate_group(name, grp)Translate a schema group dict to the internal format.
#extract_cli_structure
def extract_cli_structure(source_paths, base_dir)Read the CLI structure from .strictcli/schema.json.
Returns a dict describing the app, its commands, flags, args, and groups -- or raises FileNotFoundError if no schema is found.
The source_paths parameter is accepted for call-site compatibility but is not used.
#expected_cli_page_filenames
def expected_cli_page_filenames(cli_structure)Return the list of filenames generate_cli_pages would write.
Used by the stale-file cleanup pass to know which CLI page names are "current" so the generated pages from a prior run are not deleted as stale before the new pages have been written.
#_read_existing_cli_description
def _read_existing_cli_description(filepath, *, kind, name, app_name, help_text=None)Return the hand-edited description from a CLI page, else None.
Returns None (meaning: reseed with the machine default) if the file does not exist, has no description key, has an empty description, or still holds a machine-generated default (recognized by :func:is_default_cli_description). Any other value is a genuine hand edit and is returned verbatim.
#generate_cli_pages
def generate_cli_pages(cli_structure, docs_dir)Generate Markdown documentation pages from cli_structure.
Creates an index page and one page per top-level command group. All pages have generated: true frontmatter and read-only permissions (0o444).
Returns a list of generated filenames (relative to docs_dir).
#_write_page
def _write_page(filepath, content)Write a generated page atomically with read-only permissions.
#_schema_has_effects
def _schema_has_effects(cli_structure)Return True if any command in cli_structure declares an effect.
Classification is mandatory under the effects regime, so a single effect field anywhere proves the app is built on a strictcli that owns the reserved quartet.
#_fmt_default
def _fmt_default(value)Format a flag default for table display.
Falsy defaults (None, False, 0, "") render as an empty cell. Structured defaults -- strictcli's relative_to_root form, for instance -- render as compact JSON rather than a Python repr.
#_flag_table
def _flag_table(flags)Render the standard flag table for a list of schema flags.
#_arg_table
def _arg_table(args)Render the standard argument table for a list of schema args.
#_command_meta_lines
def _command_meta_lines(cmd)Return the effect badge and dry-run refusal lines for one command.
Empty for a pre-effects schema: effect is mandatory under the effects regime, so its absence means the app predates the regime and there is nothing honest to print.
#_grants_lines
def _grants_lines(cmd, heading)Return the grants table lines for one command, or an empty list.
#_env_table
def _env_table(entries, description_header)Render an infra env-var table (env_var plus one other column).
#_render_command_page
def _render_command_page(cmd, app_name, nav_order, existing_path=None)Render a Markdown page for a single command.
If existing_path points to an existing page whose description frontmatter has been hand-edited (i.e. is neither the current default -- the complete first sentence of the help -- nor a historical help[:155] truncation nor the long-form default template), that description is preserved instead of recomputing it.
#_render_group_page
def _render_group_page(grp, app_name, nav_order, existing_path=None)Render a Markdown page for a command group and its subcommands.
If existing_path points to an existing page whose description frontmatter has been hand-edited (i.e. is neither the current default -- the complete first sentence of the help -- nor a historical help[:155] truncation nor the long-form default template), that description is preserved instead of recomputing it.
#_fmt_short
def _fmt_short(short)Format a short flag for table display.