Skip to content

Fix domain plugin manifests: all 10 packs fail install validation - #469

Merged
richard-devbot merged 3 commits into
mainfrom
fix-468-domain-plugin-manifest-paths
Jul 26, 2026
Merged

Fix domain plugin manifests: all 10 packs fail install validation#469
richard-devbot merged 3 commits into
mainfrom
fix-468-domain-plugin-manifest-paths

Conversation

@richard-devbot

@richard-devbot richard-devbot commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fixes Domain plugin packs fail to install: manifest 'Invalid input' on agents/commands/skills #468 — every one of the 10 consolidated domain plugin packs (backend, data-ml, devops-cloud, docs-content, frontend-mobile, languages, product-team, quality-testing, security, specialized) failed /plugin install with Validation errors: commands: Invalid input, agents: Invalid input, skills: Invalid input.
  • Root cause per Claude Code's plugin manifest spec: all path fields must be relative to the plugin root and start with ./; generate-domain-plugins.mjs built bare paths ("api-scaffolding/agents") with no prefix.
  • Second, narrower issue once the prefix was added: commands/skills accept directory paths, but agents only accepts individual .md file paths per the documented schema — a bare agents directory still failed. The generator now expands each sub-plugin's agents/ folder into its individual file entries instead.
  • Regenerated all 10 plugins/<domain>/plugin.json manifests + .claude-plugin/marketplace.json from the fixed generator (the original per-sub-plugin manifests it reads from were already removed by the earlier domain-consolidation cleanup, so entries were patched to match what the fixed generator now produces byte-for-byte).

Test plan

  • node scripts/generate-marketplace.mjs — marketplace.json regenerates identically (no diff)
  • npx tsx --test tests/marketplace-conformance.test.js — 4/4 pass, including "marketplace.json matches a fresh generation from plugins/*/plugin.json"
  • Live-verified via a local marketplace pointed at this branch: /plugin install backend (and the other domain packs) now install cleanly with zero manifest validation errors, vs. failing 100% of the time before this fix

Summary by CodeRabbit

  • Improvements

    • Plugin manifests now enumerate individual agent documents for more accurate discovery and selection.
    • Agent, command, and skill entries use consistent relative path formatting across plugin collections.
    • Generated domain manifests omit missing command/skill/agent sections to reduce invalid entries.
    • Agent lists are expanded and sorted for more predictable browsing.
  • Bug Fixes

    • Agent resolution now supports both direct agent documents and agent directories.
  • Tests

    • Added coverage to verify manifest path rules and correct omission/expansion behavior.

…lidation (#468)

commands/skills/agents path entries were missing the required "./" prefix
(Claude Code plugin manifest spec: "all paths must be relative to the plugin
root and start with ./") and agents pointed at bare directories where the
schema only accepts individual .md file paths. Fixed the generator and
regenerated all 10 domain plugin.json manifests + marketplace.json.

Live-verified: /plugin install backend (and the other 9 domain packs) now
install cleanly with no manifest validation errors.
@strix-security

strix-security Bot commented Jul 26, 2026

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for d5308f1.


Reviewed by Strix
Re-run review · Configure security review settings

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Plugin manifests now enumerate individual agent Markdown files, while command and skill directories use ./-prefixed paths. The domain manifest generator discovers existing resources, filters and sorts agent files, conditionally emits resource entries, and inventory loading accepts both directories and individual Markdown files.

Changes

Plugin manifest path expansion

Layer / File(s) Summary
Manifest generation logic
scripts/generate-domain-plugins.mjs
Manifest generation discovers agent Markdown files, checks command and skill directories, sorts agent paths, supports injected plugin directories, and emits normalized relative paths.
Explicit agent entrypoints
plugins/backend/plugin.json, plugins/data-ml/plugin.json, plugins/devops-cloud/plugin.json, plugins/docs-content/plugin.json, plugins/frontend-mobile/plugin.json, plugins/languages/plugin.json, plugins/product-team/plugin.json, plugins/quality-testing/plugin.json, plugins/security/plugin.json, plugins/specialized/plugin.json
Plugin manifests replace directory-level agent references with explicit Markdown agent paths.
Command and skill path normalization
plugins/*/plugin.json
Command and skill directory references gain ./ prefixes while preserving their existing targets.
Inventory compatibility and validation
src/core/inventory/backend-inventory.js, tests/generate-domain-plugins.test.js
Agent inventory resolution supports directories and individual Markdown files, and tests validate manifest path formats and omitted resource sections.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DomainGenerator
  participant PluginFolders
  participant DomainManifest
  participant Inventory
  DomainGenerator->>PluginFolders: inspect agent files and resource directories
  PluginFolders-->>DomainGenerator: return discovered paths
  DomainGenerator->>DomainManifest: write explicit agents and ./ resource paths
  Inventory->>DomainManifest: read manifest entries
  Inventory->>PluginFolders: resolve files or directories
  PluginFolders-->>Inventory: return Markdown files
Loading

Possibly related issues

Suggested reviewers: richardsongunde

Poem

A rabbit hops through folders bright,
Sorting agent files just right.
Commands gain a careful ./,
Skills follow the path anew.
Manifests bloom, neat and clear—
“Ship it!” twitches every ear.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: fixing domain plugin manifests that were failing install validation.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-468-domain-plugin-manifest-paths

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix consolidated domain plugin manifests to pass Claude Code install validation

🐞 Bug fix ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Fix domain pack plugin.json paths to satisfy Claude Code manifest schema requirements.
• Prefix commands/skills paths with "./" and expand agents to per-file .md entries.
• Regenerate all 10 domain pack manifests so /plugin install  validates cleanly.
Diagram

graph TD
  dev(["Maintainer"]) --> gen(["scripts/generate-domain-plugins.mjs"]) --> dom["plugins/<domain>/plugin.json"] --> mgen(["scripts/generate-marketplace.mjs"]) --> mkt[".claude-plugin/marketplace.json"] --> cli(["Claude Code /plugin install\nmanifest validator"])
  dom -."references".-> sub[/"plugins/<domain>/<sub>/*"/]
  subgraph Legend
    direction LR
    _actor(["Actor"]) ~~~ _script(["Script"]) ~~~ _file["JSON file"] ~~~ _dir[/"Directory"/]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Manually patch each domain plugin.json without changing the generator
  • ➕ Fastest short-term unblock if generation is rarely used
  • ➖ Regeneration would reintroduce the bug
  • ➖ Higher chance of drift/inconsistency across domains
2. Add/maintain per-domain agents index files (single file per sub-plugin)
  • ➕ Keeps agents list shorter in domain manifests
  • ➖ Adds extra build artifacts to maintain
  • ➖ Still requires explicit per-file references somewhere if schema forbids directories
3. Adjust tooling to validate manifests in CI before publishing/installing
  • ➕ Prevents future schema regressions regardless of generator changes
  • ➖ Does not fix current broken manifests by itself
  • ➖ Adds CI complexity and maintenance

Recommendation: The PR’s approach (fix the generator and regenerate manifests) is the right default: it removes the root cause and makes future regenerations safe. Consider adding a lightweight CI check that runs generation + manifest validation to prevent regressions, but keep the current generator behavior (explicit agent .md paths + "./" prefixing) as the source of truth.

Files changed (11) +278 / -154

Bug fix (1) +23 / -4
generate-domain-plugins.mjsGenerate schema-valid domain manifests (./ prefix + per-file agents) +23/-4

Generate schema-valid domain manifests (./ prefix + per-file agents)

• Updates generation logic to prefix commands/skills paths with "./" as required by the manifest schema. Changes agents generation to enumerate and sort individual .md files (using statSync) instead of emitting an agents directory path, matching Claude Code’s documented agents schema.

scripts/generate-domain-plugins.mjs

Other (10) +255 / -150
plugin.jsonMake backend domain manifest schema-compliant paths +40/-18

Make backend domain manifest schema-compliant paths

• Replaces bare agents directory entries with explicit ./-prefixed .md agent file paths. Adds required "./" prefix for commands and skills directory paths so Claude Code validation passes.

plugins/backend/plugin.json

plugin.jsonFix data-ml manifest paths and expand agents list +20/-14

Fix data-ml manifest paths and expand agents list

• Expands agents from directories to explicit .md files and prefixes paths with "./". Updates commands/skills entries to use schema-compliant relative directory paths.

plugins/data-ml/plugin.json

plugin.jsonFix devops-cloud manifest path formatting and agents schema +39/-18

Fix devops-cloud manifest path formatting and agents schema

• Converts agents entries to explicit .md files and ensures consistent "./"-prefixed relative paths. Updates commands/skills entries to directory paths with required prefix.

plugins/devops-cloud/plugin.json

plugin.jsonFix docs-content manifest paths and agent file references +23/-9

Fix docs-content manifest paths and agent file references

• Replaces agents directory references with explicit agent .md files and adds the required "./" prefix. Updates commands/skills paths to be validator-compliant.

plugins/docs-content/plugin.json

plugin.jsonFix frontend-mobile manifest relative paths and agent entries +23/-12

Fix frontend-mobile manifest relative paths and agent entries

• Expands agent directories into explicit .md file paths and applies "./" prefixing. Updates commands/skills directories to use schema-required relative path format.

plugins/frontend-mobile/plugin.json

plugin.jsonFix languages manifest paths; expand agents to .md entries +29/-18

Fix languages manifest paths; expand agents to .md entries

• Replaces agents directory paths with explicit sorted .md agent file references and prefixes with "./". Updates commands and skills paths to schema-compliant relative directories.

plugins/languages/plugin.json

plugin.jsonFix product-team manifest paths and agent schema compliance +24/-20

Fix product-team manifest paths and agent schema compliance

• Expands agents into explicit .md file paths rather than agent directories and prefixes with "./". Updates commands/skills directory paths to include the required prefix.

plugins/product-team/plugin.json

plugin.jsonFix quality-testing manifest paths and agent file listings +36/-25

Fix quality-testing manifest paths and agent file listings

• Converts agents entries from directories to explicit .md file paths and adds required "./" prefixing. Prefixes all commands and skills directory paths for Claude Code validation.

plugins/quality-testing/plugin.json

plugin.jsonFix security manifest relative paths and per-agent file references +9/-7

Fix security manifest relative paths and per-agent file references

• Replaces agents directory entries with explicit .md agent files and ensures all paths start with "./". Updates commands/skills entries to schema-compliant directory references.

plugins/security/plugin.json

plugin.jsonFix specialized manifest paths and expand agents to files +12/-9

Fix specialized manifest paths and expand agents to files

• Expands agents directories into explicit .md file paths and applies the required "./" prefix. Updates commands/skills directory paths to match validator expectations.

plugins/specialized/plugin.json

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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-domain-plugins.mjs`:
- Around line 94-102: Update the manifest.agents consumer in the inventory
backend, including its collectAgentItems flow, to detect explicit file entries
and collect them directly while continuing to enumerate directory entries for
legacy manifests. Preserve the file-level agent paths emitted by the generator
and enforce this distinction at runtime before directory traversal.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 091d6e31-e491-4238-88b0-624919842a06

📥 Commits

Reviewing files that changed from the base of the PR and between 03f8d5d and d5308f1.

📒 Files selected for processing (11)
  • plugins/backend/plugin.json
  • plugins/data-ml/plugin.json
  • plugins/devops-cloud/plugin.json
  • plugins/docs-content/plugin.json
  • plugins/frontend-mobile/plugin.json
  • plugins/languages/plugin.json
  • plugins/product-team/plugin.json
  • plugins/quality-testing/plugin.json
  • plugins/security/plugin.json
  • plugins/specialized/plugin.json
  • scripts/generate-domain-plugins.mjs

Comment thread scripts/generate-domain-plugins.mjs
@qodo-code-review

qodo-code-review Bot commented Jul 26, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 300 rules
✅ Skills: 17 invoked
  code-review-pr
  claude-api
  documentation-writing
  pptx
  docx
  performance-monitoring
  security-compliance
  cso
  plan-eng-review
  design-review
  prompt-engineering
  mcp-builder
  qa-testing
  code-patterns
  xlsx
  security-owasp
  testing-qa

Grey Divider


Action required

1. Inventory ENOTDIR on agents 🐞 Bug ≡ Correctness
Description
Domain plugin manifests now list individual agent .md files in manifest.agents, but backend
inventory treats each entry as a directory and calls readdir() on it. This will deterministically
throw ENOTDIR and break rstack-agents inventory (and any other inventory builds) for these domain
plugins.
Code

plugins/backend/plugin.json[R10-18]

  "agents": [
-    "api-scaffolding/agents",
-    "api-testing-observability/agents",
-    "backend-api-security/agents",
-    "backend-development/agents",
-    "c4-architecture/agents",
-    "database-cloud-optimization/agents",
-    "database-design/agents",
-    "database-migrations/agents",
-    "full-stack-orchestration/agents"
+    "./api-scaffolding/agents/api-scaffolding-backend-architect.md",
+    "./api-scaffolding/agents/api-scaffolding-graphql-architect.md",
+    "./api-scaffolding/agents/django-pro.md",
+    "./api-scaffolding/agents/fastapi-pro.md",
+    "./api-testing-observability/agents/api-documenter.md",
+    "./backend-api-security/agents/backend-api-security-backend-architect.md",
+    "./backend-api-security/agents/backend-security-coder.md",
+    "./backend-development/agents/backend-development-backend-architect.md",
Relevance

⭐⭐⭐ High

Deterministic runtime break (ENOTDIR) from treating agent file paths as dirs; team accepts inventory
FS hardening.

PR-#143

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The updated domain manifest now contains agent entries that are individual .md files, while
backend-inventory maps manifest.agents entries into filesystem paths and passes them to a recursive
directory walk that calls readdir(), which fails on regular files.

plugins/backend/plugin.json[10-18]
src/core/inventory/backend-inventory.js[223-234]
src/core/inventory/backend-inventory.js[82-95]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Domain plugin manifests now provide `agents` as a list of individual `./.../*.md` files, but `src/core/inventory/backend-inventory.js` assumes `manifest.agents` contains directories and passes each entry into `listFilesRecursive(...)`, which calls `readdir(...)`. When the entry is a file, this throws `ENOTDIR` and breaks inventory generation.

## Issue Context
This PR intentionally changed domain `plugin.json` manifests to satisfy Claude Code manifest validation rules (agents must be files, path must start with `./`). Repo tooling must accept both shapes (directory-based and file-based) to remain compatible.

## Fix Focus Areas
- src/core/inventory/backend-inventory.js[82-95]
- src/core/inventory/backend-inventory.js[223-255]

## Implementation notes
- Update the inventory plugin scanning to support `manifest.agents` entries that are either:
 - directories (existing behavior), OR
 - individual `.md` files (new domain-manifest behavior).
- One robust approach:
 - Replace `listFilesRecursive(dir, ...)` with logic that `stat`s the path:
   - if directory: recurse as today
   - if file: treat it as a singleton candidate (include it if it matches predicate)
- Ensure the same logic is safe for `commands` and `skills` if they ever become file-based (optional), but at minimum fix `agents` so current manifests don’t crash inventory.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. No tests for manifest fix 📘 Rule violation ▣ Testability
Description
This PR changes install-critical manifest generation logic (path prefixing and agent file expansion)
but does not add/modify any automated tests to exercise the new behavior. Without test coverage,
future refactors may reintroduce the same install validation failure undetected.
Code

scripts/generate-domain-plugins.mjs[R89-102]

+  for (const kind of ['commands', 'skills']) {
    const paths = subDirs.filter((sub) => existsSync(join(PLUGINS_DIR, domain, sub, kind)))
-      .map((sub) => `${sub}/${kind}`);
+      .map((sub) => `./${sub}/${kind}`);
    if (paths.length) entry[kind] = paths;
  }
+  const agentPaths = subDirs.flatMap((sub) => {
+    const dir = join(PLUGINS_DIR, domain, sub, 'agents');
+    if (!existsSync(dir)) return [];
+    return readdirSync(dir)
+      .filter((f) => f.endsWith('.md') && statSync(join(dir, f)).isFile())
+      .sort()
+      .map((f) => `./${sub}/agents/${f}`);
+  });
+  if (agentPaths.length) entry.agents = agentPaths;
Relevance

⭐⭐⭐ High

Repo often requests/accepts regression tests when behavior changes; likely to add tests for manifest
generation.

PR-#399
PR-#153
PR-#167

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The checklist requires behavior changes to be accompanied by automated tests in the same changeset.
The updated generator logic at scripts/generate-domain-plugins.mjs[89-102] alters how plugin
manifests are generated, but this PR diff contains no corresponding test additions/modifications
validating the new output.

Rule 1587034: Require tests in the same changeset as behavior modifications
scripts/generate-domain-plugins.mjs[89-102]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR changes `scripts/generate-domain-plugins.mjs` to generate different manifest paths and to expand `agents/` directories into individual `.md` entries, but no automated test was added/updated to assert this behavior.

## Issue Context
Compliance requires that non-trivial behavior modifications ship with tests in the same changeset to prevent regressions (e.g., paths must start with `./`, and `agents` must list `.md` files rather than directories).

## Fix Focus Areas
- scripts/generate-domain-plugins.mjs[89-102]
- tests/domain-plugin-manifest-generation.test.js[1-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +89 to +102
for (const kind of ['commands', 'skills']) {
const paths = subDirs.filter((sub) => existsSync(join(PLUGINS_DIR, domain, sub, kind)))
.map((sub) => `${sub}/${kind}`);
.map((sub) => `./${sub}/${kind}`);
if (paths.length) entry[kind] = paths;
}
const agentPaths = subDirs.flatMap((sub) => {
const dir = join(PLUGINS_DIR, domain, sub, 'agents');
if (!existsSync(dir)) return [];
return readdirSync(dir)
.filter((f) => f.endsWith('.md') && statSync(join(dir, f)).isFile())
.sort()
.map((f) => `./${sub}/agents/${f}`);
});
if (agentPaths.length) entry.agents = agentPaths;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. No tests for manifest fix 📘 Rule violation ▣ Testability

This PR changes install-critical manifest generation logic (path prefixing and agent file expansion)
but does not add/modify any automated tests to exercise the new behavior. Without test coverage,
future refactors may reintroduce the same install validation failure undetected.
Agent Prompt
## Issue description
The PR changes `scripts/generate-domain-plugins.mjs` to generate different manifest paths and to expand `agents/` directories into individual `.md` entries, but no automated test was added/updated to assert this behavior.

## Issue Context
Compliance requires that non-trivial behavior modifications ship with tests in the same changeset to prevent regressions (e.g., paths must start with `./`, and `agents` must list `.md` files rather than directories).

## Fix Focus Areas
- scripts/generate-domain-plugins.mjs[89-102]
- tests/domain-plugin-manifest-generation.test.js[1-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed — added tests/generate-domain-plugins.test.js: fixture-based unit tests pinning the ./-prefix rule and the agents-as-individual-files rule, plus a static assertion that all 10 committed domain manifests conform. Exported buildDomainManifest with an injectable pluginsDir param (same pattern as generate-marketplace.mjs's buildMarketplace(root)) so it's testable against a fixture tree instead of only the real plugins/ dir. CLI behavior unchanged.

Comment on lines 10 to +18
"agents": [
"api-scaffolding/agents",
"api-testing-observability/agents",
"backend-api-security/agents",
"backend-development/agents",
"c4-architecture/agents",
"database-cloud-optimization/agents",
"database-design/agents",
"database-migrations/agents",
"full-stack-orchestration/agents"
"./api-scaffolding/agents/api-scaffolding-backend-architect.md",
"./api-scaffolding/agents/api-scaffolding-graphql-architect.md",
"./api-scaffolding/agents/django-pro.md",
"./api-scaffolding/agents/fastapi-pro.md",
"./api-testing-observability/agents/api-documenter.md",
"./backend-api-security/agents/backend-api-security-backend-architect.md",
"./backend-api-security/agents/backend-security-coder.md",
"./backend-development/agents/backend-development-backend-architect.md",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Inventory enotdir on agents 🐞 Bug ≡ Correctness

Domain plugin manifests now list individual agent .md files in manifest.agents, but backend
inventory treats each entry as a directory and calls readdir() on it. This will deterministically
throw ENOTDIR and break rstack-agents inventory (and any other inventory builds) for these domain
plugins.
Agent Prompt
## Issue description
Domain plugin manifests now provide `agents` as a list of individual `./.../*.md` files, but `src/core/inventory/backend-inventory.js` assumes `manifest.agents` contains directories and passes each entry into `listFilesRecursive(...)`, which calls `readdir(...)`. When the entry is a file, this throws `ENOTDIR` and breaks inventory generation.

## Issue Context
This PR intentionally changed domain `plugin.json` manifests to satisfy Claude Code manifest validation rules (agents must be files, path must start with `./`). Repo tooling must accept both shapes (directory-based and file-based) to remain compatible.

## Fix Focus Areas
- src/core/inventory/backend-inventory.js[82-95]
- src/core/inventory/backend-inventory.js[223-255]

## Implementation notes
- Update the inventory plugin scanning to support `manifest.agents` entries that are either:
  - directories (existing behavior), OR
  - individual `.md` files (new domain-manifest behavior).
- One robust approach:
  - Replace `listFilesRecursive(dir, ...)` with logic that `stat`s the path:
    - if directory: recurse as today
    - if file: treat it as a singleton candidate (include it if it matches predicate)
- Ensure the same logic is safe for `commands` and `skills` if they ever become file-based (optional), but at minimum fix `agents` so current manifests don’t crash inventory.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed — already fixed in this same PR by an earlier commit (5b1aa49), pushed before this review ran: added resolveMarkdownFiles() in src/core/inventory/backend-inventory.js, which stats each manifest path and handles both directories and individual .md files instead of assuming scandir() always works. Verified via tests/backend-inventory.test.js (5/5 pass) and this PR's CI (Node 18.x/20.x/22.x test jobs, now green).

…t change

buildBackendInventory's collectAgentItems assumed every plugin.json
"agents" entry was a directory and called readdir() on it directly.
That broke once domain manifests started listing individual .md agent
files (per this PR's earlier commit), tripping ENOTDIR in CI
(backend-inventory.test.js, caught by the Node 18/20/22 test jobs).

resolveMarkdownFiles() now stats each entry and handles either shape
(directory -> recursive walk, single .md file -> itself) — matching
Claude Code's own plugin manifest schema, which documents `agents` as
accepting both directories and individual files.
…#469)

Qodo flagged that the ./-prefix + agents-as-files generator change
shipped with no test coverage. Export buildDomainManifest with an
injectable pluginsDir (same pattern as generate-marketplace.mjs's
buildMarketplace(root)) so it's testable against a fixture tree
instead of only the real plugins/ dir (whose per-sub-plugin
manifests are deleted after a real generation run). Adds:
- fixture-based unit tests for the ./-prefix and agents-as-files rules
- a static assertion that all 10 committed domain manifests conform

CLI behavior (buildDomainManifest(domain) defaulting to the real
plugins/ dir) is unchanged.
@richard-devbot

Copy link
Copy Markdown
Owner Author

Qodo Fix Summary — Round 1

Reviewed and addressed Qodo review issues:

✅ Fixed Issues

  • Inventory ENOTDIR on agents (Action required) - already fixed by an earlier commit in this same PR (5b1aa49), pushed before this review ran; resolveMarkdownFiles() now stats each manifest path and handles both directories and individual .md files.
  • No tests for manifest fix (Review recommended) - added tests/generate-domain-plugins.test.js (fixture-based unit tests + a static assertion over all 10 committed manifests); exported buildDomainManifest with an injectable pluginsDir param for testability, matching the existing buildMarketplace(root) pattern.

Qodo
Generated by Qodo PR Resolver skill

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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 `@tests/generate-domain-plugins.test.js`:
- Around line 104-117: Update the manifest validation loop in the
generate-domain-plugins test to resolve each agents, commands, and skills entry
against its domain root and verify the target exists. Require agents entries to
resolve to regular .md files, and require commands and skills entries to resolve
to directories, while retaining the existing prefix and agent-extension checks.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fe1cda62-e162-486e-975a-86f391c85b2f

📥 Commits

Reviewing files that changed from the base of the PR and between d5308f1 and f9e7b32.

📒 Files selected for processing (3)
  • scripts/generate-domain-plugins.mjs
  • src/core/inventory/backend-inventory.js
  • tests/generate-domain-plugins.test.js

Comment on lines +104 to +117
for (const domain of domains) {
const manifestPath = join(pluginsDir, domain, 'plugin.json');
const parsed = JSON.parse(readFileSync(manifestPath, 'utf8'));
for (const kind of ['agents', 'commands', 'skills']) {
if (!Array.isArray(parsed[kind])) continue;
for (const entry of parsed[kind]) {
assert.ok(entry.startsWith('./'), `${domain}: ${kind} entry "${entry}" must start with ./`);
}
}
if (Array.isArray(parsed.agents)) {
for (const entry of parsed.agents) {
assert.ok(entry.endsWith('.md'), `${domain}: agents entry "${entry}" must be an individual .md file`);
}
}

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.

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

Validate committed manifest targets, not just their strings.

A deleted target—or a directory named *.md—still passes these assertions. Resolve each entry under its domain root; require agent targets to be regular files and generated command/skill targets to be directories.

As per coding guidelines, “Add regression and mutation-oriented tests for … data-integrity behavior; tests should exercise the real path where mocks could hide integration bugs.”

🤖 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 `@tests/generate-domain-plugins.test.js` around lines 104 - 117, Update the
manifest validation loop in the generate-domain-plugins test to resolve each
agents, commands, and skills entry against its domain root and verify the target
exists. Require agents entries to resolve to regular .md files, and require
commands and skills entries to resolve to directories, while retaining the
existing prefix and agent-extension checks.

Source: Coding guidelines

@richard-devbot
richard-devbot merged commit a1ffc24 into main Jul 26, 2026
8 of 9 checks passed
@richard-devbot
richard-devbot deleted the fix-468-domain-plugin-manifest-paths branch July 26, 2026 11:28
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.

Domain plugin packs fail to install: manifest 'Invalid input' on agents/commands/skills

2 participants