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
10 changes: 5 additions & 5 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "derrickko-clify",
"name": "codeyogi911-clify",
"owner": {
"name": "derrickko",
"url": "https://github.com/derrickko"
"name": "codeyogi911",
"url": "https://github.com/codeyogi911"
},
"plugins": [
{
"name": "clify",
"description": "Generate self-updating CLI repos from API documentation URLs.",
"version": "0.1.0",
"description": "Generate A+ Node.js CLIs from API documentation. Copy a hand-crafted exemplar, mechanically substitute API-specific content, then verify with a deterministic validation gate.",
"version": "0.2.0",
"source": "./"
}
]
Expand Down
20 changes: 13 additions & 7 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
{
"name": "clify",
"version": "0.1.0",
"description": "Generate self-updating CLI repos from API documentation URLs. Produces Node.js CLIs with agent framework wrappers, smoke tests, and a self-learning knowledge system.",
"version": "0.2.0",
"description": "Generate A+ Node.js CLIs from API documentation. Copy a hand-crafted exemplar, mechanically substitute API-specific content, then verify with a deterministic validation gate.",
"author": {
"name": "Derrick",
"url": "https://github.com/derrickko"
"name": "codeyogi911",
"url": "https://github.com/codeyogi911"
},
"homepage": "https://github.com/derrickko/clify",
"repository": "https://github.com/derrickko/clify",
"homepage": "https://github.com/codeyogi911/clify",
"repository": "https://github.com/codeyogi911/clify",
"license": "MIT",
"keywords": ["cli-generator", "api", "openapi", "codegen", "agent"]
"keywords": ["cli-generator", "api", "openapi", "codegen", "agent"],
"skills": [
{ "name": "clify-scaffold", "source": "skills/clify-scaffold/SKILL.md" },
{ "name": "clify-validate", "source": "skills/clify-validate/SKILL.md" },
{ "name": "clify-sync", "source": "skills/clify-sync/SKILL.md" }
],
"capabilities": ["network", "codegen", "file-write"]
}
22 changes: 22 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: test
on:
push:
pull_request:
jobs:
clify:
runs-on: ubuntu-latest
strategy:
matrix:
node: ["20", "22"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: clify unit tests
run: npm test
- name: validate exemplar
run: node bin/clify.mjs validate examples/jsonplaceholder-cli
- name: exemplar tests
working-directory: examples/jsonplaceholder-cli
run: npm test
267 changes: 67 additions & 200 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,258 +1,125 @@
<h1 align="center">clify</h1>

<p align="center">
<strong>Paste a URL. Get a CLI.</strong>
<strong>Paste a URL. Get a tested, A+ grade CLI.</strong>
</p>

<p align="center">
A Claude Code plugin that turns any API documentation into a self-updating CLI repo.
A Claude Code plugin that generates Node.js CLIs from API documentation by copying a hand-crafted exemplar, mechanically substituting API-specific content, and verifying with a deterministic validation gate. Inspired by <a href="https://github.com/google/agents-cli">google/agents-cli</a>.
</p>

<p align="center">
<a href="https://github.com/derrickko/clify/blob/main/LICENSE"><img src="https://img.shields.io/github/license/derrickko/clify?style=flat" alt="License"></a>
<a href="https://github.com/codeyogi911/clify/blob/main/LICENSE"><img src="https://img.shields.io/github/license/codeyogi911/clify?style=flat" alt="License"></a>
<a href="#install"><img src="https://img.shields.io/badge/Claude_Code-plugin-blueviolet?style=flat" alt="Claude Code plugin"></a>
<img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen?style=flat" alt="Node 20+">
</p>

---

```
You: /clify https://developer.calendly.com/api-docs

Claude: Fetching docs... detected REST API.
Crawling 8 doc pages...

Detected API: Calendly
Base URL: https://api.calendly.com
Auth: Bearer token via CALENDLY_API_KEY
## Why

Resources (15 endpoints):
events: list, get, cancel
scheduling-links: list, create
users: get, list
invitees: list, get, no-show
webhooks: list, get, create, delete
organizations: get, invite
MCPs are heavy; CLIs are the natural fit for agents. clify produces CLIs that are:

CLI name: calendly-cli
- **Tested by default.** Every generated repo ships with smoke + integration tests and CI on Node 20 & 22.
- **Verifiable.** A deterministic validation gate (`clify validate`) checks 8 categories — manifest consistency, coverage bookkeeping, structural reachability, declared nuances, secrets, CI, and tests.
- **Reproducible.** The deterministic phases (copy + rename + validate) are pure JS — same pass/fail for any agent.
- **Honest.** Endpoints that get dropped require an explicit reason in `coverage.json`. No silent omissions.

Recommendations:
1. Include all 6 resources — small enough to ship as one CLI.
2. Map DELETE /scheduled_events/{uuid} → events cancel (not
events delete) — Calendly treats this as a cancellation.
## Architecture

Before generating, one question:
Docs show both OAuth and Personal Access Token auth.
Recommendation: Personal Access Token only — simpler for
CLI/agent use. OK?
clify is **a binary + skills**, on the same model as `google/agents-cli`:

You: yes, ship it
| Layer | What it does | What runs it |
|---|---|---|
| **Skills** | Fetch docs, parse free-form HTML/Markdown, consult the user on tradeoffs, rewrite per-API content. | LLM (Claude/Codex) |
| **`bin/clify.mjs`** | `clify validate <dir>` — full validation gate. `clify scaffold-init <api-name>` — copy exemplar + rename. `clify sync-check <dir>` — re-fetch docs, hash diff. | Pure JS, no LLM |

Claude: Generated ./calendly-cli/ with:
- 6 resources, 15 actions
- CLI: bin/calendly-cli.mjs
- Skills: skills/calendly/SKILL.md, skills/sync/SKILL.md
- Tests: 15 passing

Install as Claude Code plugin:
claude plugin add ./calendly-cli
```
Anything verifiable by code goes in the binary. Anything requiring judgment stays in skills. The binary is what makes verification reproducible across agent vendors.

## Install

In a Claude Code session:

```
/plugin marketplace add derrickko/clify
/plugin install clify@derrickko-clify
/plugin install codeyogi911/clify
```

Or from a local clone:
Or clone and link:

```bash
git clone https://github.com/derrickko/clify.git
```
```
/plugin add ./clify
git clone https://github.com/codeyogi911/clify
cd clify
npm install
npm link # makes `clify` available as a CLI
```

## What You Get
## Use

One command produces a complete, installable repo:
Inside Claude Code:

```
calendly-cli/
├── bin/calendly-cli.mjs ← zero-dep CLI (Node.js built-ins only)
├── skills/calendly/SKILL.md ← Claude Code skill with guided setup
├── skills/sync/SKILL.md ← detects doc changes, regenerates
├── knowledge/ ← patterns learned from usage
├── test/smoke.test.mjs ← structural tests (pass without API key)
├── .claude-plugin/ ← plugin registration
├── AGENTS.md ← Codex / OpenAI agent instructions
├── .clify.json ← metadata + content hash for sync
├── .env.example ← annotated credential template
├── package.json
└── LICENSE (MIT)
/clify-scaffold https://docs.example.com/api
```

The generated CLI works three ways:

| Mode | How | Example |
|------|-----|---------|
| **Standalone** | Run directly from terminal | `calendly-cli events list --status active` |
| **Claude Code plugin** | Install and use conversationally | `"cancel all my Calendly events for next Friday"` |
| **Codex / agent** | Reads AGENTS.md for autonomous use | Agent runs CLI commands with structured JSON output |

## Features

| | Feature | Details |
|-|---------|---------|
| **Zero deps** | Generated CLIs use only Node.js built-ins | No `node_modules`, no supply chain risk |
| **Any format** | OpenAPI specs parsed directly; HTML/Markdown crawled and extracted | Structured specs preferred for accuracy |
| **Self-update** | `/sync` re-crawls docs, diffs content hashes, regenerates on change | Knowledge files preserved across syncs |
| **Guided setup** | Generated skill walks through auth + defaults on first use | Auto-detects pervasive parameters (e.g., `workspace_id`) |
| **Knowledge system** | Learns gotchas, patterns, and shortcuts as you use the CLI | Agents consult knowledge before every command |
| **Smoke tests** | Every generated repo ships with structural tests | Tests pass with no API key — validates CLI shape, not API responses |
| **Agent-native** | Structured JSON output, error taxonomy, three-level `--help` | Agents discover flags at runtime via `--help` |
| **Consulted generation** | Shows parsed endpoints and recommendations before writing code | You approve, override, or refine before anything is generated |
The skill walks the 13-step pipeline (fetch → parse → consult → init → substitute → validate → simplify → report) and produces `<api-name>-cli/` next to the current directory.

## Usage
You can also call the binary verbs directly:

```
/clify <api-docs-url>
clify validate ./my-api-cli # check a generated repo
clify scaffold-init demo-api --target . # copy exemplar + rename only
clify sync-check ./my-api-cli # detect upstream doc drift
clify --help
```

That's it. clify fetches, parses, asks you to confirm, generates, and tests.
## What "A+" means

### Examples
Every check in [`references/validation-gate.md`](references/validation-gate.md) passes:

```bash
# From OpenAPI specs (highest accuracy)
/clify https://api.example.com/openapi.json
- `package.json` ↔ `plugin.json` ↔ `marketplace.json` are consistent
- Every endpoint has `included: true` or `dropped: true` + a reason
- Every resource × action is reachable via `--help`
- Hard-fail nuances (pagination, idempotency, multipart, deprecated) have artifacts
- No real-shaped secrets in source
- CI runs `npm test` on Node 20 + 22
- `npm test` exits 0

# From HTML documentation
/clify https://developer.calendly.com/api-docs
The exemplar at [`examples/jsonplaceholder-cli/`](examples/jsonplaceholder-cli/) is the canonical A+ implementation. Run the gate against it:

# From Markdown docs
/clify https://raw.githubusercontent.com/org/repo/main/docs/api.md
```

### Generated CLI in Action

Every generated CLI follows the same resource-action pattern:

```bash
# CRUD operations map naturally
calendly-cli events list --status active --json
calendly-cli webhooks create --url https://hook.example.com --events invitee.created
calendly-cli scheduling-links create --owner-uri <user-uri> --max-event-count 1

# Global flags work on every command
calendly-cli invitees list --event <uri> --all # auto-paginate
calendly-cli events get --uuid <uuid> --verbose # show request/response details

# Three-level help for runtime discovery
calendly-cli --help # list all resources
calendly-cli events --help # list actions for events
calendly-cli events cancel --help # show flags with descriptions

# Structured errors for agents
calendly-cli events cancel --uuid bad
# → { "type": "error", "code": "not_found", "message": "...", "retryable": false }
node bin/clify.mjs validate examples/jsonplaceholder-cli
```

### Self-Update

When the API changes, the generated `/sync` skill keeps your CLI current:
## Testing

```
/sync
→ "3 new endpoints, 1 removed, 2 modified"
→ Regenerates CLI + skills
→ Runs smoke tests
→ Reviews knowledge/ for stale entries
npm test # clify unit tests + deliberate-break tests
npm run validate-exemplar # run the gate against the bundled exemplar
```

Content hashes in `.clify.json` track exactly what changed. Knowledge files survive regeneration, so your learned patterns carry forward.

### Knowledge System
The clify CI workflow (`.github/workflows/test.yml`) runs both, plus the exemplar's own test suite, on Node 20 and 22.

As agents use the generated CLI, they write down what they learn:
## Repo layout

```yaml
# knowledge/upload-content-type.md
---
type: gotcha
command: "files upload"
learned: 2026-04-06
confidence: high
---
Upload endpoint returns 422 if Content-Type header is missing.
Always include --content-type application/octet-stream for binary uploads.
```

Four knowledge types: **gotcha** (error → recovery), **pattern** (common flag combos), **shortcut** (multi-step workflows), **quirk** (API contradicts docs). The generated skill reads all knowledge files before every command, so accumulated patterns carry forward without touching code.

## How It Works

clify is a pure Claude Code skill with no runtime dependencies. The generation pipeline:

1. **Fetch** — pulls the docs URL
2. **Detect** — checks for OpenAPI/Swagger (parsed directly) vs HTML/Markdown (crawled up to depth 2)
3. **Parse** — extracts endpoints, auth scheme, resource structure, pervasive parameters
4. **Consult** — presents findings with opinionated recommendations; you confirm before generating
5. **Generate** — writes all files following rigid conventions ([`conventions.md`](skills/clify/references/conventions.md))
6. **Validate** — runs smoke tests, scans for leaked secrets, self-reviews generated skills
7. **Report** — summary + install command

OpenAPI specs skip crawling entirely — structured data means higher accuracy and fewer questions.

<details>
<summary>Error taxonomy in generated CLIs</summary>

Every generated CLI maps HTTP errors to a standard taxonomy that agents can act on programmatically:

| Code | Retryable | When |
|------|-----------|------|
| `auth_missing` | No | No API key in `.env` |
| `auth_invalid` | No | Key rejected (401) |
| `validation_error` | No | Bad request (400, 422) |
| `not_found` | No | Resource doesn't exist (404) |
| `forbidden` | No | Insufficient permissions (403) |
| `conflict` | No | State conflict (409) |
| `rate_limited` | Yes | Too many requests (429) |
| `server_error` | Yes | API server error (5xx) |
| `network_error` | Yes | Connection failed |
| `timeout` | Yes | Request exceeded timeout |

Retry logic lives in the skill wrapper, not the CLI — the agent decides when and how to retry.

</details>

<details>
<summary>Generated CLI conventions</summary>

All generated CLIs follow the same contracts:

- **Resource-action pattern:** `<cli> <resource> <action> [flags]`
- **Standard CRUD mapping:** `list`, `get`, `create`, `update`, `delete`
- **Non-CRUD verbs:** use the API's own terminology (`send`, `verify`, `cancel`)
- **Nesting cap:** 2 levels max; deeper paths flatten to flags
- **Global flags:** `--json`, `--dry-run`, `--help`, `--version`, `--verbose`, `--all`
- **Per-action flags:** declared via `_flags` metadata — single source of truth for both parsing and help text
- **`.env` loading:** reads from repo root only, never overrides shell env vars
- **Pagination:** one page by default, `--all` auto-paginates
- **`--body <json>`:** escape hatch on every mutating endpoint

See [`conventions.md`](skills/clify/references/conventions.md) for the full specification.

</details>

## Contributing

Contributions welcome.

- [Report a bug](https://github.com/derrickko/clify/issues/new?labels=bug)
- [Request a feature](https://github.com/derrickko/clify/issues/new?labels=enhancement)
clify/
├── bin/clify.mjs top-level binary (verbs)
├── lib/
│ ├── validate.mjs validation gate impl
│ ├── scaffold-init.mjs file-copy + rename
│ └── sync-check.mjs hash-diff
├── skills/
│ ├── clify-scaffold/SKILL.md the 13-step generation pipeline
│ ├── clify-validate/SKILL.md wraps `clify validate`
│ └── clify-sync/SKILL.md wraps `clify sync-check` + regeneration
├── examples/jsonplaceholder-cli/ canonical A+ exemplar
├── references/
│ ├── conventions.md contracts every generated CLI honors
│ └── validation-gate.md every check the gate enforces
├── test/clify.test.mjs unit + deliberate-break tests
└── .github/workflows/test.yml CI (Node 20, 22)
```

## License

[MIT](LICENSE)
MIT — see [LICENSE](LICENSE).
Loading
Loading