afslug CLI reference

Generate and validate slugs with explicit agent-first-slug rules.

afslug is compiled from a closed cli-spec-v1 registry: one source for argv parsing, typed invocation values, which parameter combinations are legal, output contracts, and help. An invocation runs only when it matches exactly one registered combination.

Global arguments

AFDATA registers these itself, so the syntax in Commands leaves them out.

ArgumentWhereWhat it does
--helpevery commandEvery legal shape of that command, complete, plus its subcommands. JSON by default; --output plain for a terminal.
--versionafslug onlyName, version, and build identity as one protocol result.
--docsafslug onlyThis document, rendered from the registry.
--output <FORMAT>per output contractRender as json, yaml, plain (default json).
--output-to <DESTINATION>per output contractRoute results and diagnostics to split, stdout, stderr (default split).
--stdout-file <PATH>, --stderr-file <PATH>per output contractAppend that stream to a file instead.

Success output is protocol events, on those terms, unless a command’s own Output line says otherwise.

A shape is one legal set of arguments that may appear together, under a stable id. Where a command has more than one, each id is a heading below. --help returns them all at once, so discovering a command costs one call; there is no recursive mode across commands, and this document is that view.

Commands

afslug skill install

Install the Agent-First Slug skill.

skill-install-every-agent — Target every agent that supports the scope

afslug skill install [--agent all] [--scope <personal|workspace>] [--force]

skill-install-one-agent — Target one named agent; only this shape accepts –skills-dir

afslug skill install --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>] [--force]

Arguments across every shape above:

ArgumentMeaning
--agentAgent to manage
--scopeSkill scope
--skills-dirDirectory that contains skill folders
--forceOverwrite or remove an unmanaged Agent-First Slug skill at the target path

afslug skill status

Show whether the Agent-First Slug skill is installed, valid, and up to date.

skill-status-every-agent — Target every agent that supports the scope

afslug skill status [--agent all] [--scope <personal|workspace>]

skill-status-one-agent — Target one named agent; only this shape accepts –skills-dir

afslug skill status --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>]

Arguments across every shape above:

ArgumentMeaning
--agentAgent to manage
--scopeSkill scope
--skills-dirDirectory that contains skill folders

afslug skill uninstall

Remove an afslug-managed Agent-First Slug skill.

skill-uninstall-every-agent — Target every agent that supports the scope

afslug skill uninstall [--agent all] [--scope <personal|workspace>] [--force]

skill-uninstall-one-agent — Target one named agent; only this shape accepts –skills-dir

afslug skill uninstall --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>] [--force]

Arguments across every shape above:

ArgumentMeaning
--agentAgent to manage
--scopeSkill scope
--skills-dirDirectory that contains skill folders
--forceOverwrite or remove an unmanaged Agent-First Slug skill at the target path

afslug slugify

Generate a slug from input text.

afslug slugify <TEXT> [--delimiter <CHAR>] [--no-lowercase] [--max-chars <N>] [--charset <unicode-alphanumeric|ascii-alphanumeric|unicode-letters-digits>] [--dots <replace|preserve|preserve-between-digits>] [--validation <none|local-path|url-path>] [--fallback <SLUG>] [--fallback-verbatim <SLUG>]
ArgumentMeaning
TEXTText to slugify
--delimiterDelimiter inserted for each run of filtered characters
--no-lowercaseKeep the original case instead of lowercasing the slug
--max-charsCap the slug to at most N Unicode characters
--charsetCharacter set kept from the input after filtering
--dotsHow input dots are handled before other characters become delimiters
--validationValidation applied to the generated slug
--fallbackSlug substituted when the generated slug would otherwise be empty; must satisfy the same character set, delimiter, dot, case and length rules
--fallback-verbatimSame, inserted exactly as written for a value that must match something already stored; only the –validation surface is checked

afslug validate

Validate an existing value as a path segment.

afslug validate <VALUE> [--policy <local-path|url-path>]
ArgumentMeaning
VALUEValue to validate as a path segment
--policyPath-segment kind to validate against

Exit codes

CodeMeaning
0The command ran and succeeded.
1The command ran and failed. The event carries a domain error.code.
2The invocation was rejected before anything ran. error.code is one of the cli_* codes below.

The split is the useful one for a caller: exit 2 means the call was never made, so retrying it unchanged cannot help, while exit 1 means it was.

CLI errors

Every structural failure emits one strict JSON kind:"error" event on stderr, leaves stdout empty, and exits 2. The code names the failure — cli_unknown_argument for an unknown spelling, cli_unregistered_combination for registered arguments in a mixture that is not, and one each for cli_unknown_command, cli_missing_argument_value, cli_invalid_argument_value, cli_duplicate_argument, cli_unexpected_positional, and cli_invalid_utf8. message identifies a safe argument spelling or the failure category and hint gives the command to run next; neither ever quotes a raw value, including secrets. These are decided before any config, secret source, filesystem, network, or domain I/O.

Two exit-1 codes describe the tool itself rather than the call: cli_invocation_invalid means the program misread its own resolved invocation — an unknown action id, or an argument id the selected combination cannot produce — and output_setup_failed means an output sink (--stdout-file, --stderr-file, stream redirection) could not be established. Both are defects to report, not inputs to correct; retrying the same command cannot help.

Domain failures (exit 1) carry their own stable error.code instead, drawn from whatever this tool defines rather than from the cli_* set. Error events are routinely logged, so a message never quotes a value that came from an argument able to carry a credential — a header, a cookie, a token, a password, a proxy URL, an environment value, a form field. Such an error names the argument and the shape that was wrong, and stops there. A value that cannot be a secret — a path, a dot-path, a session name — is quoted, because an error that cannot say which one it means is not worth logging either.