{
  "topic": "cli.help",
  "path": [
    "cli",
    "help"
  ],
  "title": "cyoda help — the help subsystem",
  "synopsis": "`cyoda help` is the built-in documentation browser. Topics are organized in a dot-separated tree (`cli`, `cli.serve`, `config.database`, etc.). Invoking `cyoda help` with no arguments prints a summary of all top-level topics. Invoking it with one or more topic segments navigates the tree.",
  "body": "# cli.help\n\n## NAME\n\ncli.help — the cyoda help subsystem and topic-tree contract.\n\n## SYNOPSIS\n\n`cyoda help [<topic>...] [--format=<fmt>]`\n\n## DESCRIPTION\n\n`cyoda help` is the built-in documentation browser. Topics are organized in a dot-separated tree (`cli`, `cli.serve`, `config.database`, etc.). Invoking `cyoda help` with no arguments prints a summary of all top-level topics. Invoking it with one or more topic segments navigates the tree.\n\nThe help content is embedded in the binary at build time — no network access or external files are needed.\n\nRelease archives include a pre-rendered `help/` directory for offline reference.\n\n## OPTIONS\n\n- `--format=<auto|text|markdown|json>` — Default `auto` selects text on a TTY and markdown off-TTY.\n\n## TOPIC ACTIONS\n\nSome topics publish machine-readable actions invoked as `cyoda help <topic> <action>`. Actions emit raw content to stdout without rendering the help body.\n\nThe `cyoda help` top-level summary lists topics that have actions registered. Each topic's render output includes an `ACTIONS` footer enumerating its actions. The JSON payload of `cyoda help <topic> --format=json` carries an `actions` array of the same names.\n\nActions do not accept `--format` (that flag governs the help body's output form, not action emission).\n\n## REST API\n\nThe same topic tree is served over HTTP on the running server. No authentication is required — help content is public. Responses are machine-parseable (`application/json` for topic payloads, `application/problem+json` for errors).\n\n### Endpoints\n\n- `GET {CYODA_CONTEXT_PATH}/help` — returns the full topic tree as a `HelpPayload` JSON document.\n- `GET {CYODA_CONTEXT_PATH}/help/{topic}` — returns a single `TopicDescriptor` JSON document for the addressed topic.\n\n`CYODA_CONTEXT_PATH` defaults to `/api`. Both mount points are relative to the configured context path.\n\n### Methods\n\nOnly `GET` is accepted by the help handler. CORS preflights (`OPTIONS`) are handled by the unified middleware before reaching this handler. Any other method (`POST`, `PUT`, `DELETE`, `PATCH`) returns `405 Method Not Allowed` with header `Allow: GET` and a `BAD_REQUEST` error body (`application/problem+json`).\n\n### Topic path syntax\n\n`{topic}` uses either the canonical **dotted** form (`errors.VALIDATION_FAILED`, `cli.serve`) or the **slash** form (`errors/VALIDATION_FAILED`, `cli/serve`). Both resolve to the same topic. The dotted form matches the identifier used in the JSON payload (`topic`, `see_also`, `children` fields); the slash form is a REST-idiomatic hierarchy. Mixed separators in a single path (e.g. `cli.serve/examples`) are also accepted.\n\nValid path characters: `[A-Za-z0-9._/-]+`, starting and ending with alphanumeric. A path with any other character (including URL-encoded spaces `%20`) returns `400 BAD_REQUEST`. An empty path segment (leading separator, trailing separator, or double separator) also returns `400`.\n\nURL-encoded slash (`%2F`) is decoded to a literal `/` by the HTTP stack and treated as a separator — so `GET /api/help/cli%2Fhelp` is equivalent to `GET /api/help/cli/help`.\n\nNote: consecutive slashes (e.g. `cli//help`) are cleaned to a single slash by Go's HTTP stack before the handler runs, so `cli//help` resolves the same as `cli/help`. This is analogous to how a bare `.` path segment redirects to the parent.\n\n### Response — full tree\n\n`GET {CYODA_CONTEXT_PATH}/help` returns a `HelpPayload` object.\n\n```json\n{\n  \"schema\": 1,\n  \"version\": \"0.6.1\",\n  \"topics\": [\n    {\n      \"topic\": \"cli.help\",\n      \"path\": [\"cli\", \"help\"],\n      \"title\": \"cyoda help — the help subsystem\",\n      \"synopsis\": \"the cyoda help subsystem and topic-tree contract.\",\n      \"body\": \"# cli.help\\n\\n## NAME\\n\\n...\",\n      \"sections\": [\n        { \"name\": \"NAME\", \"body\": \"cli.help — the cyoda help subsystem and topic-tree contract.\" },\n        { \"name\": \"SYNOPSIS\", \"body\": \"`cyoda help [<topic>...] [--format=<fmt>]`\" }\n      ],\n      \"see_also\": [\"cli\"],\n      \"stability\": \"stable\",\n      \"actions\": [],\n      \"children\": []\n    }\n  ]\n}\n```\n\n`HelpPayload` fields:\n\n- `schema` (integer) — payload schema version. Currently `1`. Consumers must check this before parsing; a higher value signals additive fields were added.\n- `version` (string) — ldflag-injected binary version string (e.g. `\"0.6.1\"`).\n- `topics` (array of `TopicDescriptor`) — every topic in the tree, in walk order.\n\n### Response — single topic\n\n`GET {CYODA_CONTEXT_PATH}/help/{topic}` returns a `TopicDescriptor` object.\n\n```json\n{\n  \"topic\": \"cli.help\",\n  \"path\": [\"cli\", \"help\"],\n  \"title\": \"cyoda help — the help subsystem\",\n  \"synopsis\": \"the cyoda help subsystem and topic-tree contract.\",\n  \"body\": \"# cli.help\\n\\n## NAME\\n\\ncli.help — the cyoda help subsystem and topic-tree contract.\\n\\n...\",\n  \"sections\": [\n    { \"name\": \"NAME\", \"body\": \"cli.help — the cyoda help subsystem and topic-tree contract.\" },\n    { \"name\": \"SYNOPSIS\", \"body\": \"`cyoda help [<topic>...] [--format=<fmt>]`\" },\n    { \"name\": \"DESCRIPTION\", \"body\": \"...\" },\n    { \"name\": \"OPTIONS\", \"body\": \"...\" },\n    { \"name\": \"STABILITY\", \"body\": \"...\" },\n    { \"name\": \"EXAMPLES\", \"body\": \"...\" },\n    { \"name\": \"SEE ALSO\", \"body\": \"...\" }\n  ],\n  \"see_also\": [\"cli\"],\n  \"stability\": \"stable\",\n  \"actions\": [],\n  \"children\": [\"cli.help\"]\n}\n```\n\n`TopicDescriptor` fields:\n\n- `topic` (string) — canonical dotted path (e.g. `\"cli.help\"`).\n- `path` (array of strings) — topic path split into segments (e.g. `[\"cli\", \"help\"]`).\n- `title` (string) — topic title from the front-matter `title:` field.\n- `synopsis` (string) — single-line description extracted from the NAME or DESCRIPTION section; inline markers stripped, whitespace collapsed.\n- `body` (string) — full raw markdown source of the topic file.\n- `sections` (array of objects) — H2-delimited blocks; each object has `name` (string, the H2 heading text) and `body` (string, everything between this H2 and the next H2 or end-of-file, trimmed).\n- `see_also` (array of strings) — dotted topic paths from the front-matter `see_also:` list.\n- `stability` (string) — one of `\"stable\"`, `\"evolving\"`, or `\"experimental\"`.\n- `actions` (array of strings) — names of machine-readable actions the topic supports; empty array when none.\n- `children` (array of strings, omitted when empty) — dotted paths of direct child topics.\n\n### Errors\n\nErrors use RFC 9457 Problem Details (`application/problem+json`). See `errors` topic for the full envelope shape.\n\n- `400 BAD_REQUEST` — the `{topic}` path segment contains disallowed characters (fails `^[A-Za-z0-9]([A-Za-z0-9._/-]*[A-Za-z0-9])?$`), or contains an empty segment (leading/trailing separator, double separator). Also returned for any method other than `GET` (with `Allow: GET` response header).\n- `404 HELP_TOPIC_NOT_FOUND` — the `{topic}` is well-formed but does not resolve to any topic in the tree.\n\n### Examples\n\n```bash\n# Fetch the full topic tree and inspect schema version and binary version\ncurl -s http://localhost:8080/api/help | jq '{schema: .schema, version: .version}'\n\n# Fetch a single topic — dotted form (canonical)\ncurl -s http://localhost:8080/api/help/cli.serve | jq .topic\n\n# Fetch the same topic — slash form (REST-idiomatic, equivalent)\ncurl -s http://localhost:8080/api/help/cli/serve | jq .topic\n\n# Mixed separators also resolve (e.g. errors.VALIDATION_FAILED via slash)\ncurl -s http://localhost:8080/api/help/errors/VALIDATION_FAILED | jq .topic\n\n# Fetch a single topic and extract its registered actions\ncurl -s http://localhost:8080/api/help/cli.help | jq '.actions'\n\n# Fetch an unknown topic — observe the 404 HELP_TOPIC_NOT_FOUND body\ncurl -s -w \"\\nHTTP %{http_code}\\n\" http://localhost:8080/api/help/no.such.topic\n\n# Send a disallowed method and confirm 405 with Allow header\ncurl -si -X POST http://localhost:8080/api/help | grep -E \"^HTTP|^Allow:\"\n```\n\n### CORS\n\nCORS is configured globally — see `config.cors` for the full env-var reference and deployment guidance.\n\n## STABILITY\n\nTopic additions are non-breaking. Renaming or removing a topic requires a deprecation window and an entry in CONTRIBUTING.md. Topic paths are stable for the duration of a major version.\n\n## EXAMPLES\n\n```\n# Show all top-level topics\ncyoda help\n\n# Show the cli topic\ncyoda help cli\n\n# Show the serve subtopic\ncyoda help cli serve\n\n# Output JSON for the full topic tree\ncyoda help --format=json\n\n# Output JSON for a single topic\ncyoda help --format=json cli serve\n```\n\n## SEE ALSO\n\n- cli\n",
  "sections": [
    {
      "name": "NAME",
      "body": "cli.help — the cyoda help subsystem and topic-tree contract."
    },
    {
      "name": "SYNOPSIS",
      "body": "`cyoda help [<topic>...] [--format=<fmt>]`"
    },
    {
      "name": "DESCRIPTION",
      "body": "`cyoda help` is the built-in documentation browser. Topics are organized in a dot-separated tree (`cli`, `cli.serve`, `config.database`, etc.). Invoking `cyoda help` with no arguments prints a summary of all top-level topics. Invoking it with one or more topic segments navigates the tree.\n\nThe help content is embedded in the binary at build time — no network access or external files are needed.\n\nRelease archives include a pre-rendered `help/` directory for offline reference."
    },
    {
      "name": "OPTIONS",
      "body": "- `--format=<auto|text|markdown|json>` — Default `auto` selects text on a TTY and markdown off-TTY."
    },
    {
      "name": "TOPIC ACTIONS",
      "body": "Some topics publish machine-readable actions invoked as `cyoda help <topic> <action>`. Actions emit raw content to stdout without rendering the help body.\n\nThe `cyoda help` top-level summary lists topics that have actions registered. Each topic's render output includes an `ACTIONS` footer enumerating its actions. The JSON payload of `cyoda help <topic> --format=json` carries an `actions` array of the same names.\n\nActions do not accept `--format` (that flag governs the help body's output form, not action emission)."
    },
    {
      "name": "REST API",
      "body": "The same topic tree is served over HTTP on the running server. No authentication is required — help content is public. Responses are machine-parseable (`application/json` for topic payloads, `application/problem+json` for errors).\n\n### Endpoints\n\n- `GET {CYODA_CONTEXT_PATH}/help` — returns the full topic tree as a `HelpPayload` JSON document.\n- `GET {CYODA_CONTEXT_PATH}/help/{topic}` — returns a single `TopicDescriptor` JSON document for the addressed topic.\n\n`CYODA_CONTEXT_PATH` defaults to `/api`. Both mount points are relative to the configured context path.\n\n### Methods\n\nOnly `GET` is accepted by the help handler. CORS preflights (`OPTIONS`) are handled by the unified middleware before reaching this handler. Any other method (`POST`, `PUT`, `DELETE`, `PATCH`) returns `405 Method Not Allowed` with header `Allow: GET` and a `BAD_REQUEST` error body (`application/problem+json`).\n\n### Topic path syntax\n\n`{topic}` uses either the canonical **dotted** form (`errors.VALIDATION_FAILED`, `cli.serve`) or the **slash** form (`errors/VALIDATION_FAILED`, `cli/serve`). Both resolve to the same topic. The dotted form matches the identifier used in the JSON payload (`topic`, `see_also`, `children` fields); the slash form is a REST-idiomatic hierarchy. Mixed separators in a single path (e.g. `cli.serve/examples`) are also accepted.\n\nValid path characters: `[A-Za-z0-9._/-]+`, starting and ending with alphanumeric. A path with any other character (including URL-encoded spaces `%20`) returns `400 BAD_REQUEST`. An empty path segment (leading separator, trailing separator, or double separator) also returns `400`.\n\nURL-encoded slash (`%2F`) is decoded to a literal `/` by the HTTP stack and treated as a separator — so `GET /api/help/cli%2Fhelp` is equivalent to `GET /api/help/cli/help`.\n\nNote: consecutive slashes (e.g. `cli//help`) are cleaned to a single slash by Go's HTTP stack before the handler runs, so `cli//help` resolves the same as `cli/help`. This is analogous to how a bare `.` path segment redirects to the parent.\n\n### Response — full tree\n\n`GET {CYODA_CONTEXT_PATH}/help` returns a `HelpPayload` object.\n\n```json\n{\n  \"schema\": 1,\n  \"version\": \"0.6.1\",\n  \"topics\": [\n    {\n      \"topic\": \"cli.help\",\n      \"path\": [\"cli\", \"help\"],\n      \"title\": \"cyoda help — the help subsystem\",\n      \"synopsis\": \"the cyoda help subsystem and topic-tree contract.\",\n      \"body\": \"# cli.help\\n\\n## NAME\\n\\n...\",\n      \"sections\": [\n        { \"name\": \"NAME\", \"body\": \"cli.help — the cyoda help subsystem and topic-tree contract.\" },\n        { \"name\": \"SYNOPSIS\", \"body\": \"`cyoda help [<topic>...] [--format=<fmt>]`\" }\n      ],\n      \"see_also\": [\"cli\"],\n      \"stability\": \"stable\",\n      \"actions\": [],\n      \"children\": []\n    }\n  ]\n}\n```\n\n`HelpPayload` fields:\n\n- `schema` (integer) — payload schema version. Currently `1`. Consumers must check this before parsing; a higher value signals additive fields were added.\n- `version` (string) — ldflag-injected binary version string (e.g. `\"0.6.1\"`).\n- `topics` (array of `TopicDescriptor`) — every topic in the tree, in walk order.\n\n### Response — single topic\n\n`GET {CYODA_CONTEXT_PATH}/help/{topic}` returns a `TopicDescriptor` object.\n\n```json\n{\n  \"topic\": \"cli.help\",\n  \"path\": [\"cli\", \"help\"],\n  \"title\": \"cyoda help — the help subsystem\",\n  \"synopsis\": \"the cyoda help subsystem and topic-tree contract.\",\n  \"body\": \"# cli.help\\n\\n## NAME\\n\\ncli.help — the cyoda help subsystem and topic-tree contract.\\n\\n...\",\n  \"sections\": [\n    { \"name\": \"NAME\", \"body\": \"cli.help — the cyoda help subsystem and topic-tree contract.\" },\n    { \"name\": \"SYNOPSIS\", \"body\": \"`cyoda help [<topic>...] [--format=<fmt>]`\" },\n    { \"name\": \"DESCRIPTION\", \"body\": \"...\" },\n    { \"name\": \"OPTIONS\", \"body\": \"...\" },\n    { \"name\": \"STABILITY\", \"body\": \"...\" },\n    { \"name\": \"EXAMPLES\", \"body\": \"...\" },\n    { \"name\": \"SEE ALSO\", \"body\": \"...\" }\n  ],\n  \"see_also\": [\"cli\"],\n  \"stability\": \"stable\",\n  \"actions\": [],\n  \"children\": [\"cli.help\"]\n}\n```\n\n`TopicDescriptor` fields:\n\n- `topic` (string) — canonical dotted path (e.g. `\"cli.help\"`).\n- `path` (array of strings) — topic path split into segments (e.g. `[\"cli\", \"help\"]`).\n- `title` (string) — topic title from the front-matter `title:` field.\n- `synopsis` (string) — single-line description extracted from the NAME or DESCRIPTION section; inline markers stripped, whitespace collapsed.\n- `body` (string) — full raw markdown source of the topic file.\n- `sections` (array of objects) — H2-delimited blocks; each object has `name` (string, the H2 heading text) and `body` (string, everything between this H2 and the next H2 or end-of-file, trimmed).\n- `see_also` (array of strings) — dotted topic paths from the front-matter `see_also:` list.\n- `stability` (string) — one of `\"stable\"`, `\"evolving\"`, or `\"experimental\"`.\n- `actions` (array of strings) — names of machine-readable actions the topic supports; empty array when none.\n- `children` (array of strings, omitted when empty) — dotted paths of direct child topics.\n\n### Errors\n\nErrors use RFC 9457 Problem Details (`application/problem+json`). See `errors` topic for the full envelope shape.\n\n- `400 BAD_REQUEST` — the `{topic}` path segment contains disallowed characters (fails `^[A-Za-z0-9]([A-Za-z0-9._/-]*[A-Za-z0-9])?$`), or contains an empty segment (leading/trailing separator, double separator). Also returned for any method other than `GET` (with `Allow: GET` response header).\n- `404 HELP_TOPIC_NOT_FOUND` — the `{topic}` is well-formed but does not resolve to any topic in the tree.\n\n### Examples\n\n```bash\n# Fetch the full topic tree and inspect schema version and binary version\ncurl -s http://localhost:8080/api/help | jq '{schema: .schema, version: .version}'\n\n# Fetch a single topic — dotted form (canonical)\ncurl -s http://localhost:8080/api/help/cli.serve | jq .topic\n\n# Fetch the same topic — slash form (REST-idiomatic, equivalent)\ncurl -s http://localhost:8080/api/help/cli/serve | jq .topic\n\n# Mixed separators also resolve (e.g. errors.VALIDATION_FAILED via slash)\ncurl -s http://localhost:8080/api/help/errors/VALIDATION_FAILED | jq .topic\n\n# Fetch a single topic and extract its registered actions\ncurl -s http://localhost:8080/api/help/cli.help | jq '.actions'\n\n# Fetch an unknown topic — observe the 404 HELP_TOPIC_NOT_FOUND body\ncurl -s -w \"\\nHTTP %{http_code}\\n\" http://localhost:8080/api/help/no.such.topic\n\n# Send a disallowed method and confirm 405 with Allow header\ncurl -si -X POST http://localhost:8080/api/help | grep -E \"^HTTP|^Allow:\"\n```\n\n### CORS\n\nCORS is configured globally — see `config.cors` for the full env-var reference and deployment guidance."
    },
    {
      "name": "STABILITY",
      "body": "Topic additions are non-breaking. Renaming or removing a topic requires a deprecation window and an entry in CONTRIBUTING.md. Topic paths are stable for the duration of a major version."
    },
    {
      "name": "EXAMPLES",
      "body": "```\n# Show all top-level topics\ncyoda help\n\n# Show the cli topic\ncyoda help cli\n\n# Show the serve subtopic\ncyoda help cli serve\n\n# Output JSON for the full topic tree\ncyoda help --format=json\n\n# Output JSON for a single topic\ncyoda help --format=json cli serve\n```"
    },
    {
      "name": "SEE ALSO",
      "body": "- cli"
    }
  ],
  "see_also": [
    "cli"
  ],
  "stability": "stable",
  "actions": []
}
