Skip to content

Add SEO Dungeon#224

Open
avalonreset wants to merge 1 commit into
hashgraph-online:mainfrom
avalonreset:add-seo-dungeon
Open

Add SEO Dungeon#224
avalonreset wants to merge 1 commit into
hashgraph-online:mainfrom
avalonreset:add-seo-dungeon

Conversation

@avalonreset

Copy link
Copy Markdown

Summary

  • Add SEO Dungeon to the Tools & Integrations section.
  • Mirror the installable SEO Dungeon bundle under plugins/avalonreset/seo-dungeon.
  • Update plugins.json and .agents/plugins/marketplace.json with the new marketplace entry.

Validation

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the "seo-dungeon" plugin, a gamified local SEO audit tool integrated with Codex, Claude, and Gemini CLI workflows. The changes include adding the plugin to the marketplace, README, and plugins registry, alongside its extensive suite of SEO skills, templates, and references. The review feedback highlights a critical runtime issue where the hook configuration references scripts that are missing from the repository. Additionally, several robustness improvements are recommended in the interactive cluster map template, specifically to prevent potential TypeErrors when parsing malformed data and to handle edge cases in the color-darkening utility. Finally, a naming inconsistency in the plugin registry should be resolved to use the canonical lowercase name.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +11 to +12
"${CLAUDE_PLUGIN_ROOT}/hooks/run-python-hook.js",
"${CLAUDE_PLUGIN_ROOT}/hooks/validate-schema.py",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The hook references run-python-hook.js and validate-schema.py inside the hooks/ directory, but these files are not included in the pull request. This will cause the PostToolUse hook to fail at runtime when trying to execute the command.

Comment on lines +581 to +589
function darken(hex) {
var r = parseInt(hex.slice(1, 3), 16);
var g = parseInt(hex.slice(3, 5), 16);
var b = parseInt(hex.slice(5, 7), 16);
r = Math.max(0, Math.floor(r * 0.75));
g = Math.max(0, Math.floor(g * 0.75));
b = Math.max(0, Math.floor(b * 0.75));
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The darken function assumes that the hex parameter is always a 7-character string starting with # followed by 6 hex digits. If a 3-character hex code (e.g., #fff) or a CSS color name is passed, this function will produce NaN values and return an invalid color string (e.g., #an). Consider adding support for 3-character hex codes and a fallback mechanism.

    function darken(hex) {
      if (!hex || hex.indexOf('#') !== 0) return '#000000';
      var color = hex.slice(1);
      if (color.length === 3) {
        color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
      }
      if (color.length !== 6) return '#000000';
      var r = parseInt(color.slice(0, 2), 16);
      var g = parseInt(color.slice(2, 4), 16);
      var b = parseInt(color.slice(4, 6), 16);
      r = Math.max(0, Math.floor(r * 0.75));
      g = Math.max(0, Math.floor(g * 0.75));
      b = Math.max(0, Math.floor(b * 0.75));
      return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
    }

Comment on lines +465 to +469
} else {
const parts = nodeId.match(/cluster-(\d+)-post-(\d+)/);
if (!parts) return;
info = data.clusters[parseInt(parts[1])].posts[parseInt(parts[2])];
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Accessing data.clusters[parseInt(parts[1])].posts directly without verifying if the cluster at the parsed index exists can lead to a TypeError if the index is out of bounds or the data is malformed. Additionally, it is a best practice to specify the radix (base 10) for parseInt.

Suggested change
} else {
const parts = nodeId.match(/cluster-(\d+)-post-(\d+)/);
if (!parts) return;
info = data.clusters[parseInt(parts[1])].posts[parseInt(parts[2])];
}
} else {
const parts = nodeId.match(/cluster-(\d+)-post-(\d+)/);
if (!parts) return;
const cluster = data.clusters[parseInt(parts[1], 10)];
if (cluster && cluster.posts) {
info = cluster.posts[parseInt(parts[2], 10)];
}
}

Comment on lines +558 to +564
} else {
const parts = nodeId.match(/cluster-(\d+)-post-(\d+)/);
if (parts) {
const post = data.clusters[parseInt(parts[1])].posts[parseInt(parts[2])];
label = "Spoke page: " + post.title;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Accessing data.clusters[parseInt(parts[1])].posts directly without verifying if the cluster at the parsed index exists can lead to a TypeError if the index is out of bounds or the data is malformed. Additionally, it is a best practice to specify the radix (base 10) for parseInt.

Suggested change
} else {
const parts = nodeId.match(/cluster-(\d+)-post-(\d+)/);
if (parts) {
const post = data.clusters[parseInt(parts[1])].posts[parseInt(parts[2])];
label = "Spoke page: " + post.title;
}
}
} else {
const parts = nodeId.match(/cluster-(\d+)-post-(\d+)/);
if (parts) {
const cluster = data.clusters[parseInt(parts[1], 10)];
const post = cluster && cluster.posts ? cluster.posts[parseInt(parts[2], 10)] : null;
if (post) {
label = "Spoke page: " + post.title;
}
}
}

Comment thread plugins.json
"install_url": "https://raw.githubusercontent.com/jingjing2222/rust-reverse-engineering-skill/HEAD/.codex-plugin/plugin.json"
},
{
"name": "SEO Dungeon",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The name of the plugin in plugins.json is set to "SEO Dungeon", but in .agents/plugins/marketplace.json and the plugin's own plugin.json it is defined as "seo-dungeon". It is recommended to use the lowercase canonical name "seo-dungeon" to maintain consistency across all registry files.

Suggested change
"name": "SEO Dungeon",
"name": "seo-dungeon",

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