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
48 changes: 48 additions & 0 deletions .claude/skills/plugin-readme/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: plugin-readme
description: Write or review a NetAlertX plugin's README.md (server/plugins/<code_name>/README.md). Use this when asked to create, enhance, audit, or clean up a plugin README, or plugin docs generally.
---

# Plugin README Documentation

## Structure

- `## Overview` — prose: what the plugin does and why, 1-3 sentences. Link out to a full guide under `docs/*.md` if one exists for this topic.
- `### Requirements` / `### Prerequisites` (optional) — only when there's a real precondition beyond installing the app (credentials, specific hardware/firmware, host networking, a third-party account).
- `### Usage` — how a user actually engages with the plugin: where to enable it, the overall flow, which non-obvious values they need to go find elsewhere (e.g. "grab your API key from your provider's dashboard"). Not a settings reference table.
- `### Notes` (optional) — caveats, gotchas, limitations, similar/related plugins worth cross-linking.
- `## Other info` (optional) — Version / Author / Maintainer(s) / Release Date. **Never drop this when rewriting a README** - if it's there, carry it forward verbatim even if you're rewriting everything else.

## The core rule: don't re-document settings

Every setting already gets a name and description shown directly in the Settings UI, generated straight from `config.json`. A README that re-lists each setting with its key and default value duplicates that and drifts out of sync the moment `config.json` changes — the UI is the single source of truth for field-level docs, not the README.

Exception: call out a *specific* setting by name, in prose, only when its behavior is genuinely non-obvious - e.g. a setting whose name doesn't match what it actually holds (`_publisher_telegram`'s `HOST` setting is actually the chat ID, `URL` is the bot token), a recommended value or schedule, or an upstream bug tied to a specific value (see `unifi_import`'s `UNFIMP_version`/`UNFIMP_port` note). Don't turn this into a table of every field "just in case" - if you're listing more than one or two settings, ask whether that content belongs in the UI's per-field description instead.

## Verify against the actual code first

Read `config.json` (`unique_prefix`, `plugin_type`, `data_source`, `settings`) and the plugin's script before writing anything - don't guess at mechanism from the plugin's name alone. Real bugs found this way during a past audit: `dig_scan/README.md` described the `nbtscan` utility (copy-paste from a sibling plugin); `adguard_import/README.md` was a byte-for-byte copy of `__template/README.md`, never actually written.

## Backfilling missing "Other info"

Before concluding a plugin has no attribution to record, grep its script for a credit comment (e.g. `grep -rn "Based on\|Author:" server/plugins/<code_name>/*.py`) - two plugins (`dhcp_servers`, `website_monitor`) had `# Based on the work of https://github.com/leiweibau/Pi.Alert` in the script that nothing in the README reflected. Do **not** use `git log --diff-filter=A` "who first added this file" as an attribution source - `server/plugins/` has at least one bulk restructuring commit, so several unrelated plugins share the same "first added" date/author despite having nothing to do with each other. If you can't verify authorship from an in-source comment or an existing (already-correct) README, leave the section out rather than guess - most first-party/core plugins (`maintenance`, `custom_props`, `db_cleanup`, `set_password`, etc.) simply don't have one, which is the correct, honest state.

## Cross-linking convention

- Link to a top-level docs page: `https://docs.netalertx.com/PAGE_NAME`. Never `/docs/PAGE_NAME.md` or a `github.com/.../tree/main/...` URL - both break once the README is rendered inside the docs site (`docs/gen_plugin_pages.py` generates it at a different path than the repo, so repo-relative and GitHub-tree links don't resolve there).
- Link to *another plugin's* README: `https://docs.netalertx.com/plugins/<code_name>` (matches the page `docs/gen_plugin_pages.py` generates for it). Never a GitHub tree URL.
- If a `docs/*.md` guide is dedicated to (or shared by) this plugin, link both directions - plugin → guide, and guide → plugin. Check the other side actually links back; it's easy to add one direction and forget the other (e.g. `PIHOLE_GUIDE.md` linked to four Pi-hole plugins, none of which linked back, until this was audited).
- If a sibling plugin is easily confused with this one (`unifi_import` vs `unifi_api_import`, `dig_scan` vs `nslookup_scan`, `adguard_export` vs `adguard_import`), say so in one sentence and link it - which one to prefer and why.

## Common defects to check for when auditing existing READMEs

- Template leftovers: grep for `Plugin name`, `<your github handle>`, `Some tip.`, `PREF_RUN` - a sign the README was never actually written. Diff against `server/plugins/__template/README.md` if unsure.
- Content copy-pasted from a sibling plugin without updating the tool/utility name.
- `TBC` or similarly empty content, especially for a prominent feature.
- Duplicate or orphaned sections (e.g. two `### Usage` headings) - usually a merge/edit artifact.
- Sibling non-README files (a provider-specific sub-guide, a translated `README_<LANG>.md`) that aren't linked from the plugin's own `README.md` - `docs/gen_plugin_pages.py` generates a page for every `*.md` in the plugin folder, but only reachable if something links to it.

## Reference

- Repo-wide plugin catalog with icon/type legend: `docs/PLUGINS.md`
- Full plugin authoring reference (settings schema, execution phases, data contract): `docs/PLUGINS_DEV.md` and the `plugin-development` skill.
48 changes: 48 additions & 0 deletions .gemini/skills/plugin-readme/plugin-readme-skill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: netalertx-plugin-readme
description: Write or review a NetAlertX plugin's README.md (server/plugins/<code_name>/README.md). Use this when asked to create, enhance, audit, or clean up a plugin README, or plugin docs generally.
---

# Plugin README Documentation

## Structure

- `## Overview` — prose: what the plugin does and why, 1-3 sentences. Link out to a full guide under `docs/*.md` if one exists for this topic.
- `### Requirements` / `### Prerequisites` (optional) — only when there's a real precondition beyond installing the app (credentials, specific hardware/firmware, host networking, a third-party account).
- `### Usage` — how a user actually engages with the plugin: where to enable it, the overall flow, which non-obvious values they need to go find elsewhere (e.g. "grab your API key from your provider's dashboard"). Not a settings reference table.
- `### Notes` (optional) — caveats, gotchas, limitations, similar/related plugins worth cross-linking.
- `## Other info` (optional) — Version / Author / Maintainer(s) / Release Date. **Never drop this when rewriting a README** - if it's there, carry it forward verbatim even if you're rewriting everything else.

## The core rule: don't re-document settings

Every setting already gets a name and description shown directly in the Settings UI, generated straight from `config.json`. A README that re-lists each setting with its key and default value duplicates that and drifts out of sync the moment `config.json` changes — the UI is the single source of truth for field-level docs, not the README.

Exception: call out a *specific* setting by name, in prose, only when its behavior is genuinely non-obvious - e.g. a setting whose name doesn't match what it actually holds (`_publisher_telegram`'s `HOST` setting is actually the chat ID, `URL` is the bot token), a recommended value or schedule, or an upstream bug tied to a specific value (see `unifi_import`'s `UNFIMP_version`/`UNFIMP_port` note). Don't turn this into a table of every field "just in case" - if you're listing more than one or two settings, ask whether that content belongs in the UI's per-field description instead.

## Verify against the actual code first

Read `config.json` (`unique_prefix`, `plugin_type`, `data_source`, `settings`) and the plugin's script before writing anything - don't guess at mechanism from the plugin's name alone. Real bugs found this way during a past audit: `dig_scan/README.md` described the `nbtscan` utility (copy-paste from a sibling plugin); `adguard_import/README.md` was a byte-for-byte copy of `__template/README.md`, never actually written.

## Backfilling missing "Other info"

Before concluding a plugin has no attribution to record, grep its script for a credit comment (e.g. `grep -rn "Based on\|Author:" server/plugins/<code_name>/*.py`) - two plugins (`dhcp_servers`, `website_monitor`) had `# Based on the work of https://github.com/leiweibau/Pi.Alert` in the script that nothing in the README reflected. Do **not** use `git log --diff-filter=A` "who first added this file" as an attribution source - `server/plugins/` has at least one bulk restructuring commit, so several unrelated plugins share the same "first added" date/author despite having nothing to do with each other. If you can't verify authorship from an in-source comment or an existing (already-correct) README, leave the section out rather than guess - most first-party/core plugins (`maintenance`, `custom_props`, `db_cleanup`, `set_password`, etc.) simply don't have one, which is the correct, honest state.

## Cross-linking convention

- Link to a top-level docs page: `https://docs.netalertx.com/PAGE_NAME`. Never `/docs/PAGE_NAME.md` or a `github.com/.../tree/main/...` URL - both break once the README is rendered inside the docs site (`docs/gen_plugin_pages.py` generates it at a different path than the repo, so repo-relative and GitHub-tree links don't resolve there).
- Link to *another plugin's* README: `https://docs.netalertx.com/plugins/<code_name>` (matches the page `docs/gen_plugin_pages.py` generates for it). Never a GitHub tree URL.
- If a `docs/*.md` guide is dedicated to (or shared by) this plugin, link both directions - plugin → guide, and guide → plugin. Check the other side actually links back; it's easy to add one direction and forget the other (e.g. `PIHOLE_GUIDE.md` linked to four Pi-hole plugins, none of which linked back, until this was audited).
- If a sibling plugin is easily confused with this one (`unifi_import` vs `unifi_api_import`, `dig_scan` vs `nslookup_scan`, `adguard_export` vs `adguard_import`), say so in one sentence and link it - which one to prefer and why.

## Common defects to check for when auditing existing READMEs

- Template leftovers: grep for `Plugin name`, `<your github handle>`, `Some tip.`, `PREF_RUN` - a sign the README was never actually written. Diff against `server/plugins/__template/README.md` if unsure.
- Content copy-pasted from a sibling plugin without updating the tool/utility name.
- `TBC` or similarly empty content, especially for a prominent feature.
- Duplicate or orphaned sections (e.g. two `### Usage` headings) - usually a merge/edit artifact.
- Sibling non-README files (a provider-specific sub-guide, a translated `README_<LANG>.md`) that aren't linked from the plugin's own `README.md` - `docs/gen_plugin_pages.py` generates a page for every `*.md` in the plugin folder, but only reachable if something links to it.

## Reference

- Repo-wide plugin catalog with icon/type legend: `docs/PLUGINS.md`
- Full plugin authoring reference (settings schema, execution phases, data contract): `docs/PLUGINS_DEV.md` and the `plugin-development` skill.
1 change: 1 addition & 0 deletions .gemini/skills/skills-index/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Skills with the same purpose exist in more than one, sometimes under different n
| MCP activation | `mcp-activation` | `mcp-activation` | — | Gemini version covers Gemini CLI session restart; Copilot version covers VS Code window reload |
| Project navigation | `project-navigation` | `project-navigation` | — | Copilot version has full path tables and env vars; Gemini version is a brief reference |
| Plugin dev | `plugin-development` | `plugin-run-development` | `plugin-development` | All three cover data contract, phases, formats, the `RUN_TIMEOUT` kill-timer gotcha (`timeoutMultiplier`/`per_item_timeout()`), and a pre-PR pointer to the Conventions Checklist in `docs/PLUGINS_DEV.md` |
| Plugin README docs | `plugin-readme` | `plugin-readme` | `plugin-readme` | All three cover README structure, the "don't re-document settings" rule, the `docs.netalertx.com` cross-linking convention, and common defects (template leftovers, copy-paste errors) found during a full-repo audit |
| Devcontainer | `devcontainer-management` | `devcontainer-services` + `devcontainer-setup` + `devcontainer-configs` | — | Gemini combines into one (uses `docker exec`); Copilot splits into 3 focused skills |
| PR review | `pr-analysis` | `pr-analysis` | `pr-analysis` | How to classify and respond to PR comments; pre-flight skill loading checklist |
| Logging | `logging-standards` | `logging-standards` | — | `mylog` levels, message format, what not to log |
Expand Down
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Procedural knowledge lives in `.github/skills/`. Load the appropriate skill when
| Build Docker images | `docker-build` |
| Reprovision devcontainer | `devcontainer-setup` |
| Create or run plugins | `plugin-run-development` |
| Write or review a plugin README | `plugin-readme` |
| Analyze PR comments | `pr-analysis` |
| Clean Docker resources | `docker-prune` |
| Generate devcontainer configs | `devcontainer-configs` |
Expand Down
48 changes: 48 additions & 0 deletions .github/skills/plugin-readme/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: netalertx-plugin-readme
description: Write or review a NetAlertX plugin's README.md (server/plugins/<code_name>/README.md). Use this when asked to create, enhance, audit, or clean up a plugin README, or plugin docs generally.
---

# Plugin README Documentation

## Structure

- `## Overview` — prose: what the plugin does and why, 1-3 sentences. Link out to a full guide under `docs/*.md` if one exists for this topic.
- `### Requirements` / `### Prerequisites` (optional) — only when there's a real precondition beyond installing the app (credentials, specific hardware/firmware, host networking, a third-party account).
- `### Usage` — how a user actually engages with the plugin: where to enable it, the overall flow, which non-obvious values they need to go find elsewhere (e.g. "grab your API key from your provider's dashboard"). Not a settings reference table.
- `### Notes` (optional) — caveats, gotchas, limitations, similar/related plugins worth cross-linking.
- `## Other info` (optional) — Version / Author / Maintainer(s) / Release Date. **Never drop this when rewriting a README** - if it's there, carry it forward verbatim even if you're rewriting everything else.

## The core rule: don't re-document settings

Every setting already gets a name and description shown directly in the Settings UI, generated straight from `config.json`. A README that re-lists each setting with its key and default value duplicates that and drifts out of sync the moment `config.json` changes — the UI is the single source of truth for field-level docs, not the README.

Exception: call out a *specific* setting by name, in prose, only when its behavior is genuinely non-obvious - e.g. a setting whose name doesn't match what it actually holds (`_publisher_telegram`'s `HOST` setting is actually the chat ID, `URL` is the bot token), a recommended value or schedule, or an upstream bug tied to a specific value (see `unifi_import`'s `UNFIMP_version`/`UNFIMP_port` note). Don't turn this into a table of every field "just in case" - if you're listing more than one or two settings, ask whether that content belongs in the UI's per-field description instead.

## Verify against the actual code first

Read `config.json` (`unique_prefix`, `plugin_type`, `data_source`, `settings`) and the plugin's script before writing anything - don't guess at mechanism from the plugin's name alone. Real bugs found this way during a past audit: `dig_scan/README.md` described the `nbtscan` utility (copy-paste from a sibling plugin); `adguard_import/README.md` was a byte-for-byte copy of `__template/README.md`, never actually written.

## Backfilling missing "Other info"

Before concluding a plugin has no attribution to record, grep its script for a credit comment (e.g. `grep -rn "Based on\|Author:" server/plugins/<code_name>/*.py`) - two plugins (`dhcp_servers`, `website_monitor`) had `# Based on the work of https://github.com/leiweibau/Pi.Alert` in the script that nothing in the README reflected. Do **not** use `git log --diff-filter=A` "who first added this file" as an attribution source - `server/plugins/` has at least one bulk restructuring commit, so several unrelated plugins share the same "first added" date/author despite having nothing to do with each other. If you can't verify authorship from an in-source comment or an existing (already-correct) README, leave the section out rather than guess - most first-party/core plugins (`maintenance`, `custom_props`, `db_cleanup`, `set_password`, etc.) simply don't have one, which is the correct, honest state.

## Cross-linking convention

- Link to a top-level docs page: `https://docs.netalertx.com/PAGE_NAME`. Never `/docs/PAGE_NAME.md` or a `github.com/.../tree/main/...` URL - both break once the README is rendered inside the docs site (`docs/gen_plugin_pages.py` generates it at a different path than the repo, so repo-relative and GitHub-tree links don't resolve there).
- Link to *another plugin's* README: `https://docs.netalertx.com/plugins/<code_name>` (matches the page `docs/gen_plugin_pages.py` generates for it). Never a GitHub tree URL.
- If a `docs/*.md` guide is dedicated to (or shared by) this plugin, link both directions - plugin → guide, and guide → plugin. Check the other side actually links back; it's easy to add one direction and forget the other (e.g. `PIHOLE_GUIDE.md` linked to four Pi-hole plugins, none of which linked back, until this was audited).
- If a sibling plugin is easily confused with this one (`unifi_import` vs `unifi_api_import`, `dig_scan` vs `nslookup_scan`, `adguard_export` vs `adguard_import`), say so in one sentence and link it - which one to prefer and why.

## Common defects to check for when auditing existing READMEs

- Template leftovers: grep for `Plugin name`, `<your github handle>`, `Some tip.`, `PREF_RUN` - a sign the README was never actually written. Diff against `server/plugins/__template/README.md` if unsure.
- Content copy-pasted from a sibling plugin without updating the tool/utility name.
- `TBC` or similarly empty content, especially for a prominent feature.
- Duplicate or orphaned sections (e.g. two `### Usage` headings) - usually a merge/edit artifact.
- Sibling non-README files (a provider-specific sub-guide, a translated `README_<LANG>.md`) that aren't linked from the plugin's own `README.md` - `docs/gen_plugin_pages.py` generates a page for every `*.md` in the plugin folder, but only reachable if something links to it.

## Reference

- Repo-wide plugin catalog with icon/type legend: `docs/PLUGINS.md`
- Full plugin authoring reference (settings schema, execution phases, data contract): `docs/PLUGINS_DEV.md` and the `plugin-run-development` skill.
Loading
Loading