"Verify and configure the bugs plugin for this repository. check inspects both surfaces read-only, the rendered output_dir userConfig value, and the tracked .claude/bugs.md lane config across its cascade layers; apply writes or updates that tracked file and nothing else. Use when: 'set up bugs', 'configure bugs', 'bugs setup', 'where do bug reports land', the user wants --file reports committed alongside code, or '/bugs:scan' needs project lanes and a filing posture. Actions: check (read-only, default) | apply (creates or updates the tracked lane config; output_dir still routes through Claude Code's own configuration prompt)."
Resources
1Install
npx skillscat add melodic-software/claude-code-plugins/plugins-bugs-skills-setup Install via the SkillsCat registry.
Purpose
Confirm where /bugs:write --file writes reports, and manage the tracked project config/bugs:scan reads for its lanes and filing posture.
Two surfaces, two owners
| Surface | Holds | Written by |
|---|---|---|
output_dir. Native userConfig |
one operator's personal --file destination on one machine |
Claude Code's own plugin configuration prompt, never this skill |
.claude/bugs.md. Tracked, cascade-layered |
team policy: /bugs:scan lanes and filing posture |
apply here, team layer only |
This is the narrow-write setup shape: apply is bounded to the one writable artifact this plugin
owns, and the unwritable surface beside it stays check-only. output_dir is a personal value that
Claude Code prompts for when the plugin is enabled, stores in user settings, and ignores inpluginConfigs entries under project and local settings on current releases (≥ 2.1.207), so anapply could only write the pluginConfigs the uniform setup contract forbids, and reconfiguration
routes through the native flow instead.
Official contract: https://code.claude.com/docs/en/plugins-reference#user-configuration.
Keys, layers, merge semantics, the output_dir partition rule, and the file format live in
`${CLAUDE_PLUGIN_ROOT}/reference/config.md`, their single home. Read it
before checking or writing; never restate its keys here, and never let this skill and that reference
disagree.
Both actions are non-interactive when the invocation and the repo make the values unambiguous:
report and recommend, and ask only where a lane genuinely needs the user. No argument runs check.
check (read-only, the default)
Modify nothing. Report both surfaces, then one remediation line per gap.
A. output_dir (native userConfig)
- Read the rendered
${user_config.output_dir}value from this skill. Do not inspect or editsettings.json,settings.local.json, managed settings, orpluginConfigsdirectly. - Explain the effective behavior:
- empty or unexpanded value:
--fileuses${CLAUDE_PLUGIN_DATA}/bug-reports/<project-slug>/; - configured value:
--fileuses that directory.
- empty or unexpanded value:
- State the tradeoff instead of asking: machine-private (the default under
${CLAUDE_PLUGIN_DATA}) versus a repository path committed alongside code. For the
repository option, inspect the consumer'sCLAUDE.md,AGENTS.md, and existing report or
artifact directories and recommend one portable location. Never recommend a machine-absolute
team path. - If the recommended value differs, reconfigure through Claude Code's native flow per the marketplace's
plugin-reconfiguration convention, which owns the verified-version record: interactive/plugin configure bugs@<marketplace>any time, or headlessclaude plugin install bugs@<marketplace> -s <scope> --config output_dir=<path>— it printsalready installedand still writes the value.
Never uninstall to reconfigure: that drops the whole storedpluginConfigsentry, resetting every
option to its manifest default.-sdefaults touser; pass the scopeclaude plugin listreports,
from that project's directory for aproject/localscope, or the rerun adds a second install
record at the scope passed and enables the plugin there; the value itself always lands in user
settings. A rejected value prints a warning yet exits 0, so read the output.
Reruncheckin a fresh session (the rendered value is injected at skill load, so a
same-sessioncheckstill reports the OLD value), then report the observed destination. Convention:
https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/plugin-reconfiguration/README.md.
B. .claude/bugs.md (tracked lane config)
Anchor at the repo root. Use ${CLAUDE_PROJECT_DIR} when set, otherwise git rev-parse --show-toplevel,
never the CWD. Then report each layer separately and the effective merged result:
- Per-layer presence. Name every layer of the surface (the reference's layer table is
authoritative) and say for each: absent, present-and-parsed, or malformed. A malformed layer
degrades soft. Surface the error, name the layer, and resolve as if it were absent. - Effective config and provenance. Report the merged
lanesandfiling_postureand which
layer supplied each value, honoring the reference's merge semantics, including an explicit
empty-list opt-out, which is reported as an opt-out, not as a broken layer. All layers absent is
a valid, fully working state: INFO, never FAIL./bugs:scanfalls through to its bundled
generic default lanes. - Per-layer version-control verdict. A present team file must be tracked, which takes two
probes: not-ignored and actually-tracked. Rungit check-ignore -v .claude/bugs.md; a
non-empty result is FAIL, naming the matching pattern. Teammates would never receive it. Then rungit ls-files --error-unmatch .claude/bugs.md; a non-zero exit on a present file is also
FAIL, "present but untracked, commit it so teammates receive it". The ignore probe alone cannot
see this: an untracked, unignored file returns the same empty output as a healthy tracked one, socheckwould bless a config nobody else ever receives. The.local.mdoverlay must be
gitignored; staged or unignored is FAIL. The user-global layer sits outside the worktree, so no git
verdict applies to it. Say so rather than running a command whose answer is meaningless. - Unreachable layers. When a layer cannot be read (the user-global one often is not), WARN that
it was not considered rather than presenting the rest as the whole effective config. - Unknown keys. Report them as inert, naming their layer, including
output_dir, which is not
a recognized key here per the reference's partition rule.
apply (idempotent, bounded to .claude/bugs.md)
Run check first, then converge the team file, the only artifact this action writes. Never
touch settings.json, settings.local.json, managed settings, pluginConfigs, userConfig, the
user-global layer, the .local.md overlay, or the consumer's .gitignore. An output_dir change
requested here is routed to the native flow in check step A4, never written.
- Read the effective config first, across every layer, and present it. Where a user-global or
overlay layer changes the team file's effect, adding lanes, replacing one by name, opting out
with an empty list, or supplyingfiling_posturenearest-wins, say so explicitly: a team-scope
edit alone will not account for it, and re-adding a lane an overlay opts out of will not restore
it on this machine. Prompt the user to also update that layer; do not edit it for them. - Draft lanes from the repository. Before asking anything, infer candidates from what exists:
entrypoint and API directories, the highest-churn source areas ingit log, and any subsystem
the repo's own docs treat as critical. Propose kebab-case lane names with globs relative to the
repo root. Degrade to the bundled generic default lanes as the proposal when history or layout
gives nothing to infer from. - Confirm, one decision at a time. Present each drafted lane with a recommendation; let the
user accept, edit, or drop it. Then settlefiling_posture, stating what each value permits per
the reference, and that neither value ever lets a bare invocation file. - Write conservatively. Scaffold the file in the reference's documented format when absent; for
an existing file, make a targeted update. Fill absent keys at their documented defaults,
preserve prose and keys you do not recognize, and report rather than silently rewrite anything
you cannot reconcile. Never overwrite blind, and never rewrite a file you did not first read. - Verify after writing. Re-run the
checkB probes against the file on disk: it parses, every
lane declaresnameandglobs, the globs match real paths (a lane matching nothing is reported
as skipped), andgit check-ignore -v .claude/bugs.mdconfirms it is not ignored. A file
just scaffolded here is legitimately untracked until it is staged, sogit ls-files --error-unmatchwill not match yet. That is not a FAIL at this point; state the
commit obligation instead (step 7). Report the values you observed, never an unobserved change. - Recommend the overlay line, do not write it. Personal deviations belong in
.claude/bugs.local.md; recommend the consumer add the recursive.gitignoreline the
reference names if it is not already covered. Their ignore file is their artifact. - Remind them to stage it. The team file only reaches teammates once committed.
Re-running apply when everything already matches changes nothing and reports "already configured".
Output
Report, for each surface: the effective state and the layer that supplied it, the recommended state,
and what changed, the tracked file's path and the keys written, plus whether the user must still
change the Claude-owned output_dir through Claude Code's own flow. Do not claim a configuration
change until it is observed: for the tracked file, by re-reading it; for output_dir, by a rerun in
a fresh session.
Boundaries
- Do not produce or file a bug report; invoke
/bugs:writevia the Skill tool. - Do not run a hunt; that is
/bugs:scan. This skill only verifies and writes its config. - Do not write the plugin cache, Claude Code user settings, or
pluginConfigs, per the uniform
setup contract (docs/plugin-philosophy.md"Setup is explicit and repeatable" in the
marketplace repository). - Do not delete the tracked config:
applyconverges to the configured state and never removes. - Do not invent an organization, repository, marketplace, or environment-variable prefix.