mirror of
https://github.com/HKUDS/CLI-Anything.git
synced 2026-10-29 17:43:44 +08:00
launching CLI-Hub
This commit is contained in:
@@ -25,6 +25,7 @@ Fixes #<!-- issue number -->
|
||||
- [ ] Unit tests at `cli_anything/<software>/tests/test_core.py` are present and pass without backend
|
||||
- [ ] E2E tests at `cli_anything/<software>/tests/test_full_e2e.py` are present
|
||||
- [ ] `README.md` includes the new software (with link to harness directory)
|
||||
- [ ] `registry.json` includes an entry for the new software (for the [CLI-Hub](https://hkuds.github.io/CLI-Anything/hub/))
|
||||
- [ ] `repl_skin.py` in `utils/` is an unmodified copy from the plugin
|
||||
|
||||
### For Existing CLI Modifications
|
||||
@@ -34,6 +35,7 @@ Fixes #<!-- issue number -->
|
||||
- [ ] All unit tests pass: `python3 -m pytest cli_anything/<software>/tests/test_core.py -v`
|
||||
- [ ] All E2E tests pass: `python3 -m pytest cli_anything/<software>/tests/test_full_e2e.py -v`
|
||||
- [ ] No test regressions — no previously passing tests were removed or weakened
|
||||
- [ ] `registry.json` entry is updated if version, description, or requirements changed
|
||||
|
||||
### General Checklist
|
||||
|
||||
|
||||
@@ -102,3 +102,9 @@ assets/gen_typing_gif.py
|
||||
!opencode-commands/
|
||||
!/qoder-plugin/
|
||||
|
||||
# Step 10: Allow CLI Hub registry and frontend
|
||||
!/registry.json
|
||||
!/docs/
|
||||
/docs/*
|
||||
!/docs/hub/
|
||||
|
||||
|
||||
+32
-1
@@ -14,7 +14,8 @@ Adding a new CLI harness is the most impactful contribution. Before submitting a
|
||||
2. **`SKILL.md`** — the AI-discoverable skill definition exists inside the Python package at `cli_anything/<software>/SKILL.md`.
|
||||
3. **Tests** — unit tests (`test_core.py`, passable without backend) and E2E tests (`test_full_e2e.py`) are present and passing.
|
||||
4. **`README.md`** — the project README includes the new software with a link to its harness directory.
|
||||
5. **`repl_skin.py`** — an unmodified copy from the plugin exists in `utils/`.
|
||||
5. **`registry.json`** — add an entry for the new software so it appears on the [CLI-Hub](https://hkuds.github.io/CLI-Anything/hub/).
|
||||
6. **`repl_skin.py`** — an unmodified copy from the plugin exists in `utils/`.
|
||||
|
||||
### B) New Features
|
||||
|
||||
@@ -32,6 +33,36 @@ Bug fixes resolve incorrect behavior in existing harnesses or the plugin.
|
||||
- Include a test that reproduces the bug and verifies the fix.
|
||||
- Ensure all existing tests for the affected harness still pass.
|
||||
|
||||
## CLI-Hub & Registry
|
||||
|
||||
All available CLIs are listed in `registry.json` at the repo root and displayed on the [CLI-Hub](https://hkuds.github.io/CLI-Anything/hub/). The hub reads `registry.json` directly from `main`, so it updates immediately when a PR is merged.
|
||||
|
||||
### Adding a new CLI to the Hub
|
||||
|
||||
Include an entry in `registry.json` as part of your PR. Each entry has this shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-software",
|
||||
"display_name": "My Software",
|
||||
"version": "1.0.0",
|
||||
"description": "Short description of what the CLI does",
|
||||
"requires": "backend software or null",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=my-software/agent-harness",
|
||||
"entry_point": "cli-anything-my-software",
|
||||
"skill_md": "my-software/agent-harness/cli_anything/my_software/skills/SKILL.md",
|
||||
"category": "category-name"
|
||||
}
|
||||
```
|
||||
|
||||
### Updating an existing CLI on the Hub
|
||||
|
||||
When you modify an existing harness, update its `registry.json` entry in the same PR:
|
||||
|
||||
- Bump the `version` field to reflect the change.
|
||||
- Update `description`, `requires`, or `category` if they changed.
|
||||
- The hub will reflect the update as soon as the PR is merged to `main`.
|
||||
|
||||
## Development Setup
|
||||
|
||||
Each generated CLI lives in `<software>/agent-harness/` and is an independent Python package:
|
||||
|
||||
@@ -7,6 +7,7 @@ CLI-Anything: Bridging the Gap Between AI Agents and the World's Software</stron
|
||||
|
||||
<p align="center">
|
||||
<a href="#-quick-start"><img src="https://img.shields.io/badge/Quick_Start-5_min-blue?style=for-the-badge" alt="Quick Start"></a>
|
||||
<a href="https://hkuds.github.io/CLI-Anything/hub/"><img src="https://img.shields.io/badge/CLI_Hub-Browse_%26_Install-ff69b4?style=for-the-badge" alt="CLI Hub"></a>
|
||||
<a href="#-demonstrations"><img src="https://img.shields.io/badge/Demos-13_Apps-green?style=for-the-badge" alt="Demos"></a>
|
||||
<a href="#-test-results"><img src="https://img.shields.io/badge/Tests-1%2C588_Passing-brightgreen?style=for-the-badge" alt="Tests"></a>
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge" alt="License"></a>
|
||||
@@ -24,6 +25,8 @@ CLI-Anything: Bridging the Gap Between AI Agents and the World's Software</stron
|
||||
|
||||
**One Command Line**: Make any software agent-ready for OpenClaw, nanobot, Cursor, Claude Code, etc. [**中文文档**](README_CN.md) | [**日本語ドキュメント**](README_JA.md)
|
||||
|
||||
**🌐 [CLI-Hub](https://hkuds.github.io/CLI-Anything/hub/)**: Browse & install all community CLIs in one place. Have a CLI for a new software? [Open a PR](https://github.com/HKUDS/CLI-Anything/blob/main/CONTRIBUTING.md) — the hub updates instantly.
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/cli-typing.gif" alt="CLI-Anything typing demo" width="800">
|
||||
</p>
|
||||
@@ -38,6 +41,8 @@ CLI-Anything: Bridging the Gap Between AI Agents and the World's Software</stron
|
||||
|
||||
> Thanks to all invaluable efforts from the community! More updates continuously on the way everyday..
|
||||
|
||||
- **2026-03-17** 🌐 Launched the **[CLI-Hub](https://hkuds.github.io/CLI-Anything/hub/)** — a central registry where you can browse, search, and install any CLI with a single `pip` command. Contributors can add new CLIs or update existing ones by simply opening a PR with a `registry.json` entry. The hub updates automatically on merge.
|
||||
|
||||
- **2026-03-16** 🤖 Added **SKILL.md generation** (Phase 6.5) — every generated CLI now ships with an AI-discoverable skill definition inside the Python package. ReplSkin auto-detects the skill file after `pip install`, and the REPL banner displays the absolute path for agents. Includes `skill_generator.py`, Jinja2 template, `package_data` in all setup.py files, and 51 new tests.
|
||||
|
||||
- **2026-03-15** 🐾 Support for **OpenClaw** from the community! Merged Windows `cygpath` guard to ensure CLI-Anything works reliably in Windows bash environments. Community contributions continue to strengthen cross-platform support.
|
||||
|
||||
@@ -0,0 +1,482 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CLI-Hub</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #0d1117;
|
||||
--surface: #161b22;
|
||||
--border: #30363d;
|
||||
--text: #e6edf3;
|
||||
--text-muted: #8b949e;
|
||||
--accent: #58a6ff;
|
||||
--accent-hover: #79c0ff;
|
||||
--green: #3fb950;
|
||||
--tag-bg: #1f2937;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ── Header ── */
|
||||
.header {
|
||||
text-align: center;
|
||||
padding: 3.5rem 2rem 2.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.8rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.header h1 span { color: var(--accent); }
|
||||
|
||||
.tagline {
|
||||
font-size: 1.2rem;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.5;
|
||||
max-width: 800px;
|
||||
margin: 0 auto 1.25rem;
|
||||
}
|
||||
|
||||
.tagline strong { color: var(--text); font-weight: 600; }
|
||||
|
||||
.header-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.header-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0.45rem 1rem;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
transition: border-color 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.header-btn:hover { border-color: var(--accent); color: var(--accent); }
|
||||
|
||||
.cta {
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.65;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.cta em { color: var(--accent); font-style: normal; font-weight: 600; }
|
||||
|
||||
.stats {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 3rem;
|
||||
margin-top: 1.75rem;
|
||||
}
|
||||
|
||||
.stat-num {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* ── Controls ── */
|
||||
.controls {
|
||||
max-width: 1200px;
|
||||
margin: 1.5rem auto;
|
||||
padding: 0 1rem;
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
padding: 0.6rem 1rem;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
color: var(--text);
|
||||
font-size: 0.95rem;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search:focus { border-color: var(--accent); }
|
||||
|
||||
.filter-btn {
|
||||
padding: 0.45rem 0.85rem;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.82rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.filter-btn:hover { border-color: var(--accent); color: var(--text); }
|
||||
.filter-btn.active { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 600; }
|
||||
|
||||
/* ── Grid ── */
|
||||
.grid {
|
||||
max-width: 1200px;
|
||||
margin: 1rem auto 3rem;
|
||||
padding: 0 1rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 1.25rem;
|
||||
transition: border-color 0.15s;
|
||||
}
|
||||
|
||||
.card:hover { border-color: var(--accent); }
|
||||
|
||||
.card-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card-title a {
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card-title a:hover { color: var(--accent); }
|
||||
|
||||
.card-title a svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-left: 4px;
|
||||
vertical-align: middle;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.card-title a:hover svg { opacity: 1; }
|
||||
|
||||
.card-version {
|
||||
font-size: 0.75rem;
|
||||
color: var(--green);
|
||||
background: rgba(63, 185, 80, 0.15);
|
||||
padding: 0.15rem 0.5rem;
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card-desc {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.card-requires {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.card-requires strong { color: var(--text); }
|
||||
|
||||
.card-install {
|
||||
background: #0d1117;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
padding: 0.5rem 0.75rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.card-install code {
|
||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
||||
font-size: 0.78rem;
|
||||
color: var(--accent);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
background: none;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
transition: all 0.15s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.copy-btn:hover { color: var(--text); border-color: var(--accent); }
|
||||
|
||||
.card-links {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.card-links a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card-links a:hover { text-decoration: underline; color: var(--accent-hover); }
|
||||
|
||||
.category-tag {
|
||||
font-size: 0.72rem;
|
||||
color: var(--text-muted);
|
||||
background: var(--tag-bg);
|
||||
padding: 0.1rem 0.45rem;
|
||||
border-radius: 4px;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.empty {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 3rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* ── Footer ── */
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 2rem 1rem;
|
||||
border-top: 1px solid var(--border);
|
||||
color: var(--text-muted);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.footer a { color: var(--accent); text-decoration: none; }
|
||||
.footer a:hover { text-decoration: underline; }
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.grid { grid-template-columns: 1fr; }
|
||||
.header h1 { font-size: 2rem; }
|
||||
.header { padding: 2rem 1rem 1.5rem; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>CLI-<span>Anything</span> Hub</h1>
|
||||
<p class="tagline"><strong>Any software. Any codebase. Any Web API.</strong> Generate an agent-native CLI and let AI agents operate it — install with a single pip command.</p>
|
||||
<div class="header-links">
|
||||
<a class="header-btn" href="https://github.com/HKUDS/CLI-Anything" target="_blank">
|
||||
<svg viewBox="0 0 98 96" width="18" height="18" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6C29.304 70.25 17.9 66.013 17.9 47.02c0-5.52 1.94-10.046 5.127-13.58-.486-1.302-2.264-6.437.486-13.34 0 0 4.206-1.302 13.59 5.216 3.963-1.14 8.17-1.628 12.34-1.628 4.17 0 8.376.568 12.34 1.628 9.384-6.518 13.59-5.216 13.59-5.216 2.75 6.903.972 12.038.486 13.34 3.268 3.534 5.127 8.06 5.127 13.58 0 19.074-11.485 23.15-22.328 24.29 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"/></svg>
|
||||
Star on GitHub
|
||||
</a>
|
||||
<a class="header-btn" href="https://github.com/HKUDS/CLI-Anything/blob/main/CONTRIBUTING.md" target="_blank">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"/></svg>
|
||||
Contributing Guide
|
||||
</a>
|
||||
<a class="header-btn" href="https://github.com/HKUDS/CLI-Anything/blob/main/.github/PULL_REQUEST_TEMPLATE.md" target="_blank">
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"/></svg>
|
||||
PR Template
|
||||
</a>
|
||||
</div>
|
||||
<p class="cta">We welcome contributions for <em>any</em> application — desktop apps, dev tools, cloud services, SaaS APIs, creative suites, and beyond. If it has a GUI or an API, it deserves an agent-native CLI. Open a PR and bring it to the hub!</p>
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<div class="stat-num" id="cli-count">-</div>
|
||||
<div class="stat-label">CLIs Available</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-num" id="category-count">-</div>
|
||||
<div class="stat-label">Categories</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<input class="search" type="text" placeholder="Search CLIs..." id="search">
|
||||
<div id="filters"></div>
|
||||
</div>
|
||||
|
||||
<div class="grid" id="grid"></div>
|
||||
|
||||
<div class="footer">
|
||||
<p>Want to add or update a CLI? Read the <a href="https://github.com/HKUDS/CLI-Anything/blob/main/CONTRIBUTING.md" target="_blank">Contributing Guide</a> and use the <a href="https://github.com/HKUDS/CLI-Anything/blob/main/.github/PULL_REQUEST_TEMPLATE.md" target="_blank">PR Template</a> — Powered by <a href="https://github.com/HKUDS/CLI-Anything" target="_blank">CLI-Anything</a></p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const REPO = 'https://github.com/HKUDS/CLI-Anything';
|
||||
const REGISTRY_URLS = [
|
||||
'../../registry.json',
|
||||
'https://raw.githubusercontent.com/HKUDS/CLI-Anything/main/registry.json'
|
||||
];
|
||||
const EXTERNAL_LINK_SVG = '<svg viewBox="0 0 16 16" fill="currentColor"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5H4.56l6.72 6.72a.75.75 0 1 1-1.06 1.06L3.5 4.56v2.69a.75.75 0 0 1-1.5 0v-3.5A1.75 1.75 0 0 1 3.75 2Zm7.5 0h1A1.75 1.75 0 0 1 14 3.75v8.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-1a.75.75 0 0 1 1.5 0v1c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25h-1a.75.75 0 0 1 0-1.5Z"/></svg>';
|
||||
|
||||
let clis = [];
|
||||
let activeFilter = 'all';
|
||||
|
||||
async function loadRegistry() {
|
||||
try {
|
||||
let resp;
|
||||
for (const url of REGISTRY_URLS) {
|
||||
try {
|
||||
resp = await fetch(url);
|
||||
if (resp.ok) break;
|
||||
} catch (_) { continue; }
|
||||
}
|
||||
if (!resp || !resp.ok) throw new Error('All sources failed');
|
||||
const data = await resp.json();
|
||||
clis = data.clis;
|
||||
document.getElementById('cli-count').textContent = clis.length;
|
||||
const categories = [...new Set(clis.map(c => c.category))];
|
||||
document.getElementById('category-count').textContent = categories.length;
|
||||
buildFilters(categories);
|
||||
render();
|
||||
} catch (e) {
|
||||
document.getElementById('grid').innerHTML =
|
||||
'<div class="empty">Failed to load registry. <a href="' + REPO + '/blob/main/registry.json" style="color:var(--accent)">Check source</a>.</div>';
|
||||
}
|
||||
}
|
||||
|
||||
const CATEGORY_LABELS = { 'ai': 'AI', '3d': '3D' };
|
||||
function catLabel(cat) {
|
||||
return CATEGORY_LABELS[cat] || cat.charAt(0).toUpperCase() + cat.slice(1);
|
||||
}
|
||||
|
||||
function buildFilters(categories) {
|
||||
const container = document.getElementById('filters');
|
||||
const allBtn = document.createElement('button');
|
||||
allBtn.className = 'filter-btn active';
|
||||
allBtn.textContent = 'All';
|
||||
allBtn.dataset.cat = 'all';
|
||||
allBtn.onclick = () => setFilter('all');
|
||||
container.appendChild(allBtn);
|
||||
|
||||
categories.sort().forEach(cat => {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'filter-btn';
|
||||
btn.textContent = catLabel(cat);
|
||||
btn.dataset.cat = cat;
|
||||
btn.onclick = () => setFilter(cat);
|
||||
container.appendChild(btn);
|
||||
});
|
||||
}
|
||||
|
||||
function setFilter(cat) {
|
||||
activeFilter = cat;
|
||||
document.querySelectorAll('.filter-btn').forEach(b => {
|
||||
b.classList.toggle('active', b.dataset.cat === cat);
|
||||
});
|
||||
render();
|
||||
}
|
||||
|
||||
function render() {
|
||||
const query = document.getElementById('search').value.toLowerCase();
|
||||
const filtered = clis.filter(c => {
|
||||
const matchFilter = activeFilter === 'all' || c.category === activeFilter;
|
||||
const matchSearch = !query ||
|
||||
c.display_name.toLowerCase().includes(query) ||
|
||||
c.description.toLowerCase().includes(query) ||
|
||||
c.name.toLowerCase().includes(query);
|
||||
return matchFilter && matchSearch;
|
||||
});
|
||||
|
||||
const grid = document.getElementById('grid');
|
||||
if (filtered.length === 0) {
|
||||
grid.innerHTML = '<div class="empty">No CLIs match your search.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
grid.innerHTML = filtered.map(c => {
|
||||
const requiresHtml = c.requires
|
||||
? `<div class="card-requires"><strong>Requires:</strong> ${esc(c.requires)}</div>`
|
||||
: '';
|
||||
const skillLink = c.skill_md
|
||||
? `<a href="${REPO}/blob/main/${c.skill_md}" target="_blank">SKILL.md</a>`
|
||||
: '';
|
||||
const sourceLink = `<a href="${REPO}/tree/main/${c.name}/agent-harness" target="_blank">Source</a>`;
|
||||
const titleHtml = c.homepage
|
||||
? `<a href="${esc(c.homepage)}" target="_blank">${esc(c.display_name)}${EXTERNAL_LINK_SVG}</a>`
|
||||
: esc(c.display_name);
|
||||
|
||||
return `
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<span>
|
||||
<span class="card-title">${titleHtml}</span>
|
||||
<span class="category-tag">${catLabel(c.category)}</span>
|
||||
</span>
|
||||
<span class="card-version">v${esc(c.version)}</span>
|
||||
</div>
|
||||
<div class="card-desc">${esc(c.description)}</div>
|
||||
${requiresHtml}
|
||||
<div class="card-install">
|
||||
<code>${esc(c.install_cmd)}</code>
|
||||
<button class="copy-btn" onclick="copyCmd(this, '${esc(c.install_cmd)}')">Copy</button>
|
||||
</div>
|
||||
<div class="card-links">${sourceLink}${skillLink ? ' · ' + skillLink : ''}</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function copyCmd(btn, cmd) {
|
||||
navigator.clipboard.writeText(cmd).then(() => {
|
||||
btn.textContent = 'Copied!';
|
||||
setTimeout(() => btn.textContent = 'Copy', 1500);
|
||||
});
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
if (!s) return '';
|
||||
const d = document.createElement('div');
|
||||
d.textContent = s;
|
||||
return d.innerHTML;
|
||||
}
|
||||
|
||||
document.getElementById('search').addEventListener('input', render);
|
||||
loadRegistry();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"meta": {
|
||||
"repo": "https://github.com/HKUDS/CLI-Anything",
|
||||
"description": "CLI-Hub — Agent-native stateful CLI interfaces for softwares, codebases, and Web Services",
|
||||
"updated": "2026-03-17"
|
||||
},
|
||||
"clis": [
|
||||
{
|
||||
"name": "anygen",
|
||||
"display_name": "AnyGen",
|
||||
"version": "1.0.0",
|
||||
"description": "Generate docs, slides, websites and more via AnyGen cloud API",
|
||||
"requires": "ANYGEN_API_KEY",
|
||||
"homepage": "https://anygen.com",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=anygen/agent-harness",
|
||||
"entry_point": "cli-anything-anygen",
|
||||
"skill_md": "anygen/agent-harness/cli_anything/anygen/skills/SKILL.md",
|
||||
"category": "generation"
|
||||
},
|
||||
{
|
||||
"name": "audacity",
|
||||
"display_name": "Audacity",
|
||||
"version": "1.0.0",
|
||||
"description": "Audio editing and processing via sox",
|
||||
"requires": "sox (apt install sox)",
|
||||
"homepage": "https://www.audacityteam.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=audacity/agent-harness",
|
||||
"entry_point": "cli-anything-audacity",
|
||||
"skill_md": "audacity/agent-harness/cli_anything/audacity/skills/SKILL.md",
|
||||
"category": "audio"
|
||||
},
|
||||
{
|
||||
"name": "blender",
|
||||
"display_name": "Blender",
|
||||
"version": "1.0.0",
|
||||
"description": "3D modeling, animation, and rendering via blender --background --python",
|
||||
"requires": "blender",
|
||||
"homepage": "https://www.blender.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=blender/agent-harness",
|
||||
"entry_point": "cli-anything-blender",
|
||||
"skill_md": "blender/agent-harness/cli_anything/blender/skills/SKILL.md",
|
||||
"category": "3d"
|
||||
},
|
||||
{
|
||||
"name": "comfyui",
|
||||
"display_name": "ComfyUI",
|
||||
"version": "1.0.0",
|
||||
"description": "AI image generation workflow management via ComfyUI REST API",
|
||||
"requires": "ComfyUI running at http://localhost:8188",
|
||||
"homepage": "https://github.com/comfyanonymous/ComfyUI",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=comfyui/agent-harness",
|
||||
"entry_point": "cli-anything-comfyui",
|
||||
"skill_md": null,
|
||||
"category": "ai"
|
||||
},
|
||||
{
|
||||
"name": "drawio",
|
||||
"display_name": "Draw.io",
|
||||
"version": "1.0.0",
|
||||
"description": "Diagram creation and export via draw.io CLI",
|
||||
"requires": "draw.io desktop app",
|
||||
"homepage": "https://www.drawio.com",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=drawio/agent-harness",
|
||||
"entry_point": "cli-anything-drawio",
|
||||
"skill_md": "drawio/agent-harness/cli_anything/drawio/skills/SKILL.md",
|
||||
"category": "diagrams"
|
||||
},
|
||||
{
|
||||
"name": "gimp",
|
||||
"display_name": "GIMP",
|
||||
"version": "1.0.0",
|
||||
"description": "Raster image processing via gimp -i -b (batch mode)",
|
||||
"requires": "gimp (apt install gimp)",
|
||||
"homepage": "https://www.gimp.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=gimp/agent-harness",
|
||||
"entry_point": "cli-anything-gimp",
|
||||
"skill_md": "gimp/agent-harness/cli_anything/gimp/skills/SKILL.md",
|
||||
"category": "image"
|
||||
},
|
||||
{
|
||||
"name": "inkscape",
|
||||
"display_name": "Inkscape",
|
||||
"version": "1.0.0",
|
||||
"description": "SVG vector graphics with export via inkscape --export-filename",
|
||||
"requires": "inkscape (apt install inkscape)",
|
||||
"homepage": "https://inkscape.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=inkscape/agent-harness",
|
||||
"entry_point": "cli-anything-inkscape",
|
||||
"skill_md": "inkscape/agent-harness/cli_anything/inkscape/skills/SKILL.md",
|
||||
"category": "image"
|
||||
},
|
||||
{
|
||||
"name": "kdenlive",
|
||||
"display_name": "Kdenlive",
|
||||
"version": "1.0.0",
|
||||
"description": "Video editing and rendering via melt",
|
||||
"requires": "melt (apt install melt)",
|
||||
"homepage": "https://kdenlive.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=kdenlive/agent-harness",
|
||||
"entry_point": "cli-anything-kdenlive",
|
||||
"skill_md": "kdenlive/agent-harness/cli_anything/kdenlive/skills/SKILL.md",
|
||||
"category": "video"
|
||||
},
|
||||
{
|
||||
"name": "libreoffice",
|
||||
"display_name": "LibreOffice",
|
||||
"version": "1.0.0",
|
||||
"description": "Create and manipulate ODF documents, export to PDF/DOCX/XLSX/PPTX via headless mode",
|
||||
"requires": "libreoffice",
|
||||
"homepage": "https://www.libreoffice.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=libreoffice/agent-harness",
|
||||
"entry_point": "cli-anything-libreoffice",
|
||||
"skill_md": "libreoffice/agent-harness/cli_anything/libreoffice/skills/SKILL.md",
|
||||
"category": "office"
|
||||
},
|
||||
{
|
||||
"name": "mermaid",
|
||||
"display_name": "Mermaid",
|
||||
"version": "1.0.0",
|
||||
"description": "Mermaid Live Editor state files and renderer URLs",
|
||||
"requires": null,
|
||||
"homepage": "https://mermaid.js.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=mermaid/agent-harness",
|
||||
"entry_point": "cli-anything-mermaid",
|
||||
"skill_md": null,
|
||||
"category": "diagrams"
|
||||
},
|
||||
{
|
||||
"name": "obs-studio",
|
||||
"display_name": "OBS Studio",
|
||||
"version": "1.0.0",
|
||||
"description": "Create and manage streaming/recording scenes via command line",
|
||||
"requires": "obs-studio",
|
||||
"homepage": "https://obsproject.com",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=obs-studio/agent-harness",
|
||||
"entry_point": "cli-anything-obs-studio",
|
||||
"skill_md": "obs-studio/agent-harness/cli_anything/obs_studio/skills/SKILL.md",
|
||||
"category": "streaming"
|
||||
},
|
||||
{
|
||||
"name": "shotcut",
|
||||
"display_name": "Shotcut",
|
||||
"version": "1.0.0",
|
||||
"description": "Video editing and rendering via melt/ffmpeg",
|
||||
"requires": "melt (apt install melt), ffmpeg (apt install ffmpeg)",
|
||||
"homepage": "https://shotcut.org",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=shotcut/agent-harness",
|
||||
"entry_point": "cli-anything-shotcut",
|
||||
"skill_md": "shotcut/agent-harness/cli_anything/shotcut/skills/SKILL.md",
|
||||
"category": "video"
|
||||
},
|
||||
{
|
||||
"name": "zoom",
|
||||
"display_name": "Zoom",
|
||||
"version": "1.0.0",
|
||||
"description": "Meeting management via Zoom REST API (OAuth2)",
|
||||
"requires": "Zoom account + OAuth app credentials",
|
||||
"homepage": "https://zoom.us",
|
||||
"install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=zoom/agent-harness",
|
||||
"entry_point": "cli-anything-zoom",
|
||||
"skill_md": "zoom/agent-harness/cli_anything/zoom/skills/SKILL.md",
|
||||
"category": "communication"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user