Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,6 @@ dist
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vite/

# Gemini
.gemini/
25 changes: 10 additions & 15 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,42 @@

## [3.0.0](https://github.com/ioncakephper/cli-schema/compare/v2.1.0...v3.0.0) (2025-12-08)


### ⚠ BREAKING CHANGES

* **schema:** This commit introduces breaking changes.
- **schema:** This commit introduces breaking changes.

### Code Refactoring

* **schema:** Remove `variadic` property from CLI options definition ([7f71cf1](https://github.com/ioncakephper/cli-schema/commit/7f71cf107da1f7822b3364b8655b4e311250a559))
- **schema:** Remove `variadic` property from CLI options definition ([7f71cf1](https://github.com/ioncakephper/cli-schema/commit/7f71cf107da1f7822b3364b8655b4e311250a559))

## [2.1.0](https://github.com/ioncakephper/cli-schema/compare/v2.0.1...v2.1.0) (2025-12-08)


### Features

* **schema:** Enhance argument and option schema with default values, validation, and advanced options ([e96a42c](https://github.com/ioncakephper/cli-schema/commit/e96a42c9fee344ba3ba57714f48ac7ac420e731a))
* **schema:** Enhance argument and option schema with default values, validation, and advanced options ([ce1c541](https://github.com/ioncakephper/cli-schema/commit/ce1c541b95e8cae636acdf32e412f97bccfd23bf))
- **schema:** Enhance argument and option schema with default values, validation, and advanced options ([e96a42c](https://github.com/ioncakephper/cli-schema/commit/e96a42c9fee344ba3ba57714f48ac7ac420e731a))
- **schema:** Enhance argument and option schema with default values, validation, and advanced options ([ce1c541](https://github.com/ioncakephper/cli-schema/commit/ce1c541b95e8cae636acdf32e412f97bccfd23bf))

## [2.0.1](https://github.com/ioncakephper/cli-schema/compare/v2.0.0...v2.0.1) (2025-12-08)


### Bug Fixes

* **schema:** Add detailed reference for the root `cli` object ([ef34155](https://github.com/ioncakephper/cli-schema/commit/ef341556a93dc87040b69e934a04e63801318949))
* **schema:** Add detailed reference for the root `cli` object ([b67988d](https://github.com/ioncakephper/cli-schema/commit/b67988d27553fd0fe010472a9905b19961a12e4d))
- **schema:** Add detailed reference for the root `cli` object ([ef34155](https://github.com/ioncakephper/cli-schema/commit/ef341556a93dc87040b69e934a04e63801318949))
- **schema:** Add detailed reference for the root `cli` object ([b67988d](https://github.com/ioncakephper/cli-schema/commit/b67988d27553fd0fe010472a9905b19961a12e4d))

## [2.0.0](https://github.com/ioncakephper/cli-schema/compare/v1.1.0...v2.0.0) (2025-12-08)


### ⚠ BREAKING CHANGES

* **examples:** This commit introduces breaking changes.
* **schema:** This commit introduces breaking changes.
- **examples:** This commit introduces breaking changes.
- **schema:** This commit introduces breaking changes.

### Features

* **schema:** Require 'cli' property at the root level ([4dfd528](https://github.com/ioncakephper/cli-schema/commit/4dfd528df98d8d441d09b04efde6011fb601761d))

- **schema:** Require 'cli' property at the root level ([4dfd528](https://github.com/ioncakephper/cli-schema/commit/4dfd528df98d8d441d09b04efde6011fb601761d))

### Documentation

* **examples:** update examples and README for required 'cli' root object ([099617a](https://github.com/ioncakephper/cli-schema/commit/099617af549fd24ad92cdd44e4dfd0a81b60fc8e))
- **examples:** update examples and README for required 'cli' root object ([099617a](https://github.com/ioncakephper/cli-schema/commit/099617af549fd24ad92cdd44e4dfd0a81b60fc8e))

## [1.1.0](https://github.com/ioncakephper/cli-schema/compare/1.0.7...v1.1.0) (2025-12-08)

Expand Down
81 changes: 81 additions & 0 deletions GEMINI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Gemini Project: cli-schema

## Project Overview

This project provides a canonical JSON schema for defining Command-Line Interfaces (CLIs) in a declarative YAML format. The goal is to establish a universal standard for CLIs, enabling automation, consistency, and a better developer experience. The core of the project is a JSON schema that defines the structure of the CLI, and a validation library to check YAML files against this schema.

The main technologies used are:

- **Node.js:** The runtime environment for the project.
- **JSON Schema:** Used to define the structure of the CLI definition files.
- **YAML:** The format for writing the declarative CLI definitions.
- **Ajv:** A fast JSON schema validator.
- **Jest:** The testing framework.
- **Commander.js:** A library for building command-line interfaces in Node.js.
- **ESLint and Prettier:** For code linting and formatting.

## Building and Running

### Installation

To install the project dependencies, run:

```bash
npm install
```

### Running the CLI

The main CLI tool can be run with the following command:

```bash
npm start
```

You can also use the `npx` command to run the CLI and validate a file:

```bash
npx cli-schema path/to/your/file.yml
```

### Running Tests

To run the test suite, use the following command:

```bash
npm test
```

### Linting

To check the code for linting errors, run:

```bash
npm run lint
```

To automatically fix linting errors, run:

```bash
npm run lint:fix
```

### Formatting

To format the code using Prettier, run:

```bash
npm run format
```

## Development Conventions

- **Code Style:** The project uses Prettier for automatic code formatting and ESLint for enforcing code style and quality.
- **Testing:** Tests are written using the Jest framework and are located in the `test` directory.
- **Contributions:** Contributions are welcome. Please refer to the `CONTRIBUTING.md` file for guidelines.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The documentation refers to a CONTRIBUTING.md file for contribution guidelines. However, this file doesn't appear to be present in the repository, which could be confusing for potential contributors. Please consider adding the CONTRIBUTING.md file or updating this line to point to the correct contribution process.

- **Project Structure:** The project follows a standard Node.js project structure:
- `bin`: Contains the executable script for the CLI.
- `src`: Contains the main source code for the validation library.
- `schema`: Contains the JSON schema for the CLI definitions.
- `test`: Contains the tests for the project.
- `examples`: Contains example YAML definition files.
80 changes: 52 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,30 @@ if (result.valid) {
}
```

### Schema-Driven Development in your IDE

To get autocompletion and real-time validation when writing your CLI definition files, you can link the schema directly in your YAML file. Most modern editors (like VS Code with the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)) support this via a special comment.

Add the following line to the top of your YAML file:

```yaml
# yaml-language-server: $schema=https://cdn.jsdelivr.net/npm/cli-schema@3.0.0/schema/cli.schema.json

cli:
name: my-cli
description: A sample CLI defined with cli-schema.
version: 1.0.0
# ... rest of your definition
```

By adding this comment, your editor will provide:

- **Autocompletion** for all properties (`name`, `commands`, `options`, etc.).
- **Validation** to catch typos and structural errors as you type.
- **Descriptions** on hover for each property.

> **Note:** For the latest schema, you can use `.../npm/cli-schema/schema/cli.schema.json`, but using a specific version is recommended for stability.

### Scaling with Complexity

While the examples show a simple command, the schema is designed to handle enterprise-grade CLIs with dozens of nested commands, complex options, and varied argument structures. Advanced features like command hierarchies, option dependencies, and reusable type definitions are modeled directly in the schema, ensuring that it scales with your project's needs without sacrificing clarity.
Expand All @@ -126,19 +150,19 @@ While the examples show a simple command, the schema is designed to handle enter

The `cli` object is the root of your CLI definition. It contains the following properties:

| Property | Type | Description |
| ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `arguments` | `array` | An array of `argument` objects for the root command. |
| `commands` | `array` | An array of nested `command` objects (subcommands). |
| `defaultConfigFile` | `string` | The path to a default configuration file that the CLI should load. |
| `description` | `string` | A brief description of your CLI's purpose. |
| `fallbackConfig` | `object` | An object containing fallback configuration values to be used if the default configuration file is not found or does not contain a required value. |
| `name` | `string` | The name of your CLI application. **(Required)** |
| `options` | `array` | An array of `option` objects for the root command. |
| `showGlobalOptions` | `boolean` | If `true`, global options will be displayed in the help output for subcommands. |
| `sortCommands` | `boolean` | If `true`, help output will display commands in alphabetical order. |
| `sortOptions` | `boolean` | If `true`, help output will display options in alphabetical order. |
| `version` | `string` | The version of your CLI. It is recommended to follow semantic versioning (e.g., `1.0.0`). |
| Property | Type | Description |
| ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `arguments` | `array` | An array of `argument` objects for the root command. |
| `commands` | `array` | An array of nested `command` objects (subcommands). |
| `defaultConfigFile` | `string` | The path to a default configuration file that the CLI should load. |
| `description` | `string` | A brief description of your CLI's purpose. |
| `fallbackConfig` | `object` | An object containing fallback configuration values to be used if the default configuration file is not found or does not contain a required value. |
| `name` | `string` | The name of your CLI application. **(Required)** |
| `options` | `array` | An array of `option` objects for the root command. |
| `showGlobalOptions` | `boolean` | If `true`, global options will be displayed in the help output for subcommands. |
| `sortCommands` | `boolean` | If `true`, help output will display commands in alphabetical order. |
| `sortOptions` | `boolean` | If `true`, help output will display options in alphabetical order. |
| `version` | `string` | The version of your CLI. It is recommended to follow semantic versioning (e.g., `1.0.0`). |

The `cli-schema` defines the structure for your CLI definition file. Here are the main building blocks:

Expand Down Expand Up @@ -166,28 +190,28 @@ The `cli-schema` defines the structure for your CLI definition file. Here are th

### The `option` Object

| Property | Type | Description |
| ------------- | --------- | ---------------------------------------------------------------------------- |
| `arguments` | `array` | An array of `argument` objects that can be associated with this option. |
| `choices` | `array` | A list of allowed values for the option. |
| `default` | `object` | A `default` object defining the default value for this option. |
| `description` | `string` | A brief description of the option. |
| `name` | `string` | The long name of the option (e.g., `port`). **(Required)** |
| `range` | `object` | A numerical range with `min` and `max` properties for the option's value. |
| `required` | `boolean` | Whether the option is required. Defaults to `false`. |
| `short` | `string` | The single-letter short alias (e.g., `p`). Must be `^[a-zA-Z]$`. |
| `type` | `string` | The data type. Can be `string`, `number`, `boolean`. |
| Property | Type | Description |
| ------------- | --------- | ------------------------------------------------------------------------- |
| `arguments` | `array` | An array of `argument` objects that can be associated with this option. |
| `choices` | `array` | A list of allowed values for the option. |
| `default` | `object` | A `default` object defining the default value for this option. |
| `description` | `string` | A brief description of the option. |
| `name` | `string` | The long name of the option (e.g., `port`). **(Required)** |
| `range` | `object` | A numerical range with `min` and `max` properties for the option's value. |
| `required` | `boolean` | Whether the option is required. Defaults to `false`. |
| `short` | `string` | The single-letter short alias (e.g., `p`). Must be `^[a-zA-Z]$`. |
| `type` | `string` | The data type. Can be `string`, `number`, `boolean`. |

### The `default` Object

> [!IMPORTANT]
> The `default` object is used to define a default value for an `argument` or `option`. It must have exactly one of the following properties:

| Property | Type | Description |
| ------------ | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Property | Type | Description |
| ------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `value` | `string`, `number`, `boolean`, `array`, `object` | A literal value to use as the default. |
| `fromConfig` | `string` | A dot-notation path to retrieve a value from a configuration file (e.g., `user.name`). |
| `fn` | `string` | A JavaScript arrow function that returns the default value. The `program` object is available as an argument. |
| `fromConfig` | `string` | A dot-notation path to retrieve a value from a configuration file (e.g., `user.name`). |
| `fn` | `string` | A JavaScript arrow function that returns the default value. The `program` object is available as an argument. |

## Examples

Expand Down
10 changes: 5 additions & 5 deletions examples/cli-schema.definition.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# yaml-language-server: $schema=https://cdn.jsdelivr.net/npm/cli-schema@3.0.0/schema/cli.schema.json

# This file defines the 'cli-schema' command-line tool itself,
# using the canonical schema.
cli:
command: cli-schema
name: cli-schema
description: Canonical JSON Schema for declarative CLI definitions
version: '1.0.6'

Expand All @@ -19,10 +21,8 @@ cli:
# These are standard options automatically provided by commander.js.
options:
- name: help
alias: h
short: h
description: display help for command
type: boolean
- name: version
alias: V
short: V
description: output the version number
type: boolean
2 changes: 2 additions & 0 deletions examples/demo-init.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# yaml-language-server: $schema=https://cdn.jsdelivr.net/npm/cli-schema@3.0.0/schema/cli.schema.json

cli:
name: 'demo-init'
description: 'Demo CLI initializer'
Expand Down
2 changes: 2 additions & 0 deletions examples/npm-install.definition.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# yaml-language-server: $schema=https://cdn.jsdelivr.net/npm/cli-schema@3.0.0/schema/cli.schema.json

# Defines the 'npm install', 'npm init', and 'npm version' commands using the canonical CLI schema.
# This serves as a practical example of describing common Node.js CLI operations.
cli:
Expand Down
2 changes: 1 addition & 1 deletion schema/cli.schema.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$id": "https://example.com/cli.schema.json",
"$id": "https://cdn.jsdelivr.net/npm/cli-schema@3.0.0/schema/cli.schema.json",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Hardcoding the version 3.0.0 in the schema's $id URI can lead to maintenance issues and version mismatches in the future. When you release a new version (e.g., 3.0.1), this $id will need to be manually updated. If forgotten, the schema for the new version will incorrectly identify itself as 3.0.0, potentially causing tools and IDEs to use an outdated schema.

A more robust approach would be to automate the version update in this URI as part of your release process. This ensures the schema's $id always accurately reflects its published version.

"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CLI Schema",
"description": "Canonical schema for declarative CLI definitions",
Expand Down