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
20 changes: 20 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "html-as-cli-panel-skill",
"interface": {
"displayName": "HTML as CLI Panel Skill"
},
"plugins": [
{
"name": "html-as-cli-panel-skill",
"source": {
"source": "local",
"path": "./codex"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
19 changes: 19 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "html-as-cli-panel-skill",
"owner": {
"name": "rob163"
},
"metadata": {
"description": "Agent skill for creating static, copy-only HTML command panels from repeat-use CLI workflows."
},
"plugins": [
{
"name": "html-as-cli-panel-skill",
"source": {
"source": "github",
"repo": "rob163/html-as-cli-panel-skill"
},
"description": "Create localStorage-backed HTML command panels for project CLI workflows."
}
]
}
12 changes: 12 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "html-as-cli-panel-skill",
"description": "Agent skill for creating static, copy-only HTML command panels from repeat-use CLI workflows.",
"version": "0.1.0",
"author": {
"name": "rob163",
"url": "https://github.com/rob163"
},
"homepage": "https://github.com/rob163/html-as-cli-panel-skill",
"repository": "https://github.com/rob163/html-as-cli-panel-skill",
"license": "MIT"
}
89 changes: 73 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,96 @@ do not need to install it separately — `npx skills` runs it on demand.
Use the installer so the target agent receives the correct layout. This avoids
fragile file-placement mistakes.

Install into the current project (shared with the repo via git):
### skills CLI

Install into the current project:

```bash
npx skills add rob163/html-as-cli-panel-skill --agent cursor
npx skills add rob163/html-as-cli-panel-skill
```

Install globally for one agent (available in every project on your machine):
Install for a specific agent:

```bash
npx skills add rob163/html-as-cli-panel-skill --global --agent cursor
npx skills add rob163/html-as-cli-panel-skill --agent codex
npx skills add rob163/html-as-cli-panel-skill --agent claude-code
```

Replace `cursor` with your agent: `codex`, `claude-code`, and others are
supported. Omit `--agent` only if you want the CLI to auto-detect installed
agents or prompt you to choose.

Other examples:
Install globally instead of project-local:

```bash
# Codex, project-local
npx skills add rob163/html-as-cli-panel-skill --agent codex

# Claude Code, global
npx skills add rob163/html-as-cli-panel-skill --global --agent codex
npx skills add rob163/html-as-cli-panel-skill --global --agent claude-code
```

Skip confirmation prompts when installing in scripts:

# Skip confirmation prompts (useful in scripts)
npx skills add rob163/html-as-cli-panel-skill --global --agent cursor --yes
```bash
npx skills add rob163/html-as-cli-panel-skill --global --agent codex --yes
```

Verify installation:

```bash
npx skills ls -g -a cursor
npx skills ls -g -a codex
```

### Codex plugin

Codex can install this repository as a plugin marketplace. This path uses the
checked-in `.agents/plugins/marketplace.json` and `codex/.codex-plugin/plugin.json`
files, which expose the same `cli-panel` skill through Codex's plugin system.

```bash
codex plugin marketplace add rob163/html-as-cli-panel-skill
codex plugin add html-as-cli-panel-skill@html-as-cli-panel-skill
```

For a local clone:

```bash
git clone https://github.com/rob163/html-as-cli-panel-skill
codex plugin marketplace add ./html-as-cli-panel-skill
codex plugin add html-as-cli-panel-skill@html-as-cli-panel-skill
```

Restart Codex or start a new thread if the installed skill does not appear
immediately.

### Claude Code plugin

Install as a versioned Claude Code plugin from inside Claude Code:

```text
/plugin marketplace add rob163/html-as-cli-panel-skill
/plugin install html-as-cli-panel-skill@html-as-cli-panel-skill
```

The plugin uses the `skills/cli-panel` package in this repository, so the
Claude Code plugin and direct skill installs stay aligned.

### git clone

Clone directly into the agent's skills directory when you prefer a simple
manual install.

Codex:

```bash
git clone https://github.com/rob163/html-as-cli-panel-skill "${CODEX_HOME:-$HOME/.codex}/skills/cli-panel"
```

Claude Code:

```bash
git clone https://github.com/rob163/html-as-cli-panel-skill ~/.claude/skills/cli-panel
```

Restart the agent after cloning. To update later:

```bash
git -C "${CODEX_HOME:-$HOME/.codex}/skills/cli-panel" pull
git -C ~/.claude/skills/cli-panel pull
```

## Development
Expand Down
18 changes: 18 additions & 0 deletions codex/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "html-as-cli-panel-skill",
"version": "0.1.0",
"description": "Agent skill for creating static, copy-only HTML command panels from repeat-use CLI workflows.",
"author": {
"name": "rob163",
"url": "https://github.com/rob163"
},
"homepage": "https://github.com/rob163/html-as-cli-panel-skill",
"repository": "https://github.com/rob163/html-as-cli-panel-skill",
"license": "MIT",
"skills": "./skills/",
"interface": {
"displayName": "HTML as CLI Panel Skill",
"shortDescription": "Create static HTML command panels for project CLI workflows.",
"category": "Productivity"
}
}
1 change: 1 addition & 0 deletions codex/skills
61 changes: 60 additions & 1 deletion scripts/validate-skill.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { readFile, access } from "node:fs/promises";
const requiredFiles = [
"SKILL.md",
"assets/cli-panel.html",
"LICENSE"
"LICENSE",
".agents/plugins/marketplace.json",
".claude-plugin/marketplace.json",
".claude-plugin/plugin.json",
"codex/.codex-plugin/plugin.json",
"codex/skills",
"skills/cli-panel/SKILL.md",
"skills/cli-panel/assets/cli-panel.html"
];

async function assertFile(path) {
Expand Down Expand Up @@ -66,12 +73,64 @@ async function assertTemplate() {
}
}

async function assertJson(path) {
const raw = await readFile(path, "utf8");
try {
return JSON.parse(raw);
} catch (error) {
throw new Error(`${path} must contain valid JSON: ${error.message}`);
}
}

async function assertMirroredSkillPackage() {
const rootSkill = await readFile("SKILL.md", "utf8");
const pluginSkill = await readFile("skills/cli-panel/SKILL.md", "utf8");
if (rootSkill !== pluginSkill) {
throw new Error("skills/cli-panel/SKILL.md must match root SKILL.md");
}

const rootTemplate = await readFile("assets/cli-panel.html", "utf8");
const pluginTemplate = await readFile("skills/cli-panel/assets/cli-panel.html", "utf8");
if (rootTemplate !== pluginTemplate) {
throw new Error("skills/cli-panel/assets/cli-panel.html must match assets/cli-panel.html");
}
}

async function assertPluginMetadata() {
const codexPlugin = await assertJson("codex/.codex-plugin/plugin.json");
if (codexPlugin.name !== "html-as-cli-panel-skill") {
throw new Error("Codex plugin name must be html-as-cli-panel-skill");
}
if (codexPlugin.skills !== "./skills/") {
throw new Error("Codex plugin skills path must point to ./skills/");
}

const codexMarketplace = await assertJson(".agents/plugins/marketplace.json");
const codexEntry = codexMarketplace.plugins?.[0];
if (codexEntry?.source?.path !== "./codex") {
throw new Error("Codex marketplace source.path must be ./codex");
}

const claudePlugin = await assertJson(".claude-plugin/plugin.json");
if (claudePlugin.name !== "html-as-cli-panel-skill") {
throw new Error("Claude plugin name must be html-as-cli-panel-skill");
}

const claudeMarketplace = await assertJson(".claude-plugin/marketplace.json");
const claudeEntry = claudeMarketplace.plugins?.[0];
if (claudeEntry?.source?.repo !== "rob163/html-as-cli-panel-skill") {
throw new Error("Claude plugin marketplace repo must be rob163/html-as-cli-panel-skill");
}
}

for (const file of requiredFiles) {
await assertFile(file);
}

const skill = await readFile("SKILL.md", "utf8");
assertFrontmatter(parseFrontmatter(skill));
await assertTemplate();
await assertMirroredSkillPackage();
await assertPluginMetadata();

console.log("Skill package validation passed.");
Loading
Loading