diff --git a/.claude/skills/build-plugin/SKILL.md b/.claude/skills/build-plugin/SKILL.md index 1cfca01..f65e231 100644 --- a/.claude/skills/build-plugin/SKILL.md +++ b/.claude/skills/build-plugin/SKILL.md @@ -3,7 +3,7 @@ name: build-plugin description: Guides building a SquaredUp low-code plugin for HTTP/REST APIs, from API exploration through deployment. Use when the user wants to integrate a service with SquaredUp, add a new data source, connect to a third-party tool, "pull data from", or "monitor" any service in SquaredUp. metadata: author: SquaredUp - version: "0.0.11" + version: "0.0.12" --- # Building a SquaredUp Low-Code Plugin @@ -44,7 +44,7 @@ Create a TaskCreate task for each phase. The flow deploys early and tests as it - [ ] **Prerequisite** — `squaredup status`; ensure login + tenant (see [Prerequisites](#prerequisites)) - [ ] **Phase 1** — Explore the API - [ ] **Phase 2** — Plan the plugin structure -- [ ] **Phase 3** — Scaffold files (icon, file structure, `docs/README.md`) +- [ ] **Phase 3** — Scaffold files (icon, file structure, `docs/README.md` draft) → [readme.md](references/readme.md) - [ ] **Phase 4** — Write `metadata.json`, `ui.json`, `configValidation.json` + its backing stream — the deployable **shell** → [metadata.md](references/metadata.md), [ui.md](references/ui.md) - [ ] **Checkpoint A** — Deploy the shell and authenticate (invoke `deploy-plugin`, probe auth) → [checkpoints.md](references/checkpoints.md) - [ ] **Phase 5** — Write import definitions and import streams; test each in parallel sub-agents. Repeat per dependency level if any step `dependsOn` another → [index-defs.md](references/index-defs.md), [test-agent.md](references/test-agent.md) @@ -52,7 +52,7 @@ Create a TaskCreate task for each phase. The flow deploys early and tests as it - [ ] **Phase 6** — Build + test data streams in parallel sub-agents → [test-agent.md](references/test-agent.md), [data-streams.md](references/data-streams.md) - [ ] **Phase 7** — Build OOB default content in a sub-agent (it reads [oob-content.md](references/oob-content.md)) - [ ] **Phase 8** — Write `custom_types.json` → [common-patterns.md](references/common-patterns.md) -- [ ] **Phase 9** — Final validate and deploy → invoke the `deploy-plugin` skill; re-index if import definitions changed since the last import +- [ ] **Phase 9** — Finalize `docs/README.md`, then final validate and deploy → [readme.md](references/readme.md); invoke the `deploy-plugin` skill; re-index if import definitions changed since the last import --- @@ -200,17 +200,7 @@ my-plugin/ dashboard1.dash.json ``` -**docs/README.md (required)** — surfaced in-product when a user adds the plugin. Always create as part of scaffolding; the `documentation` link in `metadata.json` must point to it (e.g. `https://github.com/squaredup/plugins/blob/main/plugins/MyPlugin/v1/docs/README.md`). - -The README must cover: - -1. What the plugin monitors — objects imported, what dashboards show -2. Prerequisites / getting credentials — step-by-step, include required scopes/permissions -3. Configuration fields — table explaining every `ui.json` field: what it is, where to find the value, whether required -4. What gets indexed — list object types and what they represent -5. Known limitations — rate limits, permission requirements, API quirks - -Write as if the user has never seen the API. They're reading it inside SquaredUp, not on the vendor's site. +**docs/README.md (required)** — surfaced in-product when a user adds the plugin. Always create as part of scaffolding; the `documentation` link in `metadata.json` must point to it (e.g. `https://github.com/squaredup/plugins/blob/main/plugins/MyPlugin/v1/docs/README.md`). **Draft it now per [readme.md](references/readme.md)**: overview, Setup, and Configuration fields in full; the remaining sections as placeholder headings. It is finalized in Phase 9, once testing has surfaced the real data streams and limitations. **Other rules:** @@ -324,8 +314,10 @@ Write `custom_types.json` — for this and other reusable patterns (built-in pro --- -## Phase 9: Final validate & deploy +## Phase 9: Finalize README, validate & deploy + +**Finalize `docs/README.md` first** — complete the placeholder sections (What this plugin monitors, Data streams, What gets indexed, Known limitations) and run the completion checklist in [readme.md](references/readme.md). Source Known limitations from the reconciliation passes' API-level discoveries: every constraint that forced a fix in Phases 5–6 belongs there in user-facing words. -Invoke the `deploy-plugin` skill for the final validate, version bump, and deploy. +Then invoke the `deploy-plugin` skill for the final validate, version bump, and deploy. **Conditional final re-index.** If `indexDefinitions/*.json` or any import stream changed since the last successful import (the Checkpoint B run, or any re-index triggered by the [re-indexing rule](#re-indexing-rule--a-definition-change-leaves-imported-objects-stale)), the deployed tenant's objects are **stale** — they still match the **old** definition and won't pick up the new shape until the next scheduled import, up to `frequencyMinutes` away (default `720` = 12 hours). So after the final deploy lands, trigger + poll one more import (the [Checkpoint B](#checkpoint-b-redeploy--run-the-first-import) trigger/wait steps) so the deployed objects match the shipped definition. Skip only if no import definition or import stream has changed since the last import. diff --git a/.claude/skills/build-plugin/references/readme.md b/.claude/skills/build-plugin/references/readme.md new file mode 100644 index 0000000..9fb2fe6 --- /dev/null +++ b/.claude/skills/build-plugin/references/readme.md @@ -0,0 +1,144 @@ +# docs/README.md — the in-product documentation + +`docs/README.md` is rendered **in-product** (as GitHub-flavored Markdown) when a user adds or configures the plugin, and the `documentation` link in `metadata.json` must point to it. The reader has never seen the vendor's API and is sitting on the config screen with empty fields in front of them — write every section for that person. + +## Two-pass authoring + +The README is written twice: + +- **Phase 3 (draft)** — write the overview paragraph, **Setup**, and **Configuration fields** in full; the Phase 2 plan has everything they need. Create the remaining four sections as headings with a `` placeholder — their real content (which streams shipped, what testing revealed) doesn't exist yet, and guessing it now means shipping stale guesses later. +- **Phase 9 (finalize, before the final deploy)** — complete **What this plugin monitors**, **Data streams**, **What gets indexed**, and **Known limitations**, then run the [completion checklist](#completion-checklist-phase-9). Source **Known limitations** from the reconciliation passes' API-level discoveries: every constraint that forced a fix in Phases 5–6 — a restricted `timeframes`, a response-size cap, an import count cap, a rate limit, an auth quirk — belongs here in user-facing words. If it surprised a testing sub-agent, it will surprise a user. + +## Structure + +**No H1** — the product shows the plugin name above the rendered doc; open directly with the overview paragraph. All sections are required, in this order: + +```markdown + + +> ⚠️ cover. Omit the blockquote entirely if there's nothing to warn about.> + +## Setup + + + +## Configuration fields + +| Field | What it is | Where to find it | Required | +| ----- | ---------- | ---------------- | -------- | + + + +## What this plugin monitors + + + +## Data streams + + + +## What gets indexed + +| Object type | API source | Represents | +| ----------- | ---------- | ---------- | + + + +## Known limitations + + +``` + +## Writing rules + +- **Name the vendor's UI surfaces, not its endpoints** — "Console → Settings → API keys", not `GET /v1/keys`. Endpoints appear only in the **What gets indexed** API-source column. +- **Bold every field label and vendor UI element** the user must click or fill, matching its on-screen wording exactly. +- **Plain GFM only** — pipe tables, and blockquotes (`> ⚠️ …`) for admonitions. Never GitHub `[!NOTE]`/`[!WARNING]` alert syntax: the in-product renderer isn't GitHub and won't style it. +- **Link out** to the vendor's sign-in page, credential-creation page, and permission docs wherever Setup mentions them — the reader shouldn't need to search for any page a step names. + +## Example + +A finished README for the fictional battery-monitoring plugin from SKILL.md's Phase 2 example: + +```markdown +Monitor your [Acme Energy](https://acme.example) installations and devices in +SquaredUp — battery health, telemetry history, alarms, and billing — via the +[Acme Cloud API](https://acme.example/docs/api). + +> ⚠️ Requires an Acme **Business** subscription — Home accounts have no API +> access. + +## Setup + +You will need an Acme Cloud **API key**. + +1. Sign in to the [Acme Cloud console](https://cloud.acme.example). +2. Go to **Settings → API keys** and click **Create key**, giving it the + **Read-only** role — the plugin never writes. +3. Copy the key and paste it into the **API key** field. + +## Configuration fields + +| Field | What it is | Where to find it | Required | +| ----------- | ------------------------------------------------------- | --------------------------------------------- | -------- | +| **API key** | Authenticates every request via the `X-API-Key` header. | Acme Cloud console → **Settings → API keys**. | Yes | + +On save, the plugin validates the key by fetching your account profile; an +invalid or expired key fails setup with an authentication error. + +## What this plugin monitors + +- **Battery health** — current charge, capacity, and cycle count per device. +- **Telemetry history** — hourly charge and temperature series per device. +- **Alarms and billing** — active alarms and daily billed cost per + installation. + +The out-of-the-box dashboards include an estate-wide **Overview** plus a +perspective for each **Installation** and **Device**. + +## Data streams + +- **Battery Summary** — current battery state, one row per device. +- **Battery History** — hourly charge/temperature time series for a device. +- **Site Alarms** — active alarms for an installation. +- **Site Billing** — daily billed cost for an installation. + +## What gets indexed + +| Object type | API source | Represents | +| ---------------- | ----------------------- | -------------------------------------- | +| **Installation** | `GET /v2/installations` | A monitored site. | +| **Device** | `GET /v2/devices` | A physical device reporting telemetry. | + +**Relationships:** each Device links to its parent Installation. + +## Known limitations + +- **Billing is daily-granularity** — billing timeframes start at last 7 + days; shorter ranges aren't offered. +- **Rate limit** — the API allows 120 requests/minute; very large estates + may import slowly. +- **Read-only** — the plugin never creates, modifies, or deletes anything in + Acme Cloud. +``` + +## Completion checklist (Phase 9) + +Verify each line against the plugin's actual files, not from memory: + +- [ ] Every field in `ui.json` has a row in **Configuration fields**, bold name matching its label exactly. +- [ ] Every `objectType` in `metadata.json` has a row in **What gets indexed**. +- [ ] Every stream in `dataStreams/*.json` has a bullet in **Data streams**, named by its `displayName`. +- [ ] Every constraint that forced a Phase 5–6 fix (restricted `timeframes`, payload caps, import caps, rate limits) appears in **Known limitations** in user-facing words. +- [ ] No `` placeholders remain.