diff --git a/plugins/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json similarity index 78% rename from plugins/.claude-plugin/marketplace.json rename to .claude-plugin/marketplace.json index 6033d9c9..976ca325 100644 --- a/plugins/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -8,8 +8,8 @@ "plugins": [ { "name": "ruview", - "source": "./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" + "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, CLI / API / WASM, mmWave radar, and witness verification" } ] } diff --git a/README.md b/README.md index ae4e97d9..cddeb24d 100644 --- a/README.md +++ b/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 -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 -# Try it for one session, no install: -claude --plugin-dir ./plugins/ruview +# In Claude Code — add this repo as a plugin marketplace, then install: +/plugin marketplace add ruvnet/RuView +/plugin install ruview@ruview -# Or add the marketplace and install: -claude plugin marketplace add ./plugins -claude plugin install ruview@ruview +# Or try it for one session without installing (from a local clone of the repo): +claude --plugin-dir ./plugins/ruview # Then, in Claude Code: # /ruview-start → onboarding (Docker demo / repo build / live ESP32) diff --git a/plugins/ruview/README.md b/plugins/ruview/README.md index 309832e0..a6460626 100644 --- a/plugins/ruview/README.md +++ b/plugins/ruview/README.md @@ -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. -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 ```bash -# Try it locally without installing -claude --plugin-dir ./plugins/ruview +# In Claude Code — add this repo as a plugin marketplace, then install: +/plugin marketplace add ruvnet/RuView +/plugin install ruview@ruview -# Or add the whole marketplace -claude plugin marketplace add ./plugins -claude plugin install ruview@ruview +# Or try it locally without installing (from a clone of the repo): +claude --plugin-dir ./plugins/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). diff --git a/plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md b/plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md index e5cbf04d..7fd31d7f 100644 --- a/plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md +++ b/plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md @@ -2,7 +2,7 @@ - **Status:** Proposed - **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 @@ -10,34 +10,34 @@ RuView (WiFi-DensePose) is a large dual-codebase project (Rust `v2/`, Python `ar ## 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.** ``` - 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/skills//SKILL.md # frontmatter: name, description, allowed-tools plugins/ruview/commands/.md # frontmatter: description (+ argument-hint) plugins/ruview/agents/.md # frontmatter: name, description, model plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md 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 ``` 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. -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/.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. -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/.md` has a matching `codex/prompts/.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/.md` has a matching `codex/prompts/.md` (command↔prompt parity); nothing is misplaced under `.claude-plugin/`. ## 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. - **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. diff --git a/plugins/ruview/scripts/smoke.sh b/plugins/ruview/scripts/smoke.sh index a4478ff1..866b6d82 100644 --- a/plugins/ruview/scripts/smoke.sh +++ b/plugins/ruview/scripts/smoke.sh @@ -3,10 +3,12 @@ # Run from anywhere: bash plugins/ruview/scripts/smoke.sh set -u -# Resolve plugin root (this file lives in /scripts/smoke.sh) +# Resolve plugin root (this file lives in /scripts/smoke.sh). +# Plugin lives at /plugins/ruview ; marketplace manifest is at /.claude-plugin/marketplace.json SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && 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 FAIL=0 @@ -16,10 +18,11 @@ has() { grep -q "$1" "$2" 2>/dev/null; } echo "ruview plugin smoke test" echo "root: $ROOT" +echo "repo: $REPO" echo -# 1. marketplace.json exists and lists the ruview plugin -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 +# 1. repo-root marketplace.json exists, lists the ruview plugin, points source at ./plugins/ruview +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 PJ="$ROOT/.claude-plugin/plugin.json"