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:
ruv 2026-05-11 19:52:04 -04:00
parent 298543913e
commit df9d3b0eea
5 changed files with 28 additions and 25 deletions

View File

@ -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"
} }
] ]
} }

View File

@ -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)

View File

@ -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).

View File

@ -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.

View File

@ -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"