Skip to content

fix(docs): tool-table completeness — 16 vanished tools restored + hard check - #42

Merged
simons-plugins merged 1 commit into
mainfrom
fix/tool-table-completeness
Jul 23, 2026
Merged

fix(docs): tool-table completeness — 16 vanished tools restored + hard check#42
simons-plugins merged 1 commit into
mainfrom
fix/tool-table-completeness

Conversation

@simons-plugins

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

Copy link
Copy Markdown
Owner

Closes #41. All 71 tools now render (was ~55); the generator fails loudly if any registered tool lands in zero or two groups, so this bug class is dead. 2026.8.0 → 2026.8.1.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EYAGXd4bE9D9Z5kZeSHeo7

Summary by CodeRabbit

  • New Features

    • Added a dedicated History tools section to the tool documentation.
    • Expanded documentation for control and action tools, including scheduling, sprinklers, thermostats, triggers, and variables.
    • Improved tool documentation validation to detect missing or incorrectly categorized tools.
  • Documentation

    • Reclassified SQL Logger tools under History tools.
    • Updated tool counts and listings throughout the README.
  • Chores

    • Updated the application and package version to 2026.8.1.

trigger/schedule/sprinkler/speedcontrol controls and query_sql_logger
matched no group predicate and were absent from the README table for
five releases (~16 tools). Predicates extended, History group added,
and the generator now exits non-zero naming any tool that lands in
zero or two groups. Closes #41.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYAGXd4bE9D9Z5kZeSHeo7
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The tool documentation generator adds History classification, expands Control matching, and validates that every tool belongs to exactly one group. The README reflects the revised counts and sections, while plugin and package versions advance to 2026.8.1.

Changes

Tool documentation grouping

Layer / File(s) Summary
Generator grouping and validation
scripts/generate_tool_doc.py
History tools are separated from Lookup tools, additional control prefixes are recognized, and generation exits with an error when a tool matches zero or multiple groups.
README and release metadata
README.md, Indigo MCP Lite.indigoPlugin/Contents/Info.plist, pyproject.toml
The README documents 18 Lookup, 42 Control, and 2 History tools; plugin and package versions are updated to 2026.8.1.

Estimated code review effort: 2 (Simple) | ~10 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 change: restoring missing tools in the tool table and adding a completeness check.
Linked Issues check ✅ Passed The generator now classifies the missing tools, adds History, and fails on zero/multiple-group matches as required by #41.
Out of Scope Changes check ✅ Passed The version bumps and README updates are directly tied to the documented release and tool-table changes, with no unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tool-table-completeness

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: 2

🧹 Nitpick comments (1)
scripts/generate_tool_doc.py (1)

85-105: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add regression coverage for the new grouping rules.

Cover every restored prefix, both History tools, Lookup exclusion, and zero/multiple-group failures so future predicate changes cannot silently alter the README count or classification.

🤖 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 `@scripts/generate_tool_doc.py` around lines 85 - 105, Add regression tests for
the grouping predicates and _GROUPS classification in generate_tool_doc.py,
covering every restored _is_control prefix, both _HISTORY_TOOLS entries, and
confirming history tools are excluded from _is_lookup_final. Also test that
zero-group and multiple-group matches fail, preserving the expected README tool
count and classification behavior.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@scripts/generate_tool_doc.py`:
- Around line 131-140: Move the completeness validation using placements and bad
in the tool-document generation flow so it runs before the first stdout print.
Ensure any validation failure exits without emitting the generated header or
partial README content, while preserving the existing exactly-one-group check.
- Around line 135-136: Rename the single-letter comprehension bindings in the
placements construction to descriptive names, using labels such as label and
predicate for _GROUPS entries and retaining clear names for tool names and group
collections. Update only the affected comprehensions while preserving the
existing placements and bad calculations.

---

Nitpick comments:
In `@scripts/generate_tool_doc.py`:
- Around line 85-105: Add regression tests for the grouping predicates and
_GROUPS classification in generate_tool_doc.py, covering every restored
_is_control prefix, both _HISTORY_TOOLS entries, and confirming history tools
are excluded from _is_lookup_final. Also test that zero-group and multiple-group
matches fail, preserving the expected README tool count and classification
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c51cf847-3408-4c21-be48-c49b93078418

📥 Commits

Reviewing files that changed from the base of the PR and between ff03fef and 3372546.

📒 Files selected for processing (4)
  • Indigo MCP Lite.indigoPlugin/Contents/Info.plist
  • README.md
  • pyproject.toml
  • scripts/generate_tool_doc.py

Comment on lines +131 to +140
# Completeness check: every tool must land in EXACTLY one group.
# A tool matching none silently vanished from the README for five
# releases (trigger/schedule/sprinkler/speedcontrol/query_sql_logger)
# — fail loudly instead.
placements = {name: [l for l, p in _GROUPS if p(name)] for name, _ in tools}
bad = {n: ls for n, ls in placements.items() if len(ls) != 1}
if bad:
import sys
print(f"ERROR: tools not in exactly one group: {bad}", file=sys.stderr)
sys.exit(1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Validate group coverage before emitting output.

The script prints the generated header before checking completeness. If stdout is redirected into README.md, a failed run can leave a partial generated document. Move this validation before the first print(...), or stage output and replace the file only after success.

🧰 Tools
🪛 Ruff (0.15.21)

[error] 135-135: Ambiguous variable name: l

(E741)

🤖 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 `@scripts/generate_tool_doc.py` around lines 131 - 140, Move the completeness
validation using placements and bad in the tool-document generation flow so it
runs before the first stdout print. Ensure any validation failure exits without
emitting the generated header or partial README content, while preserving the
existing exactly-one-group check.

Comment on lines +135 to +136
placements = {name: [l for l, p in _GROUPS if p(name)] for name, _ in tools}
bad = {n: ls for n, ls in placements.items() if len(ls) != 1}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository files matching generate_tool_doc.py:"
git ls-files | rg '(^|/)generate_tool_doc\.py$' || true

file="$(git ls-files | rg '(^|/)generate_tool_doc\.py$' | head -n1)"
if [ -n "${file:-}" ]; then
  echo
  echo "File: $file"
  echo "Line count:"
  wc -l "$file"
  echo
  echo "Relevant lines 125-145:"
  sed -n '125,145p' "$file" | nl -ba -v125
  echo
  echo "Imports/top context:"
  sed -n '1,80p' "$file" | nl -ba -v1
fi

echo
echo "Search for Ruff config and E741 references:"
git ls-files | rg '(^|/)(pyproject\.toml|setup\.cfg|ruff\.toml|\.ruff\.toml)$' || true
rg -n "E741|ruff|select|ignore" -S pyproject.toml setup.cfg ruff.toml .ruff.toml 2>/dev/null || true

Repository: simons-plugins/indigo-mcp-lite

Length of output: 392


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="scripts/generate_tool_doc.py"

echo "Relevant lines 125-145:"
awk 'NR>=125 && NR<=145 {printf "%4d: %s\n", NR, $0}' "$file"

echo
echo "Imports/top context:"
awk 'NR>=1 && NR<=80 {printf "%4d: %s\n", NR, $0}' "$file"

echo
echo "Search for Ruff config:"
git ls-files | awk 'tolower($0) ~ /(^(|.*\/)(pyproject\.toml|setup\.cfg|ruff\.toml|\.ruff\.toml))$/ {print}'

echo
echo "Ruff/E741 references in configs:"
for f in $(git ls-files | awk 'tolower($0) ~ /(^(|.*\/)(pyproject\.toml|setup\.cfg|ruff\.toml|\.ruff\.toml))$/ {print}'); do
  echo "--- $f"
  grep -InEi 'E741|ruff|select|ignore' "$f" || true
done

Repository: simons-plugins/indigo-mcp-lite

Length of output: 4380


🌐 Web query:

Ruff rule E741 ambiguous variable name l

💡 Result:

The Ruff lint rule E741, titled ambiguous-variable-name, flags the use of the characters 'l', 'O', or 'I' as variable names [1][2]. This rule is based on PEP 8 recommendations, which advise against using these specific characters because they can be easily confused with numerals in many fonts: - 'l' (lowercase L) can look like '1' (one). - 'O' (uppercase O) can look like '0' (zero). - 'I' (uppercase I) can look like '1' (one) or a lowercase 'l' depending on the font [1][3]. The rule suggests using more descriptive names or alternative identifiers (e.g., using 'L' instead of 'l') [1][3]. Important details regarding this rule in Ruff: - Rule Scope: It is automatically disabled for stub files (files with.pyi extensions), as stub authors often need to mirror the exact interface of the runtime module, including any legacy naming choices [1][4]. - Configuration: As with other lint rules, you can ignore E741 on a per-line basis using # noqa: E741, or configure it via the lint.ignore setting in your Ruff configuration file [5][6].

Citations:


Rename the ambiguous comprehension variables.

Ruff’s E741 rule flags single-letter bindings like l/O/I; use descriptive names such as label, predicate, name, and groups.

Proposed fix
-    placements = {name: [l for l, p in _GROUPS if p(name)] for name, _ in tools}
-    bad = {n: ls for n, ls in placements.items() if len(ls) != 1}
+    placements = {
+        name: [label for label, predicate in _GROUPS if predicate(name)]
+        for name, _ in tools
+    }
+    bad = {name: groups for name, groups in placements.items() if len(groups) != 1}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
placements = {name: [l for l, p in _GROUPS if p(name)] for name, _ in tools}
bad = {n: ls for n, ls in placements.items() if len(ls) != 1}
placements = {
name: [label for label, predicate in _GROUPS if predicate(name)]
for name, _ in tools
}
bad = {name: groups for name, groups in placements.items() if len(groups) != 1}
🧰 Tools
🪛 Ruff (0.15.21)

[error] 135-135: Ambiguous variable name: l

(E741)

🤖 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 `@scripts/generate_tool_doc.py` around lines 135 - 136, Rename the
single-letter comprehension bindings in the placements construction to
descriptive names, using labels such as label and predicate for _GROUPS entries
and retaining clear names for tool names and group collections. Update only the
affected comprehensions while preserving the existing placements and bad
calculations.

Source: Linters/SAST tools

@simons-plugins
simons-plugins merged commit 020af9a into main Jul 23, 2026
3 checks passed
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.

README tool table silently drops ~16 tools (generator predicates + no completeness check)

1 participant