Skip to content

Canonical docs restructure — vendor Indigo 2025.2, fix fabricated facts (v2.0.0) - #46

Merged
simons-plugins merged 7 commits into
mainfrom
feat/canonical-docs-restructure
Jul 10, 2026
Merged

Canonical docs restructure — vendor Indigo 2025.2, fix fabricated facts (v2.0.0)#46
simons-plugins merged 7 commits into
mainfrom
feat/canonical-docs-restructure

Conversation

@simons-plugins

@simons-plugins simons-plugins commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Why

Indigo completely rewrote their documentation (now published as a machine-readable llms.txt + llms-full.txt) but did not change functionality. A 4-domain audit against the new canonical found our ~11k lines of hand-maintained derivative docs had drifted and fabricated specifics that never existed. Rather than keep hand-patching a parallel corpus, this vendors the canonical and reshapes the skills to route into it.

What

Vendoring engine (P1)tools/refresh_canonical.py (stdlib-only) fetches the monolith, splits it on its --- Title (URL) --- markers into 68 small per-page files under reference/canonical/** (path mirrors the doc URL), builds INDEX.md, and stamps VERSION. Pinned to 2025.2; --check mode catches drift. Skills now do local, incremental, load-only-what-you-need discovery — canonical by construction.

Routing rewrites + correctness (P2)api/dev skills + commands now route into reference/canonical/ (anchored to ${CLAUDE_PLUGIN_ROOT}), with the pre-existing HIGH-severity errors fixed:

  • API command envelope {"message":"indigo.<ns>.<cmd>","objectId":id,…} (was name/parameters.id — wrong on every field)
  • Removed non-existent PUT /v2/api/indigo.devices/<id> and fabricated ?detail=true
  • Real 7 WebSocket feeds + refresh message (was a fake subscribe)
  • Auth: HTTP Digest added; local secrets reframed; Authorizations portal
  • super() contract corrected (emphasis on deviceUpdated/Created/Deleted); secure="true" only masks, not stored securely
  • Stale dokuwiki 2025.1 links → docs.indigodomo.com/2025.2

Prune + thin (P3) — deleted 26 duplicated/fabricated docs; kept & corrected the on-ramps (quick-start, plugin-lifecycle); ServerApiVersion 3.0 → 3.4; version sweep to 2025.2 / Python 3.13 / API 3.8; reframed the Python 2→3 guide as legacy-only.

Tier-3 coverage gaps (webhooks, ValidationError, subType enums, symlink dev workflow, debuggers) close for free — they're now canonical pages the skills route into.

Notes for review

  • reference/canonical/** is generated — never hand-edit; re-run tools/refresh_canonical.py.
  • Rationale captured in docs/plans/2026-07-09-canonical-docs-audit.md and …-hybrid-restructure.md.
  • Version bumped to 2.0.0 (major: structural change to how the plugin sources Indigo knowledge).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z

Summary by CodeRabbit

  • New Features

    • Expanded the locally available canonical documentation for Indigo 2025.2, including refreshed message formats, WebSocket/HTTP integration guides, Webhooks, and REST-to-HTTP migration content.
    • Added a generated topic index to help browse canonical reference pages.
  • Documentation

    • Updated plugin development and scripting guidance to align with the canonical docs workflow and modern version expectations.
    • Removed/retired older duplicate API and plugin-development pages in favor of the canonical set.
  • Chores

    • Bumped the plugin package manifests version to 2.0.0.

simons-plugins and others added 4 commits July 9, 2026 23:29
Indigo publishes an always-current, LLM-optimised canonical (llms.txt +
llms-full.txt). Add tools/refresh_canonical.py to fetch the monolith, split it
on its `--- Title (URL) ---` markers into small per-page Markdown files under
reference/canonical/ (path mirrors the doc URL), build INDEX.md from the index,
and stamp VERSION (indigo version + fetch date + sha256). Pinned to 2025.2; a
`--check` mode diffs the live docs against the vendored copy to catch drift.

This gives skills local, incremental, load-only-what-you-need reference that is
canonical by construction — no per-fact webpage fetches, no fabrication.

Vendors 68 pages (api/, plugin-dev/, scripting/) + INDEX.md + VERSION.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
…facts

Rewrite the api/dev skills and their commands to point at reference/canonical/
(relative to ${CLAUDE_PLUGIN_ROOT}) instead of hand-maintained derivatives, and
fix the pre-existing factual errors the canonical docs surfaced:

- API command envelope: `{"message": "indigo.<ns>.<cmd>", "objectId": id, ...}`
  (was `{"name": "device.turnOn", "parameters": {"id": id}}` — wrong on every field)
- Drop non-existent `PUT /v2/api/indigo.devices/<id>` and fabricated `?detail=true`
- WebSocket: real per-feed URLs (7 feeds) + `refresh` message (was a fake subscribe)
- Auth: add HTTP Digest; reframe local secrets as a kind of API key; Authorizations portal
- super() story: emphasise deviceUpdated/deviceCreated/deviceDeleted (base does real
  work) over deviceStartComm/StopComm (override hooks); note secure="true" only masks
- Stale dokuwiki 2025.1 links -> docs.indigodomo.com/2025.2
- Repoint html-pages command reference off the deleted device-commands.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
…25.2

The reference facts now live in reference/canonical/, so delete the 26 hand-
maintained docs that duplicated (and in places fabricated) them: all of docs/api/,
all of docs/plugin-dev/api/ (incl. iom/), and the concepts/ pages now covered by
canonical (devices, actions, events, menu-items, configui, plugin-preferences,
http-responder, scripting-shell).

Keep the genuinely-additive on-ramps and correct them:
- plugin-lifecycle.md: fix the super() contract (deviceCreated/Deleted/Updated
  need the base call; deviceStartComm/StopComm are optional override hooks)
- quick-start.md: ServerApiVersion 3.0 -> 3.4 (first Python 3 + requirements.txt
  auto-install), example paths -> 2025.2, next-steps -> canonical
- common-issues.md: paths -> 2025.2; soften "requirements.txt is the only path"
  (manual -t bundling is also supported)
- README/reference/README: repoint to canonical; reframe the Python 2->3 guide as
  legacy-only; version sweep to 2025.2 / Python 3.13 / API 3.8

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
Major version: reference docs are now vendored canonical rather than hand-authored
derivatives, and the skills route into them — a structural change to how the plugin
sources its Indigo knowledge.

Add the gap-analysis audit and the hybrid-restructure design under docs/plans/ for
provenance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c7035548-701f-40aa-b26e-8a9531809525

📥 Commits

Reviewing files that changed from the base of the PR and between 28f22ca and 257d6ce.

📒 Files selected for processing (8)
  • commands/dev.md
  • docs/plugin-dev/concepts/actions.md
  • docs/plugin-dev/concepts/devices.md
  • docs/plugin-dev/concepts/events.md
  • docs/plugin-dev/concepts/plugin-preferences.md
  • docs/plugin-dev/patterns/api-patterns.md
  • docs/plugin-dev/troubleshooting/common-issues.md
  • skills/dev/SKILL.md

📝 Walkthrough

Walkthrough

This PR bumps plugin manifests to 2.0.0, vendors generated Indigo 2025.2 canonical documentation, removes duplicated reference pages, and rewrites command, plugin-development, API, installation, and troubleshooting guidance to use the canonical documentation layout.

Changes

Canonical documentation migration

Layer / File(s) Summary
Canonical API reference
reference/canonical/api/**, reference/canonical/INDEX.md, reference/canonical/VERSION
Adds generated HTTP, WebSocket, messaging, webhook, and REST-migration references with refreshed source metadata.
Canonical plugin and scripting references
reference/canonical/plugin-dev/**, reference/canonical/scripting/**
Adds generated plugin lifecycle, XML, ConfigUI, IOM, action, device, and scripting documentation.
Routing and workspace guidance
commands/*, README.md, docs/plugin-dev/*, reference/README.md
Routes documentation workflows to canonical references and updates Indigo 2025.2, Python, API-version, installation, and troubleshooting guidance.
Documentation restructure plans
docs/plans/*
Adds the canonical documentation audit and hybrid-restructure proposal, including refresh-tool and migration details.
Manifest version
.claude-plugin/marketplace.json, .claude-plugin/plugin.json
Changes both manifest versions from 1.9.4 to 2.0.0.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main documentation restructure and version bump reflected in the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/canonical-docs-restructure

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

🟠 Major comments (28)
docs/plans/2026-07-09-canonical-hybrid-restructure.md-58-69 (1)

58-69: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Ensure refreshes remove obsolete generated pages.

generate() writes newly discovered sections but does not delete files that disappeared from the canonical source. After a page is removed or renamed, the documented python3 tools/refresh_canonical.py command leaves stale files behind, while --check continues reporting drift. Generate into a clean directory or explicitly remove previously managed files before writing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/plans/2026-07-09-canonical-hybrid-restructure.md` around lines 58 - 69,
Ensure generate() removes obsolete generated pages before writing refreshed
content. Generate into a clean temporary/output directory or track and delete
previously managed files under reference/canonical/ while preserving unrelated
files, so removed or renamed source sections cannot remain and --check
accurately detects drift.
reference/canonical/api/http.md-22-29 (1)

22-29: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reconcile the auth guidance in reference/canonical/api/http.md:23-29. The page says HTTP API requests “must be authenticated using an API Key,” but reference/canonical/api.md documents HTTP Digest, API keys, and local secrets as valid depending on server configuration. Update the canonical source so this page doesn’t exclude Digest/local-secret setups.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/api/http.md` around lines 22 - 29, Update the
Authentication section in the HTTP API documentation to state that supported
authentication methods depend on server configuration, including HTTP Digest,
API keys, and local secrets, rather than requiring API keys universally. Retain
the API-key usage and HTTPS security guidance, but clarify that the subsequent
examples apply when API-key authentication is configured.
reference/canonical/api/webhooks.md-175-180 (1)

175-180: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Give the work GET trigger its own webhook ID.

Both triggers are assigned the ID work-form, while the second URL uses /webhook/work-get. Requests to that URL will not match the documented trigger configuration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/api/webhooks.md` around lines 175 - 180, The webhook
trigger described as work-get incorrectly reuses the work-form webhook ID;
update its webhook ID to work-get so it matches the documented /webhook/work-get
URL while leaving the work-form trigger unchanged.
commands/api.md-148-166 (1)

148-166: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the canonical paths consistently in workflow instructions.

Because Line 22 defines paths relative to ${CLAUDE_PLUGIN_ROOT}, entries such as api/websocket.md and api/messages.md point to the wrong location. They should use reference/canonical/api/... just like the routing tables above.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commands/api.md` around lines 148 - 166, Update the workflow instruction file
references in the iOS/Android App, Web Dashboard, Automation Script, and
Third-Party Integration sections to use the canonical
`reference/canonical/api/...` paths, including websocket.md, http.md,
messages.md, and webhooks.md, consistently with the routing tables.
reference/canonical/api/rest-migration.md-61-64 (1)

61-64: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Declare the JSON content type in every HTTP curl example.

These commands send JSON bodies with -d but do not set Content-Type: application/json; curl therefore defaults to form encoding. Add the header to all HTTP examples.

Proposed fix
-curl -X POST -H "Authorization: Bearer YOUR-API-KEY" -d '{"message":"indigo.device.turnOn","objectId":123456789}' http://127.0.0.1:8176/v2/api/command
+curl -X POST -H "Authorization: Bearer YOUR-API-KEY" -H "Content-Type: application/json" -d '{"message":"indigo.device.turnOn","objectId":123456789}' http://127.0.0.1:8176/v2/api/command

Also applies to: 76-80, 91-94, 111-118, 132-135, 156-166, 198-201, 249-252, 299-302

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/api/rest-migration.md` around lines 61 - 64, Update every
HTTP curl example in the migration documentation, including the command near the
REST API example and the additionally referenced examples, to add the
`Content-Type: application/json` header alongside the existing authorization
header whenever a JSON body is sent with `-d`.
commands/api.md-139-145 (1)

139-145: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not claim HTTP Digest works for both transports.

This section says both APIs accept HTTP Digest, but reference/canonical/api/websocket.md states that WebSocket requests must use API-key authentication. Split the authentication guidance by transport so clients do not implement an unsupported WebSocket flow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commands/api.md` around lines 139 - 145, Update the Authentication section to
distinguish HTTP and WebSocket transports: document HTTP Digest only for the
HTTP API, and state that WebSocket requests require API-key authentication,
while retaining the applicable local-secret and Bearer-token guidance. Remove
the claim that both APIs accept HTTP Digest.
reference/canonical/api/websocket.md-138-143 (1)

138-143: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not JSON-encode the message twice.

msg is already serialized at Line 140, then serialized again at Line 142. The server receives a JSON string instead of a command object.

-            await ws.send(json.dumps(msg))
+            await ws.send(msg)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/api/websocket.md` around lines 138 - 143, In the sender
loop, avoid serializing the message twice: use the already serialized `msg`
value created by `json.dumps(message)` when calling `ws.send`, so the server
receives the command object rather than a JSON string.
reference/canonical/plugin-dev.md-15-17 (1)

15-17: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the canonical reference links.

These links target the pre-restructure index.md layout, but the generated files are plugin-dev/reference/plugin-py.md, plugin-dev/reference/xml.md, and scripting.md. Update the canonical source or refresh-tool link rewriting, then regenerate the file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev.md` around lines 15 - 17, Update the canonical
reference links to target plugin-dev/reference/plugin-py.md,
plugin-dev/reference/xml.md, and scripting.md, adjusting the canonical source or
refresh-tool link rewriting as appropriate; then regenerate the documentation
file.
reference/canonical/scripting/iom-concepts.md-12-12 (1)

12-12: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove stale pre-restructure links from the IOM reference.

The page still links to the old index.md hierarchy and removed derivative pages, including the SQL Logger and utility references. Update links to the generated canonical files or remove references to pages that are no longer vendored.

Also applies to: 72-105, 241-241, 485-503

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/iom-concepts.md` at line 12, Update the IOM
reference links throughout the affected sections, including the object-type list
and ranges 72-105 and 485-503, to point to the generated canonical documentation
files instead of the obsolete index.md hierarchy; remove links and references to
deleted or no-longer-vendored derivative pages such as SQL Logger and utility
references, including the item at 241.
reference/canonical/scripting/guides/python-packages.md-171-174 (1)

171-174: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not recommend global installation for Plugin dependencies.

For a Plugin, direct installation should target Contents/Packages; global site-packages is shared and can break unrelated Plugins or Indigo itself. Clarify this section as script-only guidance or provide the plugin-local pip3 -t .../Contents/Packages/ command.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/guides/python-packages.md` around lines 171 -
174, The Python package guidance currently implies that plugin dependencies may
be installed globally into site-packages. Revise the section around the pip3
installation guidance to clearly limit global installation to standalone
scripts, and document that plugin dependencies must be installed into the
plugin’s Contents/Packages directory using pip3’s target option.
reference/canonical/scripting/guides/python-packages.md-6-17 (1)

6-17: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the Python version consistent with Indigo 2025.2.

The page simultaneously documents Python 3.13 and Python 3.11, including hardcoded 3.11 site-package paths and a “Python 3.11.6 Packages” heading. Update the stale version references and paths to the supported runtime, then regenerate the page.

Also applies to: 72-79, 164-191

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/guides/python-packages.md` around lines 6 - 17,
Update all stale Python 3.11 references in the guide, including prose, headings,
site-package paths, and package listings, to consistently document the Python
version supported by Indigo 2025.2 (Python 3.13). Review the sections around the
package installation instructions and package tables, then regenerate the page
after applying the changes.
reference/canonical/plugin-dev/reference/plugin-py.md-18-19 (1)

18-19: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the IOM reference link depth.

Use ../../scripting/iom-concepts.md#subscribing-to-object-change-events; the current ../../../ path resolves outside reference/canonical/.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py.md` around lines 18 - 19,
Update the IOM reference link in the “Subscribing to Object Changes” note to use
../../scripting/iom-concepts.md#subscribing-to-object-change-events instead of
the incorrect ../../../ path.
reference/canonical/plugin-dev/guide.md-9-11 (1)

9-11: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Correct the relative scripting links.

From reference/canonical/plugin-dev/guide.md, these targets need ../../scripting/..., not ../scripting/...; otherwise the links resolve under the nonexistent plugin-dev/scripting/ directory.

Also applies to: 112-112

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/guide.md` around lines 9 - 11, Update the
scripting documentation links in the plugin development guide, including the
Indigo Object Model link, from ../scripting/... to ../../scripting/... so they
resolve to the correct scripting directory.
reference/canonical/scripting/iom-concepts.md-239-250 (1)

239-250: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Correct the subscribeToChanges() spelling.

The API name is case-sensitive. Change both occurrences of subscribeTochanges() to subscribeToChanges().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/iom-concepts.md` around lines 239 - 250,
Correct the case-sensitive method spelling in the “Object Events” table: update
both occurrences of subscribeTochanges() to subscribeToChanges() for the heading
and API references.
reference/canonical/scripting/guides/python-packages.md-90-96 (1)

90-96: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the package-install target path.

The command must target Contents/Packages, not the singular Contents/Package; otherwise the documented requirements installation will not populate the package directory used by IPH.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/guides/python-packages.md` around lines 90 -
96, The documentation’s pip installation target uses the incorrect singular
Contents/Package path. Update the requirements installation step to consistently
specify Contents/Packages, matching the success-log location and the directory
consumed by IPH.
reference/canonical/scripting.md-18-24 (1)

18-24: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Update links to the flattened canonical paths.

This page still points at the removed index.md layout, for example reference/devices/index.md, reference/device-subclasses/index.md, ../plugin-dev/index.md, and ../api/index.md. Point these links at the generated .md files or regenerate them through the refresh-tool mapping.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting.md` around lines 18 - 24, Update the links in
the scripting reference overview to use flattened canonical Markdown paths
instead of removed index.md paths. Adjust the Devices, Device Subclasses, Plugin
Development, and Integration APIs links, and verify all related references
against the refresh-tool mapping.
reference/canonical/plugin-dev/reference/dev-environment.md-282-286 (1)

282-286: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Call debugMode() in the example.

The earlier example documents this as a method, but this code stores the bound method itself. bool(debug_mode) will therefore be truthy regardless of the actual debugger state.

-debug_mode = indigo.host.debugMode
+debug_mode = indigo.host.debugMode()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/dev-environment.md` around lines 282
- 286, Update the debug-mode example to invoke the `indigo.host.debugMode()`
method before converting its returned integer to a boolean, ensuring
`debug_mode_bool` reflects the actual debugger state rather than the bound
method.
reference/canonical/plugin-dev/reference/dev-environment.md-160-162 (1)

160-162: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Avoid shell interpolation in the restart utility.

CFBundleIdentifier is external file data and is inserted directly into os.system(...). Use argument-vector execution instead:

 import plistlib
+import subprocess
...
-            os.system(f"/usr/local/indigo/indigo-restart-plugin -d -n {plist_dict['CFBundleIdentifier']}")
+            subprocess.run(
+                ["/usr/local/indigo/indigo-restart-plugin", "-d", "-n",
+                 plist_dict["CFBundleIdentifier"]],
+                check=True,
+            )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/dev-environment.md` around lines 160
- 162, The restart command currently interpolates the external
CFBundleIdentifier value into os.system, creating shell-injection risk. Replace
this invocation with argument-vector execution, such as subprocess.run or
subprocess.call with a list of arguments, while preserving the existing utility
flags and plist_dict['CFBundleIdentifier'] value.
reference/canonical/plugin-dev/reference/plugin-py/general-methods.md-79-82 (1)

79-82: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the destructor example’s super() call.

super().__del__(self) passes self twice because super().__del__ is already bound. The example should call super().__del__().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py/general-methods.md` around
lines 79 - 82, Update the __del__ destructor example to call the bound
superclass method as super().__del__() without passing self explicitly.
reference/canonical/plugin-dev/reference/plugin-py/general-methods.md-203-205 (1)

203-205: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Preserve the default sleep/wake lifecycle behavior.

These methods stop/start device communication and trigger processing by default. The guidance should tell overriding implementations to call super().prepareToSleep() and super().wakeUp() unless they intentionally replace that behavior.

Also applies to: 237-239

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py/general-methods.md` around
lines 203 - 205, Update the prepareToSleep() and wakeUp() guidance to state that
overriding implementations should call super().prepareToSleep() and
super().wakeUp() to preserve the default device communication and
trigger-processing lifecycle, unless intentionally replacing that behavior.
reference/canonical/plugin-dev/reference/plugin-py/device-methods.md-290-293 (1)

290-293: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Return a state ID, not a state value.

getDeviceDisplayStateId() must return the identifier of the state to display. dev.states['some_state_id'] returns that state’s value; the example should return the key or select a key dynamically.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py/device-methods.md` around
lines 290 - 293, Update getDeviceDisplayStateId() to return the state identifier
key, such as "some_state_id", rather than indexing dev.states and returning its
value; if the identifier is dynamic, select and return the appropriate key from
dev.states.
reference/canonical/plugin-dev/reference/plugin-py/http-requests.md-5-14 (1)

5-14: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not recommend sending API keys in query strings.

Query parameters are commonly logged and propagated, which can expose the bearer credential. Require the Authorization header, or clearly document the query-string form as a legacy/insecure fallback with strict leakage warnings.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py/http-requests.md` around
lines 5 - 14, The HTTP authentication guidance in the plugin request
documentation permits insecure API-key query parameters. Update the
authentication section to require the Authorization header as the recommended
and supported method, and remove the query-string example or explicitly label it
as a legacy insecure fallback with prominent warnings about logging and
credential leakage.
reference/canonical/plugin-dev/reference/plugin-py/device-methods.md-297-305 (1)

297-305: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the actual method name in the guidance.

The prose names get_device_state_list(), but the API method is getDeviceStateList(). Users copying the prose would define a method Indigo never calls.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py/device-methods.md` around
lines 297 - 305, Replace the prose references to get_device_state_list() with
the actual API method name getDeviceStateList(), including the subclassing
guidance, so users implement the method the server invokes.
reference/canonical/plugin-dev/reference/plugin-py/trigger-methods.md-36-44 (1)

36-44: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Invert the property-change comparison.

The example currently returns True when the values are equal, despite the description saying it should identify changed properties. Correct the generated source:

 def didTriggerProcessingPropertyChange(self, origTrigger, newTrigger):
-    some_property_changed = (origTrigger['some_prop'] == newTrigger['some_prop'])
+    some_property_changed = (origTrigger['some_prop'] != newTrigger['some_prop'])

Otherwise trigger processing can restart for unchanged configuration and fail to restart after a real change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py/trigger-methods.md` around
lines 36 - 44, Correct didTriggerProcessingPropertyChange so
some_property_changed is true only when origTrigger['some_prop'] and
newTrigger['some_prop'] differ; preserve the existing boolean return behavior so
processing restarts only after an actual property change.
reference/canonical/scripting/reference/device-subclasses/multiio.md-34-35 (1)

34-35: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Correct the sensorInputsAll type description.

This row describes sensor input values as binary values and booleans, contradicting the preceding sensorInputs and sensorInput# definitions, which correctly identify them as integers.

-| <span class="nw cb">`sensorInputsAll`</span>  | string  | N/A           | a comma separated list of all binary input values. Can be accessed as a Python list of booleans by using `dev.sensorInputs`.                        |
+| <span class="nw cb">`sensorInputsAll`</span>  | string  | N/A           | a comma-separated list of all sensor input values. Can be accessed as a Python list of integers by using `dev.sensorInputs`.                        |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/reference/device-subclasses/multiio.md` around
lines 34 - 35, Update the sensorInputsAll entry in the multi-I/O device property
table so its description consistently identifies the comma-separated values as
integers, removing references to binary values and booleans while preserving the
sensorInputs access detail as appropriate.
reference/canonical/scripting/reference/device-subclasses/speedcontrol.md-69-77 (1)

69-77: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the Set Speed Index example.

Line 77 calls increaseSpeedIndex even though this section documents setSpeedIndex. Users copying the example will execute a different command than intended.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/reference/device-subclasses/speedcontrol.md`
around lines 69 - 77, Update the second command example in the “Set Speed Index”
section to call indigo.speedcontrol.setSpeedIndex instead of increaseSpeedIndex,
while preserving its intended arguments.
reference/canonical/scripting/reference/device-subclasses/speedcontrol.md-23-23 (1)

23-23: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Change speedIndex state type to integer.

The class property at Line 12 and the speed-index commands define this value as an integer, but the state table says boolean. Correct the canonical source and regenerate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/scripting/reference/device-subclasses/speedcontrol.md` at
line 23, Update the speedIndex state type from boolean to integer in the
canonical source, ensuring it matches the class property and speed-index command
definitions; then regenerate the derived documentation.
reference/canonical/plugin-dev/reference/xml/devices.md-64-71 (1)

64-71: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the documented indigo.device.create signature

This example passes indigo.kRelayDeviceSubType.Plugin as the first positional argument and omits protocol and name, so it doesn’t match the documented call shape shown later.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/xml/devices.md` around lines 64 -
71, Update the example using indigo.device.create to match its documented
signature: pass the device name and protocol explicitly, and use
indigo.kRelayDeviceSubType.Plugin in the appropriate subtype argument rather
than as the first positional argument. Keep the subsequent model, subModel, and
name assignments consistent with the creation call.
🧹 Nitpick comments (2)
reference/canonical/plugin-dev.md (1)

9-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use Plugin capitalization for Indigo components.

Use lowercase only for identifiers such as plugin.py; prose referring to Indigo tools should use Plugin.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev.md` around lines 9 - 11, Update the prose in
the canonical plugin developer guide to capitalize Indigo component references
as “Plugin,” including “Plugin Developer’s Guide,” “Plugin Host,” and “Plugin
callbacks,” while keeping lowercase only for identifiers such as plugin.py.

Source: Coding guidelines

reference/canonical/plugin-dev/reference/plugin-py/logging.md (1)

21-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use warning() instead of deprecated warn().

The example should demonstrate the supported logging API:

-self.logger.warn(u"Warning log message")
+self.logger.warning(u"Warning log message")

Please verify the generated source against the Python logging API before regenerating.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/plugin-py/logging.md` around lines
21 - 26, Replace the deprecated self.logger.warn() example with
self.logger.warning() in the logging API example, then verify the generated
source uses the supported Python logging method before regenerating.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5e50d57a-9c98-41ea-abe5-61b838217383

📥 Commits

Reviewing files that changed from the base of the PR and between 05c6678 and 28f22ca.

📒 Files selected for processing (115)
  • .claude-plugin/marketplace.json
  • .claude-plugin/plugin.json
  • README.md
  • commands/api.md
  • commands/dev.md
  • commands/html-pages.md
  • docs/api/README.md
  • docs/api/authentication.md
  • docs/api/device-commands.md
  • docs/api/http-api.md
  • docs/api/overview.md
  • docs/api/websocket-api.md
  • docs/plans/2026-07-09-canonical-docs-audit.md
  • docs/plans/2026-07-09-canonical-hybrid-restructure.md
  • docs/plugin-dev/README.md
  • docs/plugin-dev/api/README.md
  • docs/plugin-dev/api/indigo-object-model.md
  • docs/plugin-dev/api/iom/architecture.md
  • docs/plugin-dev/api/iom/command-namespaces.md
  • docs/plugin-dev/api/iom/constants.md
  • docs/plugin-dev/api/iom/containers.md
  • docs/plugin-dev/api/iom/devices.md
  • docs/plugin-dev/api/iom/filters.md
  • docs/plugin-dev/api/iom/subscriptions.md
  • docs/plugin-dev/api/iom/triggers.md
  • docs/plugin-dev/api/iom/utilities.md
  • docs/plugin-dev/concepts/README.md
  • docs/plugin-dev/concepts/actions.md
  • docs/plugin-dev/concepts/configui.md
  • docs/plugin-dev/concepts/devices.md
  • docs/plugin-dev/concepts/events.md
  • docs/plugin-dev/concepts/http-responder.md
  • docs/plugin-dev/concepts/menu-items.md
  • docs/plugin-dev/concepts/plugin-lifecycle.md
  • docs/plugin-dev/concepts/plugin-preferences.md
  • docs/plugin-dev/concepts/scripting-shell.md
  • docs/plugin-dev/patterns/testing.md
  • docs/plugin-dev/quick-start.md
  • docs/plugin-dev/troubleshooting/common-issues.md
  • reference/README.md
  • reference/canonical/INDEX.md
  • reference/canonical/VERSION
  • reference/canonical/api.md
  • reference/canonical/api/http.md
  • reference/canonical/api/messages.md
  • reference/canonical/api/rest-migration.md
  • reference/canonical/api/webhooks.md
  • reference/canonical/api/websocket.md
  • reference/canonical/plugin-dev.md
  • reference/canonical/plugin-dev/guide.md
  • reference/canonical/plugin-dev/reference/dev-environment.md
  • reference/canonical/plugin-dev/reference/plugin-py.md
  • reference/canonical/plugin-dev/reference/plugin-py/additional-topics.md
  • reference/canonical/plugin-dev/reference/plugin-py/device-methods.md
  • reference/canonical/plugin-dev/reference/plugin-py/general-methods.md
  • reference/canonical/plugin-dev/reference/plugin-py/helper-methods.md
  • reference/canonical/plugin-dev/reference/plugin-py/http-requests.md
  • reference/canonical/plugin-dev/reference/plugin-py/logging.md
  • reference/canonical/plugin-dev/reference/plugin-py/message-flow.md
  • reference/canonical/plugin-dev/reference/plugin-py/properties.md
  • reference/canonical/plugin-dev/reference/plugin-py/trigger-methods.md
  • reference/canonical/plugin-dev/reference/plugin-py/variable-methods.md
  • reference/canonical/plugin-dev/reference/xml.md
  • reference/canonical/plugin-dev/reference/xml/actions.md
  • reference/canonical/plugin-dev/reference/xml/configui.md
  • reference/canonical/plugin-dev/reference/xml/configui/button.md
  • reference/canonical/plugin-dev/reference/xml/configui/checkbox.md
  • reference/canonical/plugin-dev/reference/xml/configui/color-picker.md
  • reference/canonical/plugin-dev/reference/xml/configui/dialog-close.md
  • reference/canonical/plugin-dev/reference/xml/configui/dynamic-lists.md
  • reference/canonical/plugin-dev/reference/xml/configui/label.md
  • reference/canonical/plugin-dev/reference/xml/configui/list.md
  • reference/canonical/plugin-dev/reference/xml/configui/popup-menu.md
  • reference/canonical/plugin-dev/reference/xml/configui/separator.md
  • reference/canonical/plugin-dev/reference/xml/configui/serial-port.md
  • reference/canonical/plugin-dev/reference/xml/configui/text-field.md
  • reference/canonical/plugin-dev/reference/xml/configui/validation.md
  • reference/canonical/plugin-dev/reference/xml/devices.md
  • reference/canonical/plugin-dev/reference/xml/events.md
  • reference/canonical/plugin-dev/reference/xml/menuitems.md
  • reference/canonical/plugin-dev/reference/xml/pluginconfig.md
  • reference/canonical/plugin-dev/reference/xml/supporturl.md
  • reference/canonical/plugin-dev/sdk-examples.md
  • reference/canonical/plugin-dev/tutorials/building.md
  • reference/canonical/scripting.md
  • reference/canonical/scripting/guides/python-packages.md
  • reference/canonical/scripting/iom-concepts.md
  • reference/canonical/scripting/reference/action-groups.md
  • reference/canonical/scripting/reference/actions.md
  • reference/canonical/scripting/reference/device-subclasses.md
  • reference/canonical/scripting/reference/device-subclasses/dimmer.md
  • reference/canonical/scripting/reference/device-subclasses/multiio.md
  • reference/canonical/scripting/reference/device-subclasses/relay.md
  • reference/canonical/scripting/reference/device-subclasses/sensor.md
  • reference/canonical/scripting/reference/device-subclasses/speedcontrol.md
  • reference/canonical/scripting/reference/device-subclasses/sprinkler.md
  • reference/canonical/scripting/reference/device-subclasses/thermostat.md
  • reference/canonical/scripting/reference/devices.md
  • reference/canonical/scripting/reference/devices/base-class.md
  • reference/canonical/scripting/reference/devices/dictionary.md
  • reference/canonical/scripting/reference/event-data-paths.md
  • reference/canonical/scripting/reference/folders.md
  • reference/canonical/scripting/reference/insteon-commands.md
  • reference/canonical/scripting/reference/schedules.md
  • reference/canonical/scripting/reference/server-commands.md
  • reference/canonical/scripting/reference/triggers.md
  • reference/canonical/scripting/reference/utils.md
  • reference/canonical/scripting/reference/variables.md
  • reference/canonical/scripting/reference/x10-commands.md
  • reference/canonical/scripting/tutorial.md
  • skills/api/SKILL.md
  • skills/dev/SKILL.md
  • skills/html-pages/SKILL.md
  • skills/html-pages/references/indigo-api-js.md
  • tools/refresh_canonical.py
💤 Files with no reviewable changes (26)
  • docs/api/overview.md
  • docs/plugin-dev/concepts/scripting-shell.md
  • docs/plugin-dev/api/iom/command-namespaces.md
  • docs/plugin-dev/concepts/menu-items.md
  • docs/plugin-dev/concepts/actions.md
  • docs/plugin-dev/api/iom/devices.md
  • docs/plugin-dev/api/iom/triggers.md
  • docs/plugin-dev/concepts/devices.md
  • docs/plugin-dev/concepts/http-responder.md
  • docs/plugin-dev/api/iom/containers.md
  • docs/plugin-dev/api/README.md
  • docs/plugin-dev/api/iom/subscriptions.md
  • docs/plugin-dev/api/indigo-object-model.md
  • docs/plugin-dev/api/iom/architecture.md
  • docs/plugin-dev/api/iom/constants.md
  • docs/plugin-dev/concepts/configui.md
  • docs/api/http-api.md
  • docs/api/authentication.md
  • docs/plugin-dev/api/iom/filters.md
  • docs/plugin-dev/concepts/events.md
  • docs/plugin-dev/concepts/README.md
  • docs/api/websocket-api.md
  • docs/api/README.md
  • docs/plugin-dev/concepts/plugin-preferences.md
  • docs/plugin-dev/api/iom/utilities.md
  • docs/api/device-commands.md

Comment on lines +80 to +82
```xml
<Device type="sensor" subType="kSensorDeviceSubType.Temperature, ui=Outdoor Temperature" id="my_temp_sensor", allowUserCreation="false">
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix the malformed XML attribute syntax.

The comma after id="my_temp_sensor" makes this snippet invalid XML. Remove it before publishing the example.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/xml/devices.md` around lines 80 -
82, Remove the comma after the id attribute in the Device XML example so the
opening tag is valid XML, preserving the existing attributes and values.

Comment on lines +69 to +77
```python
def turnOffLight(self, valuesDict, typeId):
indigo.server.log(f"Turning off light: {valuesDict["targetDevice"]}")
# perform the action here. If there are errors in any of the fields then
# you can return (False, valuesDict, errorsDict) just like a validation
# method and the dialog won't close and will show the errors. If you
# return True then the dialog will close when the method completes.
errorsDict = indigo.Dict()
return (True, valuesDict, errorsDict)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix the invalid f-string in the copy-paste example.

The outer and inner strings both use double quotes:

indigo.server.log(f"Turning off light: {valuesDict["targetDevice"]}")

Use single quotes for the dictionary key or the outer string.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/reference/xml/menuitems.md` around lines 69 -
77, Fix the invalid f-string in the turnOffLight example by changing either the
valuesDict key quotes or the outer f-string quotes so the delimiters do not
conflict; preserve the existing log message and behavior.

Comment on lines +161 to +164
```xml
<?xml version="1.0"?>
<Events>
<SupportURL>http://www.yourdomain.com/plugin/pluginEvents.html</SupportURL>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Move the XML declaration to the first character.

Leading spaces before <?xml version="1.0"?> can make the copied XML document invalid because the declaration must appear at the beginning.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/tutorials/building.md` around lines 161 - 164,
Remove the leading whitespace before the XML declaration in the Events example
so <?xml version="1.0"?> is the document’s first characters, before the Events
element.

Comment on lines +233 to +242
```python
def deviceCreated(self, dev):
# Receives a copy of the device instance
self.logger.debug(f"{dev.name} created."
```
```python
def deviceDeleted(self, dev):
# Receives a copy of the device instance
self.logger.info(f"{dev.name} deleted."
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Close both logger calls in the device callback examples.

The deviceCreated and deviceDeleted snippets are missing a closing ), so neither example is valid Python.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/canonical/plugin-dev/tutorials/building.md` around lines 233 - 242,
Fix the `deviceCreated` and `deviceDeleted` callback examples by adding the
missing closing parenthesis to each `self.logger.debug` and `self.logger.info`
call, respectively, so both snippets are valid Python.

simons-plugins and others added 3 commits July 10, 2026 06:43
Reconcile with PR #41 (merged after this branch started), which added
undocumented Indigo field knowledge to four concepts/ files this branch had
deleted. Keep those files (they hold non-canonical gotchas — state-ID naming
rules, uiPath crash, dynamic-state cache corruption, cross-plugin executeAction,
deviceUpdated loop guard, custom-event method traps, pluginProps underscore
rule); they are thinned to field-notes in the following commit. Keep version
2.0.0 over main's 1.9.5; common-issues.md auto-merged (both changes retained).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
…dev skill

The 4 concept files re-added by the #41 merge each mixed canonical-duplicating
narrative with genuinely undocumented field knowledge. Strip the narrative
(now in reference/canonical/) and keep only the field notes:

- devices.md: state-ID naming rules, reserved-name shadowing, dynamic
  getDeviceStateList live-cache trap, deviceUpdated self-loop guard
- actions.md: uiPath PascalCase (client crash), cross-plugin executeAction
- events.md: fireEvent/triggerEvent don't exist -> trigger.execute pattern
- plugin-preferences.md: pluginPrefs vs pluginProps '_' prefix rule

Fix their See-Also links (were pointing at deleted files) to canonical, and
surface the field notes prominently from skills/dev/SKILL.md + commands/dev.md.
The State-ID heading anchor is preserved (common-issues.md links to it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
…om/ files)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
@simons-plugins
simons-plugins merged commit 6eb4094 into main Jul 10, 2026
2 checks passed
@simons-plugins
simons-plugins deleted the feat/canonical-docs-restructure branch July 10, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant