fix(kyberforge): bridge apm content to Claude Code's flat plugin discovery
Claude Code's (and Copilot's) native plugin installer has zero awareness of .apm/ nesting -- it convention-scans only flat skills/, agents/, commands/, hooks.json at each plugin's root. Confirmed via strings on the installed claude binary and live installs of git@holocron/gitea@holocron/kyberforge@ holocron, all reporting Skills(0) Agents(0) Hooks(0) post ADR-0015's apm conversion. Root cause (apm_cli/core/plugin_manifest.py): apm's plugin.json compiler deliberately strips skills/agents/commands keys, assuming the host already auto-discovers those convention directories -- it has no model of .apm/ being host-visible at all. Separately, apm's own bundle exporter (apm_cli/bundle/plugin_exporter.py, behind `apm pack --format plugin`) implements the correct .apm/ -> flat mapping, but only ever targeted build/<name>-<version>/, a path nothing in marketplace.json's source: points at. scripts/sync-plugin-content.sh wraps that bundle exporter and copies its agents/, skills/, commands/, instructions/, extensions/, and merged hooks.json back into each plugin's own root as a second tracked compiled-output category -- same governance status as .claude-plugin/plugin.json: generated from .apm/, never hand-edited. tests/ subdirectories are excluded from the mirror (dev fixtures, not host-visible runtime content; several hardcode a relative repo-root walk-up sized for the .apm/-nested depth, which breaks when duplicated one level shallower). Applied for real across all 6 plugins and verified two ways: `claude plugin validate --strict` passes on every real plugin directory, and a live `claude --plugin-dir <path> -p "list skills/agents"` behavioral test confirms content is now actually discovered. Also, from the same issue #90 review round: - scripts/check-manifests.sh pointed at each plugin's root-level plugin.json (checking skills/hooks/mcpServers/agents pointer fields) -- that file was a stale near-duplicate of .claude-plugin/plugin.json nothing else read or wrote, now deleted across all 6 plugins. check-manifests.sh is rewritten to validate .claude-plugin/plugin.json instead, and drops the pointer-field checks entirely (nothing to check -- those fields are correctly absent by design). Content-presence drift is now check-plugin-content-sync's job, a new pre-push hook wired in .pre-commit-config.yaml. docs/adr/0017 records the root cause and decision in full, including two rejected alternatives (patching plugin.json's path fields directly -- apm's compiler strips them on every run; pointing marketplace.json at apm pack's build/ output -- a version-suffixed non-source directory nothing can install from without an extra build step). ADR-0015 and CONTEXT.md are updated to point at it. Refs: #90
This commit is contained in:
63
plugins/lint/skills/vale-run/SKILL.md
Normal file
63
plugins/lint/skills/vale-run/SKILL.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
name: vale-run
|
||||
description: >
|
||||
Use when running Vale (a prose/style linter) against files or directories in an
|
||||
already-configured project — one that already has a .vale.ini — and interpreting
|
||||
or reporting its results: choosing an output format for humans vs. CI, filtering
|
||||
by severity, handling Vale's exit codes in scripts, or resolving common runtime
|
||||
issues like false positives and unexpected CI failures. Use even if the user
|
||||
doesn't say "vale" explicitly, e.g. "lint the docs", "check prose style", "run
|
||||
the style linter", "why is CI failing on the docs check". Do not use when the
|
||||
project has no .vale.ini yet, or needs styles installed/configured — that's the
|
||||
vale-config skill.
|
||||
metadata:
|
||||
version: "0.1.1"
|
||||
category: lint
|
||||
source_keys:
|
||||
- context7-websites-vale-sh
|
||||
---
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Vale's exit code is driven by `error`-level alerts only. `warning` and `suggestion` alerts are reported but still exit `0`. `MinAlertLevel` and `--minAlertLevel` control display, never the exit code — no flag makes warnings fail. A rule that must gate CI or a commit hook has to be `level: error`. This is the single most common way a Vale gate silently passes everything.
|
||||
- `vale ls-config` prints the fully-resolved, currently active configuration as JSON — the fastest way to check why a rule "isn't applying" is what's actually active, not what's written in `.vale.ini`.
|
||||
- Inline suppression syntax is format-specific: Markdown uses HTML comments `<!-- vale off -->` / `<!-- vale on -->`, MDX uses `{/* vale off */}` / `{/* vale on */}`, Org mode uses `# vale off` / `# vale on`. The MDX form does nothing in a plain `.md` file — the alert still fires. Don't assume one syntax works across formats.
|
||||
- Before calling the `vale` binary directly, check whether the target repo documents its own wrapper script for Vale (look in its README, CONTRIBUTING docs, pre-commit config, or a `scripts/` directory). Some projects wrap `vale` to work around real bugs — e.g. a scope that silently stops matching multi-line YAML block-scalar frontmatter fields — and calling bare `vale` in a repo that has such a wrapper silently skips whatever the wrapper works around. If a wrapper is documented, invoke it with the same arguments instead of calling `vale` directly; otherwise fall back to the default below.
|
||||
|
||||
## Running vale
|
||||
|
||||
Default invocation (when the target repo has no documented Vale wrapper — see Gotchas):
|
||||
|
||||
```bash
|
||||
vale <path-or-glob>
|
||||
```
|
||||
|
||||
Key flags:
|
||||
|
||||
| Flag | Purpose |
|
||||
|---|---|
|
||||
| `--output=<style>` | Output format/template: `CLI` (default, human-readable), `line` (compact, one alert per line, good for grep/piping), `JSON` (for programmatic parsing), or a custom template. |
|
||||
| `--minAlertLevel=<suggestion\|warning\|error>` | Overrides `MinAlertLevel` from `.vale.ini` for this run only, without editing config. Filters what is displayed; does not affect the exit code. |
|
||||
| `--no-exit` | Suppresses the nonzero exit that `error`-level alerts would otherwise cause; a no-op when no rule is `error`-level. Use in CI stages that should surface lint output without hard-failing the build. |
|
||||
| `--ignore-syntax` | Treats input as plain text, skipping format-aware parsing — use when a file's syntax-aware parser produces noisy or wrong results. |
|
||||
|
||||
`vale sync` downloads the packages/styles declared in `.vale.ini` — that's a one-time-per-change setup step (vale-config's territory), not part of a normal lint run. If a run behaves as though no styles are active, that's a sign `vale sync` hasn't been run yet, not a `vale-run` problem.
|
||||
|
||||
Prefer `--output=JSON` whenever the caller (a script, a CI step, another agent) needs to act on individual alerts rather than just get a pass/fail signal — `CLI` and `line` are for humans reading the terminal.
|
||||
|
||||
## Fixing false positives
|
||||
|
||||
Scope the fix as narrowly as possible, in this order:
|
||||
|
||||
1. **Mentioning banned phrasing rather than using it**: wrap it in backticks or a fenced code block. Vale skips code spans and fences, so no suppression is needed at all. Try this before any suppression markup.
|
||||
2. **One-off**: inline-suppress the specific text run with the format's `vale off`/`vale on` markup.
|
||||
3. **Recurring known-exception string, one rule**: disable that specific rule for that specific match inline (e.g. `<!-- vale Style.Redundancy["ACT test","OTHER"] = NO -->` ... `= YES`), rather than the whole rule.
|
||||
4. **Known project term failing spell check**: add it to the style's `ignore` list, not an inline suppression.
|
||||
|
||||
Never disable a rule project-wide to fix one false positive — editing `.vale.ini`/`BasedOnStyles` is vale-config's job, and it silences the rule everywhere, not just the false-positive case.
|
||||
|
||||
If output looks wrong because Vale mis-parsed a file's format, rerun with `--ignore-syntax` before assuming the rule itself is broken.
|
||||
|
||||
For CI that fails solely because Vale returned non-zero on `error`-level alerts — not because the content is wrong for that pipeline stage — add `--no-exit` rather than disabling the rule. If the failing alerts are warnings or suggestions, Vale is not what failed the build; look elsewhere.
|
||||
|
||||
If setting up Vale as a pre-commit hook or need the full inline-suppression/spelling-ignore syntax reference, read `references/troubleshooting.md`.
|
||||
Reference in New Issue
Block a user