{
  "$schema": "https://docspack.dev/cmdspec/schema/v0.1.json",
  "cmdspec": "0.1",
  "info": {
    "name": "narro",
    "summary": "CLI for Narro presentations",
    "version": "0.12.1",
    "bin": "narro",
    "homepage": "https://getnarro.com/docs/cli",
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    },
    "description": "Builds, checks and exports Narro decks — one markdown file, or a Vite project of React slides.\n\nThe binary is `narro`, from the npm package `@getnarro/cli`. Without a global install, run it as `npx @getnarro/cli <command>`: `npx narro` resolves an unrelated package."
  },
  "options": [
    {
      "name": "--version",
      "aliases": [
        "-V"
      ],
      "summary": "output the version number",
      "inherited": true
    },
    {
      "name": "--cmdspec",
      "summary": "print this program's cmdspec document as JSON, and exit",
      "inherited": true,
      "description": "Prints the cmdspec document — every command, option, effect and exit status — and exits 0. The same document ships in the package as `dist/cmdspec.json`."
    },
    {
      "name": "--help",
      "aliases": [
        "-h"
      ],
      "summary": "display help for command",
      "inherited": true
    }
  ],
  "commands": [
    {
      "name": "create",
      "summary": "Create a new Narro presentation project",
      "arguments": [
        {
          "name": "project-name",
          "summary": "Name of the project to create"
        }
      ],
      "options": [
        {
          "name": "--version",
          "aliases": [
            "-V"
          ],
          "summary": "output the version number"
        },
        {
          "name": "--template",
          "aliases": [
            "-t"
          ],
          "summary": "Template to use (minimal, corporate, developer, creative, bold-statement, visual-story, data-narrative, startup-pitch, tech-conference, template0, markdown-minimal, markdown-app, markdown-docs)",
          "value": {
            "name": "template"
          }
        },
        {
          "name": "--mode",
          "aliases": [
            "-m"
          ],
          "summary": "Presentation mode: react (default) or markdown",
          "value": {
            "name": "mode"
          }
        },
        {
          "name": "--skip-install",
          "summary": "Skip npm install",
          "effects": [
            "write"
          ]
        },
        {
          "name": "--yes",
          "aliases": [
            "-y"
          ],
          "summary": "Accept the defaults for anything not given; never prompt"
        },
        {
          "name": "--force",
          "summary": "Scaffold into a directory that already has files in it"
        },
        {
          "name": "--list",
          "summary": "List every template with what it is, and exit",
          "effects": []
        }
      ],
      "effects": [
        "write",
        "network",
        "exec"
      ],
      "interactive": {
        "when": "tty",
        "disable": "--yes"
      },
      "examples": [
        {
          "run": "narro create my-talk --template markdown-minimal --yes"
        },
        {
          "run": "narro create --list",
          "summary": "Every template, with what it is"
        }
      ]
    },
    {
      "name": "dev",
      "summary": "Start development server (pass a .md file for markdown mode)",
      "arguments": [
        {
          "name": "file",
          "summary": "path to a markdown deck to serve directly"
        }
      ],
      "options": [
        {
          "name": "--port",
          "aliases": [
            "-p"
          ],
          "summary": "port to use",
          "value": {
            "name": "number",
            "default": 3000,
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          }
        },
        {
          "name": "--host",
          "summary": "expose to network"
        },
        {
          "name": "--open",
          "aliases": [
            "-o"
          ],
          "summary": "open browser on startup",
          "negation": [
            "--no-open"
          ]
        },
        {
          "name": "--theme",
          "summary": "theme override (markdown mode)",
          "value": {
            "name": "name"
          }
        }
      ],
      "effects": [
        "read",
        "network"
      ],
      "longRunning": true,
      "examples": [
        {
          "run": "narro dev deck.md",
          "summary": "Serve one markdown deck with live reload"
        },
        {
          "run": "narro dev --port 3001",
          "summary": "Serve a React project"
        }
      ]
    },
    {
      "name": "build",
      "summary": "Build for production (pass a .md file for markdown mode)",
      "arguments": [
        {
          "name": "file",
          "summary": "path to a markdown deck to build directly"
        }
      ],
      "options": [
        {
          "name": "--outDir",
          "aliases": [
            "-o"
          ],
          "summary": "output directory",
          "value": {
            "name": "dir",
            "default": "dist"
          }
        },
        {
          "name": "--base",
          "summary": "base path for deployment",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--no-fit",
          "summary": "skip the overflow measurement after building",
          "effects": [
            "read",
            "write"
          ]
        }
      ],
      "effects": [
        "read",
        "write",
        "exec"
      ],
      "idempotent": true,
      "description": "With a .md file, builds that deck to a static site and then measures every slide for overflow in a headless browser, failing when one overflows. Without one, builds the React project in the working directory.",
      "exits": {
        "1": {
          "meaning": "the build failed, or a slide overflows (markdown mode)"
        }
      },
      "examples": [
        {
          "run": "narro build deck.md"
        },
        {
          "run": "narro build deck.md --outDir site --base /talks/q3/"
        }
      ]
    },
    {
      "name": "new",
      "summary": "Scaffold a starter markdown deck",
      "arguments": [
        {
          "name": "file",
          "summary": "path to the new deck file (e.g. deck.md)",
          "required": true
        }
      ],
      "effects": [
        "write"
      ],
      "examples": [
        {
          "run": "narro new deck.md"
        }
      ]
    },
    {
      "name": "check",
      "summary": "Validate a markdown deck, or measure built output with --fit",
      "arguments": [
        {
          "name": "file|dir",
          "summary": "path to the deck file (e.g. deck.md), or a built dist/ directory",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--strict",
          "summary": "treat warnings as errors"
        },
        {
          "name": "--render",
          "summary": "print what each slide renders — elements, classes, and text"
        },
        {
          "name": "--fit",
          "summary": "render the deck in a headless browser and report slides whose content overflows",
          "effects": [
            "read",
            "exec"
          ]
        },
        {
          "name": "--fit-if-available",
          "summary": "like --fit, but only warn when no browser is installed",
          "effects": [
            "read",
            "exec"
          ]
        },
        {
          "name": "--render-full",
          "summary": "like --render, but print long text and large props in full"
        }
      ],
      "effects": [
        "read"
      ],
      "idempotent": true,
      "description": "The fast loop. Resolves every layout, slot, theme, component and frontmatter name in a markdown deck, and names the ones that do not exist along with what would have worked. Given a built directory and --fit, measures it instead — the only check React mode has.",
      "exits": {
        "1": {
          "meaning": "the deck has errors, warnings under --strict, or slides that overflow under --fit"
        }
      },
      "io": {
        "stdout": [
          {
            "mediaType": "text/plain",
            "summary": "the problems found, each with a fix"
          }
        ]
      },
      "examples": [
        {
          "run": "narro check deck.md"
        },
        {
          "run": "narro check deck.md --strict --fit",
          "summary": "What CI should run"
        },
        {
          "run": "narro check deck.md --render",
          "summary": "See what each slide renders, no browser"
        },
        {
          "run": "narro check dist --fit",
          "summary": "Measure a built React project"
        }
      ]
    },
    {
      "name": "fmt",
      "summary": "Normalise a deck's whitespace and frontmatter without changing what it renders",
      "arguments": [
        {
          "name": "file",
          "summary": "path to the deck file (e.g. deck.md)",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--check",
          "summary": "report whether the deck is formatted, and exit non-zero if not",
          "effects": [
            "read"
          ]
        }
      ],
      "effects": [
        "read",
        "write"
      ],
      "idempotent": true,
      "exits": {
        "1": {
          "meaning": "the deck could not be read, or is not formatted under --check"
        }
      },
      "examples": [
        {
          "run": "narro fmt deck.md"
        },
        {
          "run": "narro fmt deck.md --check"
        }
      ]
    },
    {
      "name": "export",
      "summary": "Export presentation to static files, PPTX, or Google Slides",
      "arguments": [
        {
          "name": "file",
          "summary": "path to a markdown deck to export directly"
        }
      ],
      "options": [
        {
          "name": "--outDir",
          "aliases": [
            "-o"
          ],
          "summary": "output directory for HTML export",
          "value": {
            "name": "dir",
            "default": "dist"
          }
        },
        {
          "name": "--pdf",
          "summary": "export to PDF (requires Playwright)"
        },
        {
          "name": "--png",
          "summary": "export slides as PNG images (requires Playwright)"
        },
        {
          "name": "--to",
          "summary": "export format: pptx, google-slides",
          "value": {
            "name": "format",
            "enum": [
              "pptx",
              "google-slides"
            ]
          }
        },
        {
          "name": "--output-path",
          "summary": "output file path for PPTX export",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--include-notes",
          "summary": "include speaker notes in export"
        },
        {
          "name": "--include-animations",
          "summary": "include animations in export"
        },
        {
          "name": "--settle",
          "summary": "milliseconds to let a slide's animations finish before capturing (default: 4000)",
          "value": {
            "name": "ms",
            "type": "integer",
            "minimum": 0
          }
        },
        {
          "name": "--input-path",
          "summary": "path to presentation project",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--template-path",
          "summary": "PowerPoint template file (.potx or .pptx) to apply",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--template-id",
          "summary": "Google Slides template presentation ID to copy from",
          "value": {
            "name": "id"
          }
        },
        {
          "name": "--google-client-id",
          "summary": "Google OAuth client ID",
          "value": {
            "name": "id"
          },
          "env": [
            "GOOGLE_CLIENT_ID"
          ]
        },
        {
          "name": "--google-client-secret",
          "summary": "Google OAuth client secret",
          "value": {
            "name": "secret"
          },
          "secret": true,
          "env": [
            "GOOGLE_CLIENT_SECRET"
          ]
        },
        {
          "name": "--google-refresh-token",
          "summary": "Google OAuth refresh token",
          "value": {
            "name": "token"
          },
          "secret": true,
          "env": [
            "GOOGLE_REFRESH_TOKEN"
          ]
        }
      ],
      "effects": [
        "read",
        "write",
        "exec",
        "network"
      ],
      "description": "PDF and PNG render in a headless browser and need Playwright. `--to google-slides` uploads to Google Drive and needs OAuth credentials; every other format stays on this machine.",
      "examples": [
        {
          "run": "narro export deck.md --pdf"
        },
        {
          "run": "narro export deck.md --png --outDir slides"
        },
        {
          "run": "narro export --to pptx --output-path talk.pptx"
        }
      ]
    },
    {
      "name": "import",
      "summary": "Import presentation from PowerPoint or Google Slides",
      "arguments": [
        {
          "name": "source",
          "summary": "source file path or Google Slides presentation ID/URL",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--from",
          "summary": "import source: pptx, google-slides",
          "value": {
            "name": "source",
            "enum": [
              "pptx",
              "google-slides"
            ]
          },
          "required": true
        },
        {
          "name": "--output-dir",
          "aliases": [
            "-o"
          ],
          "summary": "output directory for imported project",
          "value": {
            "name": "dir"
          }
        },
        {
          "name": "--preserve-styles",
          "summary": "preserve original styles"
        },
        {
          "name": "--convert-animations",
          "summary": "convert animations"
        },
        {
          "name": "--google-client-id",
          "summary": "Google OAuth client ID",
          "value": {
            "name": "id"
          },
          "env": [
            "GOOGLE_CLIENT_ID"
          ]
        },
        {
          "name": "--google-client-secret",
          "summary": "Google OAuth client secret",
          "value": {
            "name": "secret"
          },
          "secret": true,
          "env": [
            "GOOGLE_CLIENT_SECRET"
          ]
        },
        {
          "name": "--google-refresh-token",
          "summary": "Google OAuth refresh token",
          "value": {
            "name": "token"
          },
          "secret": true,
          "env": [
            "GOOGLE_REFRESH_TOKEN"
          ]
        }
      ],
      "effects": [
        "read",
        "write",
        "network"
      ],
      "examples": [
        {
          "run": "narro import talk.pptx --from pptx --output-dir talk"
        }
      ]
    },
    {
      "name": "preview",
      "summary": "Preview built presentation",
      "options": [
        {
          "name": "--port",
          "aliases": [
            "-p"
          ],
          "summary": "port to use",
          "value": {
            "name": "number",
            "default": 4173,
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          }
        },
        {
          "name": "--host",
          "summary": "expose to network"
        },
        {
          "name": "--open",
          "aliases": [
            "-o"
          ],
          "summary": "open browser on startup"
        },
        {
          "name": "--outDir",
          "aliases": [
            "-d"
          ],
          "summary": "serve a directory of built output directly",
          "value": {
            "name": "dir"
          }
        }
      ],
      "effects": [
        "read",
        "network"
      ],
      "longRunning": true,
      "examples": [
        {
          "run": "narro preview --outDir dist"
        }
      ]
    },
    {
      "name": "bundle",
      "summary": "Bundle presentation into a single self-contained HTML file",
      "options": [
        {
          "name": "--output",
          "aliases": [
            "-o"
          ],
          "summary": "output filename",
          "value": {
            "name": "filename",
            "default": "presentation.html"
          }
        },
        {
          "name": "--minify",
          "summary": "minify output for smaller file size"
        },
        {
          "name": "--inline-assets",
          "summary": "inline images as base64 (default: false)"
        },
        {
          "name": "--check-size",
          "summary": "warn if output exceeds email attachment limit (~25MB)"
        }
      ],
      "effects": [
        "read",
        "write",
        "exec"
      ],
      "examples": [
        {
          "run": "narro bundle --output talk.html --inline-assets"
        }
      ]
    },
    {
      "name": "themes",
      "summary": "Browse and apply themes from the marketplace",
      "commands": [
        {
          "name": "list",
          "summary": "List all available themes or color schemes",
          "options": [
            {
              "name": "--tags",
              "aliases": [
                "-t"
              ],
              "summary": "filter by tags (comma-separated)",
              "value": {
                "name": "tags"
              }
            },
            {
              "name": "--query",
              "aliases": [
                "-q"
              ],
              "summary": "search by name or description",
              "value": {
                "name": "query"
              }
            },
            {
              "name": "--color-schemes",
              "aliases": [
                "-c"
              ],
              "summary": "list color schemes instead of themes"
            }
          ],
          "effects": [
            "read"
          ],
          "idempotent": true,
          "examples": [
            {
              "run": "narro themes list"
            },
            {
              "run": "narro themes list --color-schemes"
            }
          ]
        },
        {
          "name": "info",
          "summary": "Get detailed information about a theme or color scheme",
          "arguments": [
            {
              "name": "id",
              "required": true
            }
          ],
          "effects": [
            "read"
          ],
          "idempotent": true,
          "examples": [
            {
              "run": "narro themes info ocean"
            }
          ]
        },
        {
          "name": "apply",
          "summary": "Apply a theme or color scheme to the current project",
          "arguments": [
            {
              "name": "id",
              "required": true
            }
          ],
          "options": [
            {
              "name": "--color-scheme",
              "aliases": [
                "-c"
              ],
              "summary": "apply as a color scheme (colors only)"
            }
          ],
          "effects": [
            "write"
          ],
          "idempotent": true,
          "examples": [
            {
              "run": "narro themes apply ocean"
            }
          ]
        },
        {
          "name": "help",
          "summary": "display help for command",
          "arguments": [
            {
              "name": "command"
            }
          ],
          "effects": [],
          "examples": [
            {
              "run": "narro themes help list"
            }
          ]
        }
      ],
      "subcommandRequired": true
    },
    {
      "name": "comments",
      "summary": "Manage slide comments",
      "commands": [
        {
          "name": "list",
          "summary": "List all comments in the presentation",
          "options": [
            {
              "name": "--slide-id",
              "aliases": [
                "-s"
              ],
              "summary": "filter by slide ID",
              "value": {
                "name": "id"
              }
            },
            {
              "name": "--author",
              "aliases": [
                "-a"
              ],
              "summary": "filter by author name",
              "value": {
                "name": "name"
              }
            },
            {
              "name": "--resolved",
              "aliases": [
                "-r"
              ],
              "summary": "filter by resolved status (true, false, all)",
              "value": {
                "name": "status",
                "default": "all",
                "enum": [
                  "true",
                  "false",
                  "all"
                ]
              }
            },
            {
              "name": "--format",
              "aliases": [
                "-f"
              ],
              "summary": "output format (table, json)",
              "value": {
                "name": "format",
                "default": "table",
                "enum": [
                  "table",
                  "json"
                ]
              }
            }
          ],
          "effects": [
            "read"
          ],
          "idempotent": true,
          "io": {
            "stdout": [
              {
                "mediaType": "text/plain",
                "summary": "a table of comments"
              },
              {
                "mediaType": "application/json",
                "selectedBy": "--format=json",
                "summary": "the comments"
              }
            ]
          },
          "examples": [
            {
              "run": "narro comments list --resolved false --format json"
            }
          ]
        },
        {
          "name": "add",
          "summary": "Add a new comment to a slide",
          "options": [
            {
              "name": "--slide-id",
              "aliases": [
                "-s"
              ],
              "summary": "slide ID to add comment to",
              "value": {
                "name": "id"
              },
              "required": true
            },
            {
              "name": "--author",
              "aliases": [
                "-a"
              ],
              "summary": "comment author name",
              "value": {
                "name": "name"
              },
              "required": true
            },
            {
              "name": "--content",
              "aliases": [
                "-c"
              ],
              "summary": "comment content",
              "value": {
                "name": "text"
              },
              "required": true
            },
            {
              "name": "--position-x",
              "aliases": [
                "-x"
              ],
              "summary": "inline comment X position (0-100)",
              "value": {
                "name": "number"
              }
            },
            {
              "name": "--position-y",
              "aliases": [
                "-y"
              ],
              "summary": "inline comment Y position (0-100)",
              "value": {
                "name": "number"
              }
            }
          ],
          "effects": [
            "write"
          ],
          "examples": [
            {
              "run": "narro comments add --slide-id intro --author Sam --content \"Tighten this\""
            }
          ]
        },
        {
          "name": "export",
          "summary": "Export comments to a file",
          "options": [
            {
              "name": "--output",
              "aliases": [
                "-o"
              ],
              "summary": "output file path",
              "value": {
                "name": "file"
              }
            },
            {
              "name": "--format",
              "aliases": [
                "-f"
              ],
              "summary": "export format (markdown, html, json)",
              "value": {
                "name": "format",
                "default": "markdown",
                "enum": [
                  "markdown",
                  "html",
                  "json"
                ]
              }
            },
            {
              "name": "--include-resolved",
              "summary": "include resolved comments"
            }
          ],
          "effects": [
            "read",
            "write"
          ],
          "examples": [
            {
              "run": "narro comments export --format markdown --output review.md"
            }
          ]
        },
        {
          "name": "import",
          "summary": "Import comments from a file",
          "options": [
            {
              "name": "--input",
              "aliases": [
                "-i"
              ],
              "summary": "input JSON file path",
              "value": {
                "name": "file"
              },
              "required": true
            },
            {
              "name": "--merge",
              "aliases": [
                "-m"
              ],
              "summary": "merge with existing comments instead of replacing",
              "effects": [
                "write"
              ]
            }
          ],
          "effects": [
            "write"
          ],
          "examples": [
            {
              "run": "narro comments import --input review.json --merge"
            }
          ]
        },
        {
          "name": "help",
          "summary": "display help for command",
          "arguments": [
            {
              "name": "command"
            }
          ],
          "effects": [],
          "examples": [
            {
              "run": "narro comments help add"
            }
          ]
        }
      ],
      "subcommandRequired": true
    },
    {
      "name": "create-template-from-screenshots",
      "summary": "Generate a template from presentation screenshots using AI",
      "arguments": [
        {
          "name": "template-name",
          "summary": "Name of the template to create"
        }
      ],
      "options": [
        {
          "name": "--screenshots",
          "aliases": [
            "-s"
          ],
          "summary": "Screenshot file paths",
          "value": {
            "name": "paths"
          },
          "variadic": true,
          "repeat": "list"
        },
        {
          "name": "--output",
          "aliases": [
            "-o"
          ],
          "summary": "Output directory",
          "value": {
            "name": "dir",
            "default": "./templates"
          }
        },
        {
          "name": "--provider",
          "aliases": [
            "-p"
          ],
          "summary": "AI provider (openai or claude)",
          "value": {
            "name": "provider",
            "default": "openai",
            "enum": [
              "openai",
              "claude"
            ]
          }
        },
        {
          "name": "--model",
          "aliases": [
            "-m"
          ],
          "summary": "AI model to use",
          "value": {
            "name": "model"
          }
        }
      ],
      "effects": [
        "read",
        "write",
        "network"
      ],
      "examples": [
        {
          "run": "narro create-template-from-screenshots acme --screenshots a.png b.png --provider claude"
        }
      ]
    },
    {
      "name": "analyze-slides-for-components",
      "summary": "Analyze presentation slides to identify needed shared-ui components",
      "options": [
        {
          "name": "--screenshots-dir",
          "aliases": [
            "-d"
          ],
          "summary": "Directory containing screenshot files",
          "value": {
            "name": "dir"
          }
        },
        {
          "name": "--screenshots",
          "aliases": [
            "-s"
          ],
          "summary": "Screenshot file paths",
          "value": {
            "name": "paths"
          },
          "variadic": true,
          "repeat": "list"
        },
        {
          "name": "--output",
          "aliases": [
            "-o"
          ],
          "summary": "Output markdown file",
          "value": {
            "name": "file",
            "default": "./component-analysis.md"
          }
        },
        {
          "name": "--provider",
          "aliases": [
            "-p"
          ],
          "summary": "AI provider (openai or claude)",
          "value": {
            "name": "provider",
            "default": "openai",
            "enum": [
              "openai",
              "claude"
            ]
          }
        },
        {
          "name": "--model",
          "aliases": [
            "-m"
          ],
          "summary": "AI model to use",
          "value": {
            "name": "model"
          }
        }
      ],
      "effects": [
        "read",
        "write",
        "network"
      ],
      "examples": [
        {
          "run": "narro analyze-slides-for-components --screenshots-dir shots"
        }
      ]
    },
    {
      "name": "capture-website",
      "summary": "Capture a full-page screenshot of a website",
      "arguments": [
        {
          "name": "url",
          "summary": "URL of the website to capture",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--output",
          "aliases": [
            "-o"
          ],
          "summary": "Output file path (default: screenshot.png)",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--full-page",
          "aliases": [
            "-f"
          ],
          "summary": "Capture full page (scrollable content)"
        },
        {
          "name": "--width",
          "aliases": [
            "-w"
          ],
          "summary": "Viewport width in pixels",
          "value": {
            "name": "number",
            "default": 1920,
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "--height",
          "aliases": [
            "-h"
          ],
          "summary": "Viewport height in pixels",
          "value": {
            "name": "number",
            "default": 1080,
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "--delay",
          "aliases": [
            "-d"
          ],
          "summary": "Delay before screenshot in milliseconds",
          "value": {
            "name": "number",
            "default": 2000,
            "type": "integer",
            "minimum": 0
          }
        },
        {
          "name": "--help",
          "summary": "display help for command"
        }
      ],
      "effects": [
        "write",
        "network",
        "exec"
      ],
      "examples": [
        {
          "run": "narro capture-website https://example.com --output site.png"
        }
      ]
    },
    {
      "name": "record",
      "summary": "Record a web app into an embeddable cast — real DOM, not video",
      "arguments": [
        {
          "name": "url",
          "summary": "the page to record",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--out",
          "aliases": [
            "-o"
          ],
          "summary": "where to write the cast",
          "value": {
            "name": "path",
            "default": "recording.narrocast"
          }
        },
        {
          "name": "--size",
          "summary": "recording viewport — the window is sized to match",
          "value": {
            "name": "WxH",
            "default": "1440x900"
          }
        },
        {
          "name": "--connect",
          "summary": "record a Chrome you already have open, signed in, with your extensions — start it with --remote-debugging-port and a --user-data-dir of its own",
          "value": {
            "name": "endpoint",
            "optional": true
          }
        },
        {
          "name": "--auto",
          "summary": "record headless, scrolling the page, instead of opening a window",
          "value": {
            "name": "seconds",
            "type": "number",
            "minimum": 0
          }
        },
        {
          "name": "--mask",
          "summary": "mask input values and drop scripts and comments"
        },
        {
          "name": "--chapters",
          "summary": "a JSON file of named marks — [{ \"name\": \"publish\", \"atMs\": 4200 }] — for the recordings no one is sitting through",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--mic",
          "summary": "also capture the operator's narration, for a transcript to draft a track from (needs ffmpeg)",
          "value": {
            "name": "path",
            "optional": true
          }
        },
        {
          "name": "--transcribe",
          "summary": "run a Whisper-shaped binary over what --mic caught (default: whisper-cli)",
          "value": {
            "name": "binary",
            "optional": true
          }
        },
        {
          "name": "--notes",
          "summary": "a .notes.md track to bake in — captions, callouts and spotlights over the recording",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--html",
          "summary": "also write a standalone page that plays it",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--embed",
          "summary": "also write the player, the cast and a snippet for a website",
          "value": {
            "name": "dir"
          }
        },
        {
          "name": "--poster",
          "summary": "also write a PNG of the last frame, for PDF and PPTX export",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--cursor",
          "summary": "pointer, trail or none",
          "value": {
            "name": "mode",
            "default": "pointer",
            "enum": [
              "pointer",
              "trail",
              "none"
            ]
          }
        },
        {
          "name": "--no-optimize",
          "summary": "keep images exactly as the page served them"
        },
        {
          "name": "--prompt",
          "summary": "print the prompt for a coding agent without asking first"
        }
      ],
      "effects": [
        "write",
        "network",
        "exec"
      ],
      "examples": [
        {
          "run": "narro record https://localhost:5173 --out demo.narrocast",
          "summary": "Opens a window to drive"
        },
        {
          "run": "narro record https://example.com --auto 8 --mask",
          "summary": "Headless, no window"
        }
      ]
    },
    {
      "name": "cast",
      "summary": "Read a recording back — its shape, its length, and the chapters it carries",
      "arguments": [
        {
          "name": "file",
          "summary": "the .narrocast to read",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--json",
          "summary": "print the summary as JSON"
        }
      ],
      "effects": [
        "read"
      ],
      "idempotent": true,
      "io": {
        "stdout": [
          {
            "mediaType": "text/plain",
            "summary": "the recording's shape, length and chapters"
          },
          {
            "mediaType": "application/json",
            "selectedBy": "--json",
            "summary": "the same summary"
          }
        ]
      },
      "examples": [
        {
          "run": "narro cast demo.narrocast --json"
        }
      ]
    },
    {
      "name": "annotate",
      "summary": "Bake a notes track into a recording — captions, callouts and spotlights",
      "arguments": [
        {
          "name": "file",
          "summary": "the .narrocast to annotate",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--notes",
          "aliases": [
            "-n"
          ],
          "summary": "the track to bake in, a .notes.md",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--out",
          "aliases": [
            "-o"
          ],
          "summary": "write here instead of over the recording",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--clear",
          "summary": "remove the track the recording is carrying"
        },
        {
          "name": "--ui",
          "summary": "open the editor, over the track the recording already has",
          "effects": [
            "read",
            "write",
            "network"
          ],
          "longRunning": true
        },
        {
          "name": "--port",
          "summary": "the port the editor listens on",
          "value": {
            "name": "number",
            "default": 4477,
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          }
        }
      ],
      "effects": [
        "read",
        "write"
      ],
      "examples": [
        {
          "run": "narro annotate demo.narrocast --notes demo.notes.md"
        },
        {
          "run": "narro annotate demo.narrocast --ui",
          "summary": "Edit the track in a browser"
        }
      ]
    },
    {
      "name": "review",
      "summary": "Review a recording — dead clicks, dead air, unreadable type, leaked input",
      "arguments": [
        {
          "name": "file",
          "summary": "the .narrocast to review",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--rules",
          "summary": "a comma-separated subset (leaked-input, dead-click, dead-air, scroll-rush, illegible, unchaptered, chapter-gap)",
          "value": {
            "name": "list"
          }
        },
        {
          "name": "--strict",
          "summary": "fail on warnings too, not only on errors"
        },
        {
          "name": "--out",
          "summary": "also write the briefing, for a person or a coding agent",
          "value": {
            "name": "path"
          },
          "effects": [
            "read",
            "write"
          ]
        },
        {
          "name": "--embed-width",
          "summary": "the width the demo will be shown at, for legibility",
          "value": {
            "name": "px",
            "type": "integer",
            "minimum": 1
          }
        },
        {
          "name": "--json",
          "summary": "print the findings as JSON"
        }
      ],
      "effects": [
        "read"
      ],
      "idempotent": true,
      "exits": {
        "1": {
          "meaning": "the recording has errors, or warnings under --strict"
        }
      },
      "io": {
        "stdout": [
          {
            "mediaType": "text/plain",
            "summary": "the findings"
          },
          {
            "mediaType": "application/json",
            "selectedBy": "--json",
            "summary": "the findings"
          }
        ]
      },
      "examples": [
        {
          "run": "narro review demo.narrocast --strict"
        }
      ]
    },
    {
      "name": "notes",
      "summary": "Draft a narration track from a transcript, resolving what it points at",
      "arguments": [
        {
          "name": "file",
          "summary": "the .narrocast the transcript narrates",
          "required": true
        }
      ],
      "options": [
        {
          "name": "--from",
          "aliases": [
            "-f"
          ],
          "summary": "the transcript: WebVTT, SRT, or Whisper's JSON",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--out",
          "aliases": [
            "-o"
          ],
          "summary": "where to write the draft (default: beside the recording)",
          "value": {
            "name": "path"
          }
        },
        {
          "name": "--offset",
          "summary": "shift the transcript, when it and the recording started apart",
          "value": {
            "name": "ms",
            "type": "integer"
          }
        },
        {
          "name": "--raw",
          "summary": "keep the transcript's own cue lengths instead of joining sentences"
        }
      ],
      "effects": [
        "read",
        "write"
      ],
      "examples": [
        {
          "run": "narro notes demo.narrocast --from narration.vtt"
        }
      ]
    },
    {
      "name": "help",
      "summary": "display help for command",
      "arguments": [
        {
          "name": "command"
        }
      ],
      "effects": [],
      "idempotent": true,
      "examples": [
        {
          "run": "narro help check"
        }
      ]
    }
  ],
  "subcommandRequired": true,
  "exits": {
    "0": {
      "meaning": "success"
    },
    "1": {
      "meaning": "the command failed, or was used wrongly"
    }
  },
  "environment": [
    {
      "name": "OPENAI_API_KEY",
      "summary": "Credential for the AI commands when --provider is openai",
      "secret": true
    },
    {
      "name": "ANTHROPIC_API_KEY",
      "summary": "Credential for the AI commands when --provider is claude",
      "secret": true
    },
    {
      "name": "PLAYWRIGHT_BROWSERS_PATH",
      "summary": "Where to look for a Chromium first, for --fit, --pdf, --png and record"
    },
    {
      "name": "NARRO_CHROMIUM",
      "summary": "The Chromium to use for --fit, --pdf, --png and record, ahead of any other"
    },
    {
      "name": "CHROME_PATH",
      "summary": "A Chrome or Chromium binary to use when Playwright has none installed"
    }
  ]
}
