Skills
Skill 22 of 32
Review open comment threads on a Webflow site and triage each one.
4 minutes · 838 words · 14 sections
Install
npx skills add webflow/webflow-skills --skill webflow-mcp:review-commentsnpx skills add webflow/webflow-skills/plugin marketplace add webflow/webflow-skillsThe first command installs just this skill, by the name in its SKILL.md; the second installs the whole repository.
Review open comment threads on a Webflow site and triage each one.
Input: $ARGUMENTS — a site name (e.g. “Workhaus”), site ID (e.g. 6808fd4eff835ee3af009d6f), or either with the -reply flag (e.g. Workhaus -reply).
Flags:
-reply — in addition to writing the report, post a bot reply to each non-open thread. Without this flag, the skill runs in report-only mode (read-only).Parse $ARGUMENTS at the start: strip -reply from the input to get the site identifier, and set replyMode = true if -reply was present, false otherwise.
data_sites_tool > list_sites to get all sites. Page through until all are collected.data_comments_tool > list_comment_threads with isResolved: false and limit: 100. Page through until all unresolved threads are collected. If the API does not support isResolved filtering, fetch all threads and filter client-side to isResolved === false. Process sites in batches of 20 (batch multiple actions in a single tool call). After each batch completes, log a progress line: Batch {N}/{total} done (sites {start}–{end}): {summary of findings, e.g. "all 0 threads" or "SiteName has X threads, rest 0"}.unresolvedCount = total unresolved threadsnewestDate = the maximum lastUpdated value across all unresolved threads for that site (ISO → human-readable date, e.g. “Apr 3, 2026”). If no threads, show —.oldestDate = the minimum lastUpdated value across all unresolved threads for that site (ISO → human-readable date). If no threads, show —.unresolvedCount descending. Take the top 10.### Checked {totalSiteCount} sites — {sitesWithUnresolved} have unresolved comments.https://webflow.com/design/{siteId}):| Site | Unresolved Comments | Newest / Oldest |
|------|---------------------|-----------------|
| [Site Name](https://webflow.com/design/{siteId}) ({siteId}) | {N} | {newestDate} / {oldestDate} |/webflow-mcp:review-comments <site name or ID> to review a specific site.”comment-reviews/ exists (create with mkdir comment-reviews if not).comment-reviews/triage-report-{YYYY-MM-DD-HH-MM}.md using the current local time (zero-padded).# **Webflow Comment Review**, then a blank line, then an H3 line ### Report created on: {human-readable date, time, and timezone, e.g. "April 16, 2026 at 10:39 AM PDT"}, then a blank line, then the H3 heading line (### Checked …) and the full table from steps 5–6 above, in markdown.Report written to comment-reviews/triage-report-2026-04-16-14-30.md.data_sites_tool > list_sites and find the site whose displayName matches the identifier (case-insensitive). If no match, tell the user and stop.Always make a fresh API call here — never reuse thread data from earlier in the conversation. The user may have added or resolved comments since the last run.
Call data_comments_tool > list_comment_threads with isResolved: false and limit: 100. Page through results until all threads are collected.
Log: Site: {displayName} and Found {N} open thread(s).
From the already-fetched thread list, build a frequency map of elementId.element → Set<pageId> across all threads. Any elementId.element that appears on 2 or more distinct pages is almost certainly the page root/body element (a real element ID would be page-scoped; only shared structural roots repeat across pages).
No API calls needed — this is a local computation on the thread data.
For each thread:
Call data_comments_tool > list_comment_replies for this thread.
Look for replies whose content includes the string — 🤖 Comment Review Agent.
If found, note the most recent one (lastAgentReply). If no human reply exists with a createdOn after lastAgentReply.createdOn, skip this thread (increment skipped count, continue to next thread).
elementId = thread.elementId?.elementisPageLevel = elementId appears on 2 or more distinct pageIds in the frequency map from Step 3Use the following criteria:
noise — No real design or engineering value:
stale — Real concern, but old and likely handled:
open — Real, actionable concern needing attention:
page-level — Comment is on the page root, not a specific element:
isPageLevel is trueAlways compose the reply text (it appears in the report regardless of mode):
"Looks like test text — safe to resolve.""This is 302 days old with no follow-up. Safe to resolve — reply here if it's still relevant.""This comment is on the page root rather than a specific element — it may be an orphan from a deleted element. Safe to resolve if no longer relevant."Append \n\n— 🤖 Comment Review Agent to every reply text.
replyMode = true)If replyMode is true and verdict is not open, call data_comments_tool > create_reply with the composed reply content.
Log each thread as:
{VERDICT_EMOJI} {verdict} "{preview (60 chars)}"
{one-sentence classification reason}
↳ {reply posted | no reply — report only | skipped}Verdict emojis: noise = 🗑, stale = 🕰, open = 🔴, page-level = 📄
After processing all threads:
comment-reviews/ directory exists at the top level of the working directory. If it does not exist, create it with mkdir comment-reviews.comment-reviews/{slugified-site-name}-comments-triage-report.md (lowercase, hyphens, no special chars).Report format:
# Comment Review — [{siteName} ({siteId})](https://webflow.com/design/{siteId})
**Run:** {human-readable date and time}
**Mode:** {Report only | Report + replies posted}
**Threads:** {total} total | 🔴 {open} open | 🕰 {stale} stale | 📄 {page-level} page-level | 🗑 {noise} noise | ⏭ {skipped} skipped
---
Use _None._ for any section with no entries.
Log a summary line and confirm the report path.
main, last pushed 21 September 2026.SKILL.md, not by matching a directory convention. One layout observed: plugins/webflow-skills/skills/*/SKILL.md..claude-plugin/marketplace.json by Webflow, declaring 1 plugin. It is read for editorial metadata only — never as the skill index, which is always the repository tree./webflow/webflow-skills.md, and each skill at its own .md URL.