{"id":41846959,"url":"https://github.com/bymbly/api-tools","last_synced_at":"2026-05-29T02:06:54.447Z","repository":{"id":334514699,"uuid":"1108158927","full_name":"bymbly/api-tools","owner":"bymbly","description":"Unified, opinionated CLI wrapper for API specification tooling.","archived":false,"fork":false,"pushed_at":"2026-05-26T00:49:50.000Z","size":2364,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-26T02:33:48.603Z","etag":null,"topics":["api","arazzo","asyncapi","cli","openapi","redocly","spectral","tools"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bymbly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-02T05:18:07.000Z","updated_at":"2026-05-26T00:44:47.000Z","dependencies_parsed_at":"2026-05-21T12:04:16.130Z","dependency_job_id":null,"html_url":"https://github.com/bymbly/api-tools","commit_stats":null,"previous_names":["bymbly/api-tools"],"tags_count":56,"template":false,"template_full_name":null,"purl":"pkg:github/bymbly/api-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bymbly%2Fapi-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bymbly%2Fapi-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bymbly%2Fapi-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bymbly%2Fapi-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bymbly","download_url":"https://codeload.github.com/bymbly/api-tools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bymbly%2Fapi-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33633469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","arazzo","asyncapi","cli","openapi","redocly","spectral","tools"],"created_at":"2026-01-25T10:01:35.236Z","updated_at":"2026-05-29T02:06:54.424Z","avatar_url":"https://github.com/bymbly.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @bymbly/api-tools\n\nUnified, opinionated CLI wrapper for API specification tooling.\n\nStandardizes common workflows across projects with sensible defaults while allowing full\ncustomization through CLI options and passthrough arguments.\n\n**Supports:** OpenAPI, AsyncAPI, Arazzo\n\n**Wraps:** [AsyncAPI](https://www.asyncapi.com/en/tools/cli) | [Redocly](https://github.com/Redocly/redocly-cli) | [Spectral](https://github.com/stoplightio/spectral)\n\n[![CI](https://github.com/bymbly/api-tools/actions/workflows/workflow.yaml/badge.svg)](https://github.com/bymbly/api-tools/actions/workflows/workflow.yaml)\n[![NPM Version](https://img.shields.io/npm/v/@bymbly/api-tools)](https://www.npmjs.com/package/@bymbly/api-tools)\n[![NPM License](https://img.shields.io/npm/l/@bymbly/api-tools)](https://github.com/bymbly/api-tools/blob/main/LICENSE)\n\n## Features\n\n- **Single unified CLI** - One tool for all API spec operations\n- **Opinionated defaults** - Sensible conventions for file locations and configurations\n- **Consistent interface** - Same flags and patterns across all commands\n- **Flexible overrides** - CLI options for common cases, passthrough for advanced use\n- **Bundled configs** - Default Spectral and Redocly configuration included\n- **Auto-detection** - Finds OpenAPI, AsyncAPI, and Arazzo specs automatically\n\n## Table of Contents\n\n- [@bymbly/api-tools](#bymblyapi-tools)\n  - [Features](#features)\n  - [Table of Contents](#table-of-contents)\n  - [Installation](#installation)\n  - [Quick Start](#quick-start)\n  - [Command Structure](#command-structure)\n    - [Global Options](#global-options)\n  - [Commands](#commands)\n    - [AsyncAPI Commands](#asyncapi-commands)\n      - [`asyncapi build-docs`](#asyncapi-build-docs)\n      - [`asyncapi bundle`](#asyncapi-bundle)\n      - [`asyncapi format`](#asyncapi-format)\n      - [`asyncapi generate docs`](#asyncapi-generate-docs)\n      - [`asyncapi generate from-template`](#asyncapi-generate-from-template)\n      - [`asyncapi lint`](#asyncapi-lint)\n    - [Redocly Commands](#redocly-commands)\n      - [`redocly build-docs`](#redocly-build-docs)\n      - [`redocly bundle`](#redocly-bundle)\n      - [`redocly generate-arazzo`](#redocly-generate-arazzo)\n      - [`redocly init`](#redocly-init)\n      - [`redocly join`](#redocly-join)\n      - [`redocly lint`](#redocly-lint)\n      - [`redocly respect`](#redocly-respect)\n    - [Spectral Commands](#spectral-commands)\n      - [`spectral init`](#spectral-init)\n      - [`spectral lint`](#spectral-lint)\n  - [Default File Locations](#default-file-locations)\n  - [Configuration Files](#configuration-files)\n    - [Auto-Discovery](#auto-discovery)\n    - [Bundled Defaults](#bundled-defaults)\n    - [Custom Configs](#custom-configs)\n  - [Passthrough Arguments](#passthrough-arguments)\n  - [CI/CD Integration](#cicd-integration)\n    - [GitHub Actions Example](#github-actions-example)\n  - [Common Workflows](#common-workflows)\n    - [Development](#development)\n    - [Pre-commit](#pre-commit)\n    - [CI Pipeline](#ci-pipeline)\n    - [API Testing](#api-testing)\n  - [Troubleshooting](#troubleshooting)\n    - [Command not found](#command-not-found)\n    - [Config not found](#config-not-found)\n    - [Bundled config issues](#bundled-config-issues)\n  - [Contributing](#contributing)\n  - [License](#license)\n\n## Installation\n\n```bash\nnpm install -D @bymbly/api-tools@latest\n```\n\n## Quick Start\n\nAdd scripts to your `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"lint\": \"npm run lint:spectral \u0026\u0026 npm run lint:redocly \u0026\u0026 npm run lint:asyncapi\",\n    \"lint:spectral\": \"api-tools spectral lint\",\n    \"lint:redocly\": \"api-tools redocly lint\",\n    \"lint:asyncapi\": \"api-tools asyncapi lint\",\n    \"bundle:openapi\": \"api-tools redocly bundle\",\n    \"bundle:asyncapi\": \"api-tools asyncapi bundle\",\n    \"join\": \"api-tools redocly join\",\n    \"docs:openapi\": \"api-tools redocly build-docs\",\n    \"docs:asyncapi\": \"api-tools asyncapi build-docs\",\n    \"arazzo:gen\": \"api-tools redocly generate-arazzo\",\n    \"test:api\": \"api-tools redocly respect\"\n  }\n}\n```\n\nRun:\n\n```bash\nnpm run lint              # Lint with both Spectral and Redocly\nnpm run bundle:openapi    # Bundle OpenAPI documents\nnpm run bundle:asyncapi   # Bundle AsyncAPI documents\nnpm run join              # Join OpenAPI documents\nnpm run docs:openapi      # Generate OpenAPI HTML documentation\nnpm run docs:asyncapi     # Generate AsyncAPI HTML documentation\nnpm run arazzo:gen        # Generate Arazzo workflow starter\nnpm run test:api          # Execute Arazzo workflow tests\n```\n\n## Command Structure\n\n```bash\napi-tools [global-options] \u003ccommand\u003e \u003csubcommand\u003e [options] [-- passthrough-args]\n```\n\n### Global Options\n\nAvailable for all commands:\n\n- `--quiet` - Disable wrapper logging (still shows tool output)\n- `--silent` - Disable all output (wrapper + tool)\n- `--cwd \u003cpath\u003e` - Run as if started in this directory\n\n## Commands\n\n### AsyncAPI Commands\n\n#### `asyncapi build-docs`\n\nAlias for `asyncapi generate docs` - builds HTML documentation from AsyncAPI documents.\n\n```bash\napi-tools asyncapi build-docs [input] [options]\n```\n\nSee [`asyncapi generate docs`](#asyncapi-generate-docs) for full usage details.\n\n#### `asyncapi bundle`\n\nBundle AsyncAPI documents into a single file.\n\n**Usage:**\n\n```bash\napi-tools asyncapi bundle [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Document path (default: `asyncapi/asyncapi.yaml`)\n- `--output \u003cpath\u003e` - Output file path (default: `dist/bundle/asyncapi.yaml`)\n- `--ext \u003cextension\u003e` - Output extension (overrides `--output` extension)\n  - Choices: `json`, `yaml`, `yml`\n- `--x-origin` - Generate x-origin fields with dereferenced $ref history\n\n**Examples:**\n\n```bash\n# Bundle with defaults\napi-tools asyncapi bundle\n\n# Bundle to JSON\napi-tools asyncapi bundle --ext json\n\n# Bundle with x-origin tracking\napi-tools asyncapi bundle --x-origin\n\n# Custom output\napi-tools asyncapi bundle --output dist/api-bundle.yaml\n```\n\n#### `asyncapi format`\n\nConvert AsyncAPI documents between formats (YAML \u003c---\u003e JSON).\n\n**Usage:**\n\n```bash\napi-tools asyncapi format [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Document path (default: `asyncapi/asyncapi.yaml`)\n- `--output \u003cfile\u003e` - Output file path (default: `dist/format/asyncapi.json`)\n- `--ext \u003cextension\u003e` - Output extension (overrides `--output` extension)\n  - Choices: `json`, `yaml`, `yml`\n\n**Examples:**\n\n```bash\n# Convert to JSON (default)\napi-tools asyncapi format\n\n# Convert to YAML\napi-tools asyncapi format --ext yaml\n\n# Custom input and output\napi-tools asyncapi format input.json --output output.yaml\n```\n\n#### `asyncapi generate docs`\n\nGenerate HTML documentation (convenience wrapper around [`from-template`](#asyncapi-generate-from-template) with HTML template).\n\n**Usage:**\n\n```bash\napi-tools asyncapi generate docs [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Document path (default: `asyncapi/asyncapi.yaml`)\n- `--output \u003cfile\u003e` - Output HTML file (default: `dist/docs/asyncapi.html`)\n- `--params \u003ckey=value...\u003e` - Template parameters (can be repeated)\n- `--single-file` - Generate single HTML file (default: `true`)\n- `--no-single-file` - Generate multiple files\n\n**Examples:**\n\n```bash\n# Generate single-file docs\napi-tools asyncapi generate docs\n\n# Generate multi-file docs\napi-tools asyncapi generate docs --no-single-file\n\n# Custom output and parameters\napi-tools asyncapi generate docs --output public/api.html \\\n  --params version=2.0.0\n```\n\n#### `asyncapi generate from-template`\n\nGenerate code or documentation from AsyncAPI documents using templates.\n\n**Usage:**\n\n```bash\napi-tools asyncapi generate from-template \u003ctemplate\u003e [input] [options]\n```\n\n**Options:**\n\n- `\u003ctemplate\u003e` - **REQUIRED.** Template name or URL (e.g., `@asyncapi/html-template`)\n- `[input]` - Document path (default: `asyncapi/asyncapi.yaml`)\n- `--output \u003cdirectory\u003e` - Output directory (default: `dist/generated/`)\n- `--params \u003ckey=value...\u003e` - Template parameters (can be repeated)\n- `--force-write` - Overwrite existing files\n\n**Examples:**\n\n```bash\n# Generate HTML docs\napi-tools asyncapi generate from-template @asyncapi/html-template\n\n# Generate with custom output\napi-tools asyncapi generate from-template @asyncapi/nodejs-template \\\n  --output src/generated\n\n# Generate with parameters\napi-tools asyncapi generate from-template @asyncapi/java-spring-template \\\n  --params javaPackage=com.example.myapp.codegen maven=true\n```\n\n#### `asyncapi lint`\n\nValidate and lint AsyncAPI documents.\n\n**Usage:**\n\n```bash\napi-tools asyncapi lint [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Document path (default: `asyncapi/asyncapi.yaml`)\n- `--format \u003cformat\u003e` - Output format (default: `stylish`)\n  - Choices: `json`, `stylish`, `junit`, `html`, `teamcity`, `pretty`, `github-actions`, `sarif`,\n    `code-climate`, `gitlab`, `markdown`\n- `--output \u003cfile\u003e` - Write output to file\n- `--fail-severity \u003clevel\u003e` - Fail threshold (default: `warn`)\n  - Choices: `error`, `warn`, `info`, `hint`\n\n**Examples:**\n\n```bash\n# Lint default AsyncAPI spec\napi-tools asyncapi lint\n\n# Lint specific file\napi-tools asyncapi lint custom/spec.yaml\n\n# JSON output\napi-tools asyncapi lint --format json --output results.json\n\n# Only fail on errors\napi-tools asyncapi lint --fail-severity error\n```\n\n### Redocly Commands\n\n#### `redocly build-docs`\n\nBuild HTML documentation from OpenAPI documents.\n\n**Usage:**\n\n```bash\napi-tools redocly build-docs [input] [options]\n```\n\n**Options:**\n\n- `[input]` - OpenAPI document path (default: `openapi/openapi.yaml`)\n- `--output \u003cfile\u003e` - Output HTML file (default: `dist/docs/openapi.html`)\n- `--config \u003cfile\u003e` - Config file path (overrides auto/bundled)\n\n**Examples:**\n\n```bash\n# Generate docs with defaults\napi-tools redocly build-docs\n\n# Custom output location\napi-tools redocly build-docs --output public/api-docs.html\n\n# Custom title via passthrough\napi-tools redocly build-docs -- --title \"My API Documentation\"\n```\n\n#### `redocly bundle`\n\nBundle API descriptions into a single file.\n\n\u003e **Note:** The `bundle` command differs from the `join` command.\n\u003e The `bundle` command takes a root OpenAPI file as input and follows the `$ref` mentions to include\n\u003e all the referenced components into a single output file. The `join` command can combine multiple\n\u003e OpenAPI files into a single unified API description file.\n\n**Usage:**\n\n```bash\napi-tools redocly bundle [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Document path (default: `openapi/openapi.yaml`)\n- `--output \u003cpath\u003e` - Output file path (default: `dist/bundle/openapi.yaml`)\n- `--ext \u003cextension\u003e` - Output extension (overrides `--output` extension)\n  - Choices: `json`, `yaml`, `yml`\n- `--dereferenced` - Generate fully dereferenced bundle (no `$ref`)\n- `--config \u003cfile\u003e` - Config file path (overrides auto/bundled)\n\n**Examples:**\n\n```bash\n# Bundle with defaults\napi-tools redocly bundle\n\n# Bundle to JSON\napi-tools redocly bundle --ext json\n\n# Fully dereferenced bundle\napi-tools redocly bundle --dereferenced\n\n# Custom output\napi-tools redocly bundle --output dist/api-bundle.yaml\n\n# Remove unused components via passthrough\napi-tools redocly bundle -- --remove-unused-components\n```\n\n#### `redocly generate-arazzo`\n\nGenerate Arazzo workflow description from OpenAPI document.\n\n**Usage:**\n\n```bash\napi-tools redocly generate-arazzo [input] [options]\n```\n\n**Options:**\n\n- `[input]` - OpenAPI document path (default: `openapi/openapi.yaml`)\n- `--output \u003cfile\u003e` - Output file path (default: `arazzo/auto-generated.arazzo.yaml`)\n\n**Note:** Generated Arazzo files require manual editing to be functional.\n\n**Examples:**\n\n```bash\n# Generate from default OpenAPI\napi-tools redocly generate-arazzo\n\n# Custom output\napi-tools redocly generate-arazzo --output arazzo/workflows.arazzo.yaml\n```\n\n#### `redocly init`\n\nCreate a default `redocly.yaml` config file.\n\n```bash\napi-tools redocly init [--force]\n```\n\n#### `redocly join`\n\nJoin multiple OpenAPI 3.x documents into a single file.\n\n\u003e **Note:** The `join` command differs from the `bundle` command.\n\u003e The `bundle` command takes a root OpenAPI file as input and follows the `$ref` mentions to include\n\u003e all the referenced components into a single output file. The `join` command can combine multiple\n\u003e OpenAPI files into a single unified API description file.\n\u003e Unlike the `bundle` command, `join` does not execute preprocessors or decorators and combines the\n\u003e API description files as-is without modifying the original source files.\n\n**Usage:**\n\n```bash\napi-tools redocly join \u003cinputs...\u003e [options]\n```\n\n**Options:**\n\n- `\u003cinputs...\u003e` - **REQUIRED.** At least 2 document paths to join\n- `--output \u003cfile\u003e` - Output file path (default: `dist/join/openapi.yaml`)\n- `--prefix-components-with-info-prop \u003cproperty\u003e` - Prefix component names with info property to\n  resolve conflicts (e.g., `version`, `title`)\n- `--prefix-tags-with-info-prop \u003cproperty\u003e` - Prefix tag names with info property (e.g., `title`, `version`)\n- `--prefix-tags-with-filename` - Prefix tag names with filename to resolve conflicts\n- `--without-x-tag-groups` - Skip automated `x-tagGroups` creation (avoids tag duplication)\n- `--config \u003cfile\u003e` - Config file path (overrides auto/bundled)\n\n\u003e **Note:** The options `--prefix-tags-with-info-prop`, `--prefix-tags-with-filename`, and\n\u003e `--without-x-tag-groups` are mutually exclusive.\n\n**Examples:**\n\n```bash\n# Join two documents\napi-tools redocly join api-1.yaml api-2.yaml\n\n# Join with custom output\napi-tools redocly join users-api.yaml orders-api.yaml \\\n  --output dist/combined-api.yaml\n\n# Resolve component naming conflicts using version\napi-tools redocly join museum-v1.yaml museum-v2.yaml \\\n  --prefix-components-with-info-prop version\n\n# Prefix tags with title to avoid conflicts\napi-tools redocly join first-api.yaml second-api.yaml \\\n  --prefix-tags-with-info-prop title\n\n# Prefix tags with filename\napi-tools redocly join api1/openapi.yaml api2/openapi.yaml \\\n  --prefix-tags-with-filename\n\n# Skip x-tagGroups for duplicate tags\napi-tools redocly join api-a.yaml api-b.yaml --without-x-tag-groups\n\n# Advanced passthrough options\napi-tools redocly join *.yaml -- --lint-config error\n```\n\n#### `redocly lint`\n\nValidate and lint OpenAPI, AsyncAPI, and Arazzo documents using Redocly.\n\n**Usage:**\n\n```bash\napi-tools redocly lint [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Document path (default: auto-detect)\n- `--openapi` - Lint only OpenAPI at `openapi/openapi.yaml`\n- `--asyncapi` - Lint only AsyncAPI at `asyncapi/asyncapi.yaml`\n- `--arazzo` - Lint only Arazzo at `arazzo/arazzo.yaml`\n- `--format \u003cformat\u003e` - Output format (default: `codeframe`)\n  - Choices: `codeframe`, `stylish`, `json`, `checkstyle`, `codeclimate`, `github-actions`, `markdown`, `summary`\n- `--config \u003cfile\u003e` - Config file path (overrides auto/bundled)\n\n**Examples:**\n\n```bash\n# Auto-detect and lint all specs\napi-tools redocly lint\n\n# Lint only OpenAPI\napi-tools redocly lint --openapi\n\n# JSON output\napi-tools redocly lint --format json\n\n# Custom config\napi-tools redocly lint --config custom-redocly.yaml\n```\n\n#### `redocly respect`\n\nExecute Arazzo workflow tests.\n\n**Usage:**\n\n```bash\napi-tools redocly respect [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Arazzo document path (default: `arazzo/arazzo.yaml`)\n- `--workflow \u003cnames...\u003e` - Run only specified workflows\n- `--skip \u003cnames...\u003e` - Skip specified workflows (conflicts with `--workflow`)\n- `--verbose` - Enable verbose output\n- `--input \u003cparams...\u003e` - Workflow input parameters (`key=value` or JSON)\n- `--server \u003coverrides...\u003e` - Server overrides (`name=url`)\n- `--json-output \u003cfile\u003e` - Save results to JSON file\n- `--har-output \u003cfile\u003e` - Save HTTP interactions to HAR file\n\n**Examples:**\n\n```bash\n# Execute default workflows\napi-tools redocly respect\n\n# Run specific workflow\napi-tools redocly respect --workflow login-flow\n\n# Test against staging\napi-tools redocly respect --server api=https://staging.example.com\n\n# Provide inputs\napi-tools redocly respect --input email=test@example.com --input password=secret\n\n# CI/CD with JSON output\napi-tools redocly respect --json-output results.json --verbose\n\n# Advanced options via passthrough\napi-tools redocly respect -- --max-steps 100 --severity '{\"STATUS_CODE_CHECK\":\"warn\"}'\n```\n\n### Spectral Commands\n\n#### `spectral init`\n\nCreate a default `spectral.yaml` config file.\n\n```bash\napi-tools spectral init [--force]\n```\n\n#### `spectral lint`\n\nValidate and lint OpenAPI, AsyncAPI, and Arazzo documents.\n\n**Usage:**\n\n```bash\napi-tools spectral lint [input] [options]\n```\n\n**Options:**\n\n- `[input]` - Document path (default: auto-detect)\n- `--openapi` - Lint only OpenAPI at `openapi/openapi.yaml`\n- `--asyncapi` - Lint only AsyncAPI at `asyncapi/asyncapi.yaml`\n- `--arazzo` - Lint only Arazzo at `arazzo/arazzo.yaml`\n- `--format \u003cformat\u003e` - Output format (default: `stylish`)\n  - Choices: `json`, `stylish`, `junit`, `html`, `text`, `teamcity`, `pretty`, `github-actions`, `sarif`, `markdown`, `gitlab`\n- `--output \u003cfile\u003e` - Write output to file\n- `--ruleset \u003cfile\u003e` - Custom ruleset (overrides auto/bundled)\n- `--fail-severity \u003clevel\u003e` - Fail threshold (default: `warn`)\n  - Choices: `error`, `warn`, `info`, `hint`\n- `--display-only-failures` - Show only failing results\n- `--verbose` - Enable verbose output\n\n**Examples:**\n\n```bash\n# Auto-detect and lint all specs\napi-tools spectral lint\n\n# Lint specific spec types\napi-tools spectral lint --openapi\napi-tools spectral lint --asyncapi --arazzo\n\n# Lint specific file\napi-tools spectral lint custom/spec.yaml\n\n# JSON output\napi-tools spectral lint --format json --output results.json\n\n# Custom ruleset\napi-tools spectral lint --ruleset .spectral.yaml\n\n# Passthrough advanced options\napi-tools spectral lint -- --ignore-unknown-format\n```\n\n## Default File Locations\n\nThe tool expects the following directory structure:\n\n```bash\nproject/\n├── openapi/\n│   └── openapi.yaml        # Main OpenAPI spec\n├── asyncapi/\n│   └── asyncapi.yaml       # Main AsyncAPI spec\n├── arazzo/\n│   ├── arazzo.yaml         # Production Arazzo workflows\n│   └── auto-generated.arazzo.yaml  # Generated starter\n└── dist/\n    ├── bundle/\n    │   ├── openapi.yaml    # OpenAPI bundled output\n    │   └── asyncapi.yaml   # AsyncAPI bundled output\n    ├── format/\n    │   └── asyncapi.json   # AsyncAPI format output\n    ├── generated/          # AsyncAPI template output\n    ├── join/\n    │   └── openapi.yaml    # Joined output\n    └── docs/\n        ├── openapi.html    # OpenAPI docs\n        └── asyncapi.html   # AsyncAPI docs (or asyncapi/ for multi-file)\n```\n\n## Configuration Files\n\n### Auto-Discovery\n\nThe tool automatically discovers local config files:\n\n- `.spectral.yaml`, `.spectral.yml`, `.spectral.json`, `.spectral.js`, `.spectral.mjs`,\n  `spectral.yaml`, `spectral.yml`, `spectral.json`, `spectral.js`, `spectral.mjs`\n- `.redocly.yaml`, `.redocly.yml`, `redocly.yaml`, `redocly.yml`\n\n### Bundled Defaults\n\nIf no local config exists, opinionated bundled configs are used with stricter-than-default rules:\n\n- **Spectral**: `defaults/spectral.yaml` - Comprehensive OpenAPI/AsyncAPI/Arazzo validation\n- **Redocly**: `defaults/redocly.yaml` - Strict API design standards\n\nThese bundled configs enforce best practices and may be more restrictive than upstream tool defaults.\nCreate a local config file to customize rules for your project.\n\n### Custom Configs\n\nOverride with CLI options:\n\n```bash\napi-tools spectral lint --ruleset custom/.spectral.yaml\napi-tools redocly lint --config custom/redocly.yaml\n```\n\n## Passthrough Arguments\n\nFor advanced options not exposed by the wrapper, use `--` to pass arguments directly to the underlying tool:\n\n```bash\n# Spectral advanced options\napi-tools spectral lint -- --ignore-unknown-format\n\n# Redocly advanced options\napi-tools redocly bundle -- --remove-unused-components\napi-tools redocly respect -- --max-steps 100 --execution-timeout 1800000\n```\n\n## CI/CD Integration\n\n### GitHub Actions Example\n\n```yaml\nname: API Validation\n\non: [push, pull_request]\n\njobs:\n  validate:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: actions/setup-node@v6\n        with:\n          node-version: \"24\"\n\n      - name: Install dependencies\n        run: npm ci\n        env:\n          GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_PACKAGES_TOKEN }}\n\n      - name: Lint with Spectral\n        run: npm run lint:spectral -- --format github-actions\n\n      - name: Lint with Redocly\n        run: npm run lint:redocly -- --format github-actions\n\n      - name: Bundle spec\n        run: npm run bundle\n\n      - name: Generate docs\n        run: npm run docs\n\n      - name: Test workflows\n        run: npm run test:api -- --verbose\n\n      # Alternative: Call CLI directly (useful for matrix builds or custom workflows)\n      # - name: Lint OpenAPI with Spectral\n      #   run: npx api-tools spectral lint --openapi --format github-actions\n\n      # Optional: Save results as artifacts\n      - name: Generate test report\n        if: always()\n        run: npm run test:api -- --json-output results.json\n\n      - name: Upload test results\n        if: always()\n        uses: actions/upload-artifact@v6\n        with:\n          name: api-test-results\n          path: results.json\n```\n\n## Common Workflows\n\n### Development\n\n```bash\n# Lint using Spectral during development\napi-tools spectral lint --openapi\n\n# Lint using Redocly during development\napi-tools redocly lint --openapi\n\n# Lint AsyncAPI during development\napi-tools asyncapi lint\n\n# Generate docs for local preview\napi-tools redocly build-docs\napi-tools asyncapi build-docs\n```\n\n### Pre-commit\n\n```bash\n# Fast validation\napi-tools spectral lint\napi-tools redocly lint\napi-tools asyncapi lint\n```\n\n### CI Pipeline\n\n```bash\n# Full validation with outputs\napi-tools spectral lint --format github-actions\napi-tools redocly lint --format github-actions\napi-tools asyncapi lint --format github-actions\napi-tools redocly bundle --output dist/openapi.yaml\napi-tools asyncapi bundle --output dist/asyncapi.yaml\napi-tools redocly build-docs --output dist/api-docs.html\napi-tools asyncapi build-docs --output dist/asyncapi-docs.html\n```\n\n### API Testing\n\n```bash\n# Run Arazzo workflows against staging\napi-tools redocly respect \\\n  --server api=https://staging.example.com \\\n  --input apiKey=${STAGING_API_KEY} \\\n  --json-output test-results.json \\\n  --verbose\n\n# Bundle AsyncAPI for deployment\napi-tools asyncapi bundle --output dist/asyncapi-production.yaml\n\n# Convert AsyncAPI to JSON for tooling\napi-tools asyncapi format --ext json --output dist/asyncapi.json\n```\n\n## Troubleshooting\n\n### Command not found\n\nEnsure the package is installed and npm scripts are configured:\n\n```bash\nnpm install -D @bymbly/api-tools@latest\n```\n\n### Config not found\n\nCheck config file names and locations. Use `--config` or `--ruleset` to specify custom paths.\n\n### Bundled config issues\n\nTo use your own config instead of bundled defaults, create a local config file that will be auto-discovered.\n\n## Contributing\n\nIssues and pull requests welcome at [github.com/bymbly/api-tools](https://github.com/bymbly/api-tools)!\n\n## License\n\n[Apache License, Version 2.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbymbly%2Fapi-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbymbly%2Fapi-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbymbly%2Fapi-tools/lists"}