Skip to content

feat: add AI agent skills inventory scanning support#162

Open
raysubham wants to merge 5 commits into
step-security:mainfrom
raysubham:feat/ai-agent-skills-inventory
Open

feat: add AI agent skills inventory scanning support#162
raysubham wants to merge 5 commits into
step-security:mainfrom
raysubham:feat/ai-agent-skills-inventory

Conversation

@raysubham

Copy link
Copy Markdown
Contributor

Summary

Adds a detector that inventories Agent Skills installed for AI coding agents, at both global and per-project scope. It covers Claude Code skills and skills.sh-managed installs (including plugin-provided skills).

For each discovered skill the scan records:

  • Metadata: skill name, agent, scope, and source
  • A SHA-256 hash of the skill's SKILL.md (for drift detection)
  • skills.sh provenance from lock files (source, ref, install/update timestamps)
  • A stat-only census of the skill folder (file counts and sizes — contents are not read)

Lock entries with no corresponding folder on disk are surfaced as "configured but not present" records.

Privacy

  • Skill file contents are never read beyond SKILL.md, and are never transmitted.
  • Only a single SHA-256 hash of each SKILL.md is recorded — never its contents.
  • For local skill sources, the on-disk source path is never serialized; only the lock alias is recorded.

Notes

  • SKILL.md discovery is case-sensitive (exact SKILL.md).
  • The ~/.claude.json project-registry discovery is shared with the MCP detector.
  • Enabled by default.

Testing

  • go build ./..., go vet ./..., and gofmt are clean
  • go test ./... passes for the affected packages

Scan for Agent Skills installed for AI coding agents at global and
per-project scope, covering Claude Code skills and skills.sh-managed
installs (including plugin-provided skills).

For each skill the scan records metadata (name, agent, scope, source),
a SHA-256 hash of its SKILL.md for drift detection, skills.sh provenance
from lock files, and a stat-only census of the skill folder. Skill file
contents are never read beyond SKILL.md and are never transmitted; local
source paths from lock files are recorded by alias only.

The ~/.claude.json project-registry discovery is shared with the MCP
detector.
@raysubham raysubham changed the title Add AI agent skills inventory scanning feature feat: add AI agent skills inventory scanning support Jul 9, 2026
raysubham added 4 commits July 9, 2026 19:17
The home directory appears in the ~/.claude.json project registry whenever
Claude Code has been run from $HOME. Treating it as a project re-scanned the
global skill dirs (~/.claude/skills, ~/.agents/skills) and re-emitted every
global skill as a project-scoped duplicate, also double-counting roots_scanned.

Skip the home directory in project discovery — its dotfile skill dirs are the
global roots. Adds a regression test covering a registry that lists both home
and a genuine sub-project.
…s-inventory

# Conflicts:
#	internal/featuregate/featuregate.go
skills.sh installs a skill once and symlinks it into each agent's own
root, so enumeration emitted one record per root and inflated a single
physical skill into N+1 records. Collapse those shadows into one record
per physical skill dir, keyed on the symlink-resolved path: the real
directory is canonical and the linked roots are recorded in a new
symlink_sources field. Drop lock-only synthesis — a lock entry with no
folder on disk is not an installed skill — and remove the now-constant
is_symlink and present_on_disk fields.

Also add Pi, Factory, Amp, and Copilot skill roots (global and project),
including Factory's singular .agent/skills and Copilot's .github/skills.
The ~/.claude/plugins/{cache,repos} subtrees are no longer walked for
skill directories, and claude_plugin is removed from the source set.
Skills are discovered through the global, project, and skills.sh
lock-managed roots only; a plugin's skill is inventoried when it is
symlinked or installed into one of those roots.

The per-skill has_plugin_manifest census flag and the skills.sh lock's
plugin_name provenance are unchanged.

Also stop echoing the canonical record's own source into symlink_sources
when another member of its collapse group shares that source.
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