fix(plugins): move marketplace manifest to repo root for `/plugin marketplace add ruvnet/RuView`
Claude Code looks for `.claude-plugin/marketplace.json` at the cloned repo's ROOT — not in a subdirectory — so `/plugin marketplace add ruvnet/RuView` (and `claude plugin marketplace add ruvnet/RuView`) was failing with "Marketplace file not found". - Move `plugins/.claude-plugin/marketplace.json` → `.claude-plugin/marketplace.json` (repo root); the `ruview` plugin's `source` is now `./plugins/ruview`. - README.md / plugins/ruview/README.md: install instructions now use `/plugin marketplace add ruvnet/RuView` + `/plugin install ruview@ruview` (with `claude --plugin-dir ./plugins/ruview` as the no-install fallback); manifest path references updated. - plugins/ruview/scripts/smoke.sh: resolve the manifest at the repo root; also assert the plugin `source` is `./plugins/ruview`. - ADR-0001 updated (scope, directory contract, smoke contract, consequences). Verified: `claude plugin validate .` + `./plugins/ruview` pass; smoke 13/13; `claude plugin marketplace add ./` → `claude plugin install ruview@ruview` → `claude plugin details ruview` works end-to-end (16 skill-entries + 3 agents). Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
298543913e
commit
df9d3b0eea
|
|
@ -8,8 +8,8 @@
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "ruview",
|
"name": "ruview",
|
||||||
"source": "./ruview",
|
"source": "./plugins/ruview",
|
||||||
"description": "End-to-end RuView toolkit: getting started, ESP32 hardware setup, configuration, sensing applications (presence / vitals / pose / sleep / MAT), camera-free + camera-supervised model training, advanced multistatic sensing, and witness verification"
|
"description": "End-to-end RuView toolkit: getting started, ESP32 hardware setup, configuration, sensing applications (presence / vitals / pose / sleep / MAT), camera-free + camera-supervised model training, advanced multistatic sensing, CLI / API / WASM, mmWave radar, and witness verification"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
12
README.md
12
README.md
|
|
@ -487,15 +487,15 @@ See [`docs/adr/ADR-024-contrastive-csi-embedding-model.md`](docs/adr/ADR-024-con
|
||||||
|
|
||||||
## 🧩 Claude Code & Codex Plugin
|
## 🧩 Claude Code & Codex Plugin
|
||||||
|
|
||||||
RuView ships a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin (and Codex prompt mirror) that wraps the whole workflow — onboarding, ESP32 setup, configuration, sensing apps, model training, advanced multistatic sensing, CLI/API/WASM, mmWave radar, and witness verification — as 9 skills, 7 `/ruview-*` commands, and 3 agents. It lives in [`plugins/ruview/`](plugins/ruview/README.md); the marketplace manifest is [`plugins/.claude-plugin/marketplace.json`](plugins/.claude-plugin/marketplace.json).
|
RuView ships a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin (and Codex prompt mirror) that wraps the whole workflow — onboarding, ESP32 setup, configuration, sensing apps, model training, advanced multistatic sensing, CLI/API/WASM, mmWave radar, and witness verification — as 9 skills, 7 `/ruview-*` commands, and 3 agents. It lives in [`plugins/ruview/`](plugins/ruview/README.md); the marketplace manifest is [`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json) at the repo root.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Try it for one session, no install:
|
# In Claude Code — add this repo as a plugin marketplace, then install:
|
||||||
claude --plugin-dir ./plugins/ruview
|
/plugin marketplace add ruvnet/RuView
|
||||||
|
/plugin install ruview@ruview
|
||||||
|
|
||||||
# Or add the marketplace and install:
|
# Or try it for one session without installing (from a local clone of the repo):
|
||||||
claude plugin marketplace add ./plugins
|
claude --plugin-dir ./plugins/ruview
|
||||||
claude plugin install ruview@ruview
|
|
||||||
|
|
||||||
# Then, in Claude Code:
|
# Then, in Claude Code:
|
||||||
# /ruview-start → onboarding (Docker demo / repo build / live ESP32)
|
# /ruview-start → onboarding (Docker demo / repo build / live ESP32)
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
End-to-end toolkit for **RuView** (WiFi-DensePose): onboarding, ESP32 hardware setup, configuration, sensing applications, model training, advanced multistatic sensing, and witness verification — from practical to advanced.
|
End-to-end toolkit for **RuView** (WiFi-DensePose): onboarding, ESP32 hardware setup, configuration, sensing applications, model training, advanced multistatic sensing, and witness verification — from practical to advanced.
|
||||||
|
|
||||||
Part of the **`ruview` marketplace** (`plugins/.claude-plugin/marketplace.json`).
|
Part of the **`ruview` marketplace** — manifest at the repo root: `.claude-plugin/marketplace.json` (this plugin's `source` is `./plugins/ruview`).
|
||||||
|
|
||||||
## Install / test
|
## Install / test
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Try it locally without installing
|
# In Claude Code — add this repo as a plugin marketplace, then install:
|
||||||
claude --plugin-dir ./plugins/ruview
|
/plugin marketplace add ruvnet/RuView
|
||||||
|
/plugin install ruview@ruview
|
||||||
|
|
||||||
# Or add the whole marketplace
|
# Or try it locally without installing (from a clone of the repo):
|
||||||
claude plugin marketplace add ./plugins
|
claude --plugin-dir ./plugins/ruview
|
||||||
claude plugin install ruview@ruview
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For Codex (OpenAI CLI), see [`codex/`](codex/) — all seven `/ruview-*` commands mirrored as Codex prompts, plus an `AGENTS.md` and install instructions in [`codex/README.md`](codex/README.md).
|
For Codex (OpenAI CLI), see [`codex/`](codex/) — all seven `/ruview-*` commands mirrored as Codex prompts, plus an `AGENTS.md` and install instructions in [`codex/README.md`](codex/README.md).
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
- **Status:** Proposed
|
- **Status:** Proposed
|
||||||
- **Date:** 2026-05-11
|
- **Date:** 2026-05-11
|
||||||
- **Scope:** `plugins/ruview` (and the enclosing `plugins/.claude-plugin/marketplace.json`)
|
- **Scope:** `plugins/ruview` (and the repo-root `.claude-plugin/marketplace.json` that lists it)
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
|
|
@ -10,34 +10,34 @@ RuView (WiFi-DensePose) is a large dual-codebase project (Rust `v2/`, Python `ar
|
||||||
|
|
||||||
## Decision
|
## Decision
|
||||||
|
|
||||||
1. **One mega-plugin, marketplace-listed.** A single plugin `ruview` under `plugins/ruview/`, listed by `plugins/.claude-plugin/marketplace.json` (marketplace name `ruview`). No sub-plugins; the breadth is organized by skill instead.
|
1. **One mega-plugin, marketplace-listed from the repo root.** A single plugin `ruview` under `plugins/ruview/`, listed by `.claude-plugin/marketplace.json` **at the repo root** (marketplace name `ruview`, plugin `source: "./plugins/ruview"`). The manifest sits at the repo root so `claude plugin marketplace add ruvnet/RuView` (and `/plugin marketplace add ruvnet/RuView` in Claude Code) resolve it — Claude Code looks for `.claude-plugin/marketplace.json` at the cloned repo's root, not in subdirectories. No sub-plugins; the breadth is organized by skill instead.
|
||||||
|
|
||||||
2. **Directory contract.**
|
2. **Directory contract.**
|
||||||
```
|
```
|
||||||
plugins/.claude-plugin/marketplace.json
|
.claude-plugin/marketplace.json # REPO ROOT — marketplace name `ruview`, plugin source ./plugins/ruview
|
||||||
plugins/ruview/.claude-plugin/plugin.json # name, description, version, author, homepage, license, keywords — NO skills/commands/agents arrays
|
plugins/ruview/.claude-plugin/plugin.json # name, description, version, author, homepage, license, keywords — NO skills/commands/agents arrays
|
||||||
plugins/ruview/skills/<name>/SKILL.md # frontmatter: name, description, allowed-tools
|
plugins/ruview/skills/<name>/SKILL.md # frontmatter: name, description, allowed-tools
|
||||||
plugins/ruview/commands/<name>.md # frontmatter: description (+ argument-hint)
|
plugins/ruview/commands/<name>.md # frontmatter: description (+ argument-hint)
|
||||||
plugins/ruview/agents/<name>.md # frontmatter: name, description, model
|
plugins/ruview/agents/<name>.md # frontmatter: name, description, model
|
||||||
plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md
|
plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md
|
||||||
plugins/ruview/scripts/smoke.sh # structural contract
|
plugins/ruview/scripts/smoke.sh # structural contract
|
||||||
plugins/ruview/codex/AGENTS.md + codex/prompts/*.md # Codex mirror
|
plugins/ruview/codex/AGENTS.md + codex/README.md + codex/prompts/*.md # Codex mirror
|
||||||
plugins/ruview/README.md # Compatibility + Namespace coordination + Verification + ADR sections
|
plugins/ruview/README.md # Compatibility + Namespace coordination + Verification + ADR sections
|
||||||
```
|
```
|
||||||
Skills/commands/agents are **auto-discovered** from the directory tree — they are deliberately *not* enumerated in `plugin.json`.
|
Skills/commands/agents are **auto-discovered** from the directory tree — they are deliberately *not* enumerated in `plugin.json`.
|
||||||
|
|
||||||
3. **Shell-first skills.** Skills drive RuView's own tooling — `cargo`, `python`, `idf.py` (via the Windows Python-subprocess pattern in `CLAUDE.local.md`), `docker`, `node` scripts. `allowed-tools` is limited to core tools (`Bash Read Write Edit Glob Grep`); **no `mcp__claude-flow__*` dependency** and **no wildcard tools**. The only external CLI referenced is `npx @claude-flow/cli@latest security scan`, and only as an optional step for security changes.
|
3. **Shell-first skills.** Skills drive RuView's own tooling — `cargo`, `python`, `idf.py` (via the Windows Python-subprocess pattern in `CLAUDE.local.md`), `docker`, `node` scripts. `allowed-tools` is limited to core tools (`Bash Read Write Edit Glob Grep`); **no `mcp__claude-flow__*` dependency** and **no wildcard tools**. The only external CLI referenced is `npx @claude-flow/cli@latest security scan`, and only as an optional step for security changes.
|
||||||
|
|
||||||
4. **Namespace.** The plugin claims the `ruview-*` namespace for skills (`ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-verify`), commands (`/ruview-*`), and agents (`ruview-*`). It writes to no `claude-flow` memory namespace. Coexists with the `ruflo` marketplace with zero overlap (`ruview-*` vs. `ruflo-*`); if both are present, defer to `ruflo-agentdb` ADR-0001 §"Namespace convention".
|
4. **Namespace.** The plugin claims the `ruview-*` namespace for skills (`ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-cli-api`, `ruview-mmwave`, `ruview-verify`), commands (`/ruview-*`), and agents (`ruview-*`). It writes to no `claude-flow` memory namespace. Coexists with the `ruflo` marketplace with zero overlap (`ruview-*` vs. `ruflo-*`); if both are present, defer to `ruflo-agentdb` ADR-0001 §"Namespace convention".
|
||||||
|
|
||||||
5. **Codex mirror — full command parity.** Every `/ruview-*` command (`ruview-start`, `ruview-flash`, `ruview-provision`, `ruview-app`, `ruview-train`, `ruview-advanced`, `ruview-verify`) has a matching `codex/prompts/<name>.md`; `codex/AGENTS.md` carries the project rules and `codex/README.md` documents installation. The mirror covers the operator-facing **commands** in full; the additional **skills** (`ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-cli-api`, `ruview-mmwave`, `ruview-verify`) and **agents** have no Codex equivalent — their knowledge is folded into `AGENTS.md` and the prompt files. The smoke script enforces command↔prompt parity.
|
5. **Codex mirror — full command parity.** Every `/ruview-*` command (`ruview-start`, `ruview-flash`, `ruview-provision`, `ruview-app`, `ruview-train`, `ruview-advanced`, `ruview-verify`) has a matching `codex/prompts/<name>.md`; `codex/AGENTS.md` carries the project rules and `codex/README.md` documents installation. The mirror covers the operator-facing **commands** in full; the additional **skills** (`ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-cli-api`, `ruview-mmwave`, `ruview-verify`) and **agents** have no Codex equivalent — their knowledge is folded into `AGENTS.md` and the prompt files. The smoke script enforces command↔prompt parity.
|
||||||
|
|
||||||
6. **Compatibility surface.** Targets the `ruvnet/RuView` / `wifi-densepose` repo layout (`v2/crates/`, `firmware/esp32-csi-node/`, `archive/v1/`, `scripts/`, `docs/adr/`). Hardware docs default to ESP32 on `COM8` and tell the reader to confirm the port.
|
6. **Compatibility surface.** Targets the `ruvnet/RuView` / `wifi-densepose` repo layout (`v2/crates/`, `firmware/esp32-csi-node/`, `archive/v1/`, `scripts/`, `docs/adr/`). Hardware docs default to ESP32 on `COM8` and tell the reader to confirm the port.
|
||||||
|
|
||||||
7. **Smoke contract** (`scripts/smoke.sh`, ≥12 checks): marketplace.json valid + lists `ruview`; plugin.json has `name`/`description`/`version`/`keywords` and does **not** contain `skills`/`commands`/`agents` arrays; every `skills/*/SKILL.md` has `name` + `description` + `allowed-tools`; no wildcard (`*`) in any `allowed-tools`; the expected skill set is present; every `commands/*.md` has a `description`; every `agents/*.md` has `name` + `description` + `model`; README contains a `## Compatibility` section and a `Namespace coordination` block; this ADR exists with `Status: Proposed`; `codex/AGENTS.md` and `codex/prompts/*.md` exist **and** every `commands/<name>.md` has a matching `codex/prompts/<name>.md` (command↔prompt parity); nothing is misplaced under `.claude-plugin/`.
|
7. **Smoke contract** (`scripts/smoke.sh`, ≥13 checks): repo-root `.claude-plugin/marketplace.json` exists + lists `ruview` + points `source` at `./plugins/ruview`; plugin.json has `name`/`description`/`version`/`keywords` and does **not** contain `skills`/`commands`/`agents` arrays; every `skills/*/SKILL.md` has `name` + `description` + `allowed-tools`; no wildcard (`*`) in any `allowed-tools`; the expected skill set is present; every `commands/*.md` has a `description`; every `agents/*.md` has `name` + `description` + `model`; README contains a `## Compatibility` section and a `Namespace coordination` block; this ADR exists with `Status: Proposed`; `codex/AGENTS.md` and `codex/prompts/*.md` exist **and** every `commands/<name>.md` has a matching `codex/prompts/<name>.md` (command↔prompt parity); nothing is misplaced under `.claude-plugin/`.
|
||||||
|
|
||||||
## Consequences
|
## Consequences
|
||||||
|
|
||||||
- **Good:** one `claude --plugin-dir ./plugins/ruview` gives newcomers and operators the whole RuView workflow surface; no MCP-server prerequisite; Codex users get the same operator commands; the smoke script makes drift visible.
|
- **Good:** `/plugin marketplace add ruvnet/RuView` + `/plugin install ruview@ruview` (or `claude --plugin-dir ./plugins/ruview` from a clone) gives newcomers and operators the whole RuView workflow surface; no MCP-server prerequisite; Codex users get the same operator commands; the smoke script makes drift visible.
|
||||||
- **Cost:** a mega-plugin means coarser install granularity (you get all 9 skills or none); the Codex mirror must be kept in sync by hand (the smoke script checks command↔prompt *presence* parity, not content parity); a skill stem (`ruview-verify`) collides with a command stem — tolerated by Claude Code (both resolve), but `claude plugin details` lists it twice.
|
- **Cost:** a mega-plugin means coarser install granularity (you get all 9 skills or none); the Codex mirror must be kept in sync by hand (the smoke script checks command↔prompt *presence* parity, not content parity); a skill stem (`ruview-verify`) collides with a command stem — tolerated by Claude Code (both resolve), but `claude plugin details` lists it twice.
|
||||||
- **Follow-ups:** if the skill set grows past comfortable browsing (it's at 9), revisit the "one mega-plugin" decision and split by lifecycle (`ruview-edge`, `ruview-train`, …); add a *content*-parity lint between commands and Codex prompts; consider renaming `/ruview-verify` to drop the skill/command stem collision; consider pinning a tested `claude-flow` CLI minor for the security-scan step if that step becomes load-bearing; verify the underlying RuView command flags (`sensing-server --help`, `gcloud-train.sh`, `provision.py`) against the live tree rather than from README/scripts.
|
- **Follow-ups:** if the skill set grows past comfortable browsing (it's at 9), revisit the "one mega-plugin" decision and split by lifecycle (`ruview-edge`, `ruview-train`, …); add a *content*-parity lint between commands and Codex prompts; consider renaming `/ruview-verify` to drop the skill/command stem collision; consider pinning a tested `claude-flow` CLI minor for the security-scan step if that step becomes load-bearing; verify the underlying RuView command flags (`sensing-server --help`, `gcloud-train.sh`, `provision.py`) against the live tree rather than from README/scripts.
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@
|
||||||
# Run from anywhere: bash plugins/ruview/scripts/smoke.sh
|
# Run from anywhere: bash plugins/ruview/scripts/smoke.sh
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
# Resolve plugin root (this file lives in <root>/scripts/smoke.sh)
|
# Resolve plugin root (this file lives in <root>/scripts/smoke.sh).
|
||||||
|
# Plugin lives at <repo>/plugins/ruview ; marketplace manifest is at <repo>/.claude-plugin/marketplace.json
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
MARKET="$(cd "$ROOT/.." && pwd)/.claude-plugin/marketplace.json"
|
REPO="$(cd "$ROOT/../.." && pwd)"
|
||||||
|
MARKET="$REPO/.claude-plugin/marketplace.json"
|
||||||
|
|
||||||
PASS=0
|
PASS=0
|
||||||
FAIL=0
|
FAIL=0
|
||||||
|
|
@ -16,10 +18,11 @@ has() { grep -q "$1" "$2" 2>/dev/null; }
|
||||||
|
|
||||||
echo "ruview plugin smoke test"
|
echo "ruview plugin smoke test"
|
||||||
echo "root: $ROOT"
|
echo "root: $ROOT"
|
||||||
|
echo "repo: $REPO"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# 1. marketplace.json exists and lists the ruview plugin
|
# 1. repo-root marketplace.json exists, lists the ruview plugin, points source at ./plugins/ruview
|
||||||
if [ -f "$MARKET" ] && has '"ruview"' "$MARKET"; then ok "marketplace.json present and lists 'ruview'"; else bad "marketplace.json missing or does not list 'ruview' ($MARKET)"; fi
|
if [ -f "$MARKET" ] && has '"ruview"' "$MARKET" && has '"\./plugins/ruview"' "$MARKET"; then ok "repo-root .claude-plugin/marketplace.json lists 'ruview' with source ./plugins/ruview"; else bad "marketplace.json missing / wrong location / wrong source ($MARKET)"; fi
|
||||||
|
|
||||||
# 2. plugin.json exists with required fields
|
# 2. plugin.json exists with required fields
|
||||||
PJ="$ROOT/.claude-plugin/plugin.json"
|
PJ="$ROOT/.claude-plugin/plugin.json"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue