check
Check cross-artifact consistency — reference integrity, orphans, contradictions
Render a self-contained HTML report — per-file scores, score trend, cross-artifact graph, vocabulary noun-verb map, drift candidates, and findings — into .claude/nlpm-reports/. Opens directly via file://. No server, no build, no network.
> /plugin marketplace add xiaolai/nlpm > /plugin install nlpm@xiaolai
How it fires
How this command gets triggered: by you, by Claude, or both.
/reportContext preview
What this command does when you run it.
Render a self-contained HTML report — per-file scores, score trend, cross-artifact graph, vocabulary noun-verb map, drift candidates, and findings — into .claude/nlpm-reports/. Opens directly via file://. No server, no build, no network.
name: report description: "Render a self-contained HTML report — per-file scores, score trend, cross-artifact graph, vocabulary noun-verb map, drift candidates, and findings — into .claude/nlpm-reports/. Opens directly via file://. No server, no build, no network." argument-hint: "[path]" allowed-tools: Read, Write, Glob, Grep, Bash, Task
$ARGUMENTS
| Input | Behavior | |-------|----------| | (empty) | Target = current working directory | | absolute path | Target = that path | | relative path | Target = `<cwd>/<path>` |
If the target does not exist or is not a directory → "Target path not found: {path}". Stop.
Set `out_dir = <target>/.claude/nlpm-reports/`.
Read `<target>/.claude/nlpm.local.md` if it exists. Extract:
These feed the report header and gate which panels are rendered.
Read `<target>/.claude/nlpm-history.json` if it exists. Each snapshot has `timestamp` and `average_score`. Keep all snapshots for the trend panel; the most recent one is the headline.
If the file is missing or has zero snapshots → emit the report with the trend panel showing "no history" rather than aborting.
Discover artifacts via `${CLAUDE_PLUGIN_ROOT}/commands/shared/discover.md` against the target. Then dispatch the `nlpm:scorer` and `nlpm:vague-scanner` agents in parallel (same pattern as `/nlpm:score`). Collect per-file scores and findings.
If the corpus has more than 50 artifacts, batch into groups of 25 per dispatch.
Dispatch the `nlpm:checker` agent against the target. Capture:
If the config from Step 2 declares a `vocabulary_skill` path, read `<target>/<vocabulary_skill>/registry.yaml`. Extract:
Build verb→noun edges by walking each verb's `output` field — if the output references a noun by id, emit a `produces` edge. If the output is freeform text, skip the edge (don't fabricate).
If no `vocabulary_skill` is configured, look for `<target>/skills/*/vocabulary/registry.yaml` and use the first match. If none found, omit the vocabulary panel.
If a vocabulary skill is configured **and** the corpus has at least 5 NL artifacts, dispatch the `nlpm:vocab-drift-scanner` agent (registry-free; reads existing `cross_scope_homonyms` to suppress false positives). Capture the JSONL records.
If fewer than 5 artifacts, skip vocab drift; the panel will render "corpus too small for drift detection."
Build a single JSON object with this shape (omit any panel's data when absent):
{
"project": "<plugin-name-from-plugin.json-or-dir-basename>",
"generated_at": "<ISO 8601 UTC>",
"score_threshold": 70,
"r51_enabled": false,
"summary": {
"total_files": 22,
"average_score": 95,
"pass_count": 22,
"fail_count": 0
},
"files": [{"path": "...", "type": "...", "score": 95, "findings": [...]}],
"history": [{"timestamp": "...", "average_score": 92}],
"cross_component": {
"nodes": [{"id": "...", "label": "...", "type": "artifact|manifest", "broken": false}],
"edges": [{"source": "...", "target": "...", "broken": false}]
},
"vocabulary": {
"scopes": [{"id": "internal", "label": "Internal"}],
"verbs": [{"id": "score", "scope": "internal", "deprecated": ["analyze"], "judgment": false, "output": "number+penalty"}],
"nouns": [{"id": "artifact", "class": "artifact_class", "definition": "..."}],
"edges": [{"source": "score", "target": "finding", "type": "produces"}],
"cross_scope_homonyms": ["scan", "test", "discover"],
"deferred": [{"verb": "triage", "scope": "internal", "needed_warrant": "user warrant"}]
},
"vocab_drift": {
"candidates": [{"terms": ["scanner", "analyzer"], "confidence": "high", "disposition": "drift", "suggested_canonical": "scanner", "files_affected": 3, "evidence": "..."}]
},
"findings": [{"rule": "R09", "severity": "low", "file": "agents/x.md", "line": 12, "message": "..."}]
}Write this to `/tmp/nlpm-report-data.json`.
Invoke the renderer via Bash:
python3 ${CLAUDE_PLUGIN_ROOT}/bin/nlpm-report \
--data /tmp/nlpm-report-data.json \
--project <plugin-name> \
--out <target>/.claude/nlpm-reports/If `CLAUDE_PLUGIN_ROOT` is unset, fall back to `~/.claude/plugins/cache/xiaolai/nlpm/*/bin/nlpm-report` (use `Glob`).
NLPM HTML Report
Project: {name}
Score: {avg}/100 ({pass}/{total} files pass, threshold {threshold})
Trend: {N} snapshots
Vocab: {V} verbs, {N} nouns, {D} drift candidates
Findings: {F} total, {high} high-severity
Report: {target}/.claude/nlpm-reports/index.html
Archive: {target}/.claude/nlpm-reports/<timestamp>.html
Open with: open '{target}/.claude/nlpm-reports/index.html'| Condition | Response | |-----------|----------| | Target path doesn't exist | "Target path not found: {path}" | | No NL artifacts in target | "No NL artifacts found at {path}; nothing to report." | | `bin/nlpm-report` not findable | "Could not locate nlpm-report binary. Set CLAUDE_PLUGIN_ROOT or install NLPM at user scope." | | Scorer agent fails
Natural-Language Programming Manager — score, check, fix, and test NL artifacts across Claude Code, Codex CLI, and Antigravity. Tier-aware scoring with per-tool overlays. Part of the xiaolai plugin marketplace.
Check cross-artifact consistency — reference integrity, orphans, contradictions
Auto-fix fixable findings in NL artifacts — missing fields, heading gaps, field renames
Prepare NLPM for this project — detect artifacts, set strictness, capture baseline trend snapshot
Discover all natural language programming artifacts in a repository
Score NL programming artifacts — 100-point quality score per file
Scan a Claude Code plugin for security risks in executable artifacts (hooks, scripts, MCP configs, dependencies).