# Ashard documentation export Generated from Crystal Docs HTML/JSON plus the parallel markdown files emitted by `shards docs`. Source manifest: /llms.json ## /Shards.md # module Shards ## Constants - `AI_DOCS_INFO_FILENAME` = `".ai-docs-info.yml"` - `ASSISTANT_CONFIG_FILENAME` = `".assistant-config.yml"` - `BUILD_DATE` = `""` - `BUILD_SHA1` = `{{ (env("SHARDS_CONFIG_BUILD_COMMIT")) || "" }}` - `BUILTIN_COMMANDS` = `["build", "run", "check", "diff", "init", "install", "list", "lock", "outdated", "prune", "update", "version", "run-script", "ai-docs", "docs", "sbom", "mcp", "audit", "licenses", "policy", "compliance-report", "mcp-server", "assistant"] of ::String` - `DEFAULT_COMMAND` = `"install"` - `DEFAULT_VERSION` = `"0"` - `FORMATTER` = `::Log::Formatter.new do |entry, io| message = entry.message package_name = entry.context[:package]? if @@colors if package_name && entry.severity <= ::Log::Severity::Debug ((io << "[") << (package_name.colorize(:blue)).to_s) << "] " end io << (if color = LOGGER_COLORS[entry.severity]? if idx = message.index(' ') (message[0...idx].colorize(color)).to_s + message[idx..-1] else message.colorize(color) end else message end) else (io << entry.severity.label[0]) << ": " if package_name && entry.severity <= ::Log::Severity::Debug ((io << "[") << package_name) << "] " end io << message end end` - `INSTALL_DIR` = `"lib"` - `LOCK_FILENAME` = `"shard.lock"` - `Log` = `::Log.for(self)` - `LOGGER_COLORS` = `{::Log::Severity::Error => :red, ::Log::Severity::Warn => :yellow, ::Log::Severity::Info => :green, ::Log::Severity::Debug => :light_gray}` - `OVERRIDE_FILENAME` = `"shard.override.yml"` - `POLICY_FILENAME` = `".shards-policy.yml"` - `POSTINSTALL_INFO_FILENAME` = `".shards.postinstall"` - `SPEC_FILENAME` = `"shard.yml"` - `VERSION` = `{{ (read_file("/home/runner/work/shards/shards/src/../VERSION")).chomp }}` - `VERSION_AT_FOSSIL_COMMIT` = `/^(\d+[-.][-.a-zA-Z\d]+)\+fossil\.commit\.([0-9a-f]+)$/` - `VERSION_AT_GIT_COMMIT` = `/^(\d+[-.][-.a-zA-Z\d]+)\+git\.commit\.([0-9a-f]+)$/` - `VERSION_AT_HG_COMMIT` = `/^(\d+[-.][-.a-zA-Z\d]+)\+hg\.commit\.([0-9a-f]+)$/` - `VERSION_REFERENCE` = `/^v?\d+[-.][-.a-zA-Z\d]+$/` - `VERSION_TAG` = `/^v(\d+[-.][-.a-zA-Z\d]+)$/` ## Class Methods ### `ai_docs_info` ### `bin_path` ### `bin_path=(bin_path : String)` ### `cache_path` ### `cache_path=(cache_path : String)` ### `check_and_install_dependencies(path)` ### `cli_options` ### `colors=(colors : Bool)` ### `colors?` ### `crystal_bin` ### `crystal_bin=(crystal_bin : String)` ### `crystal_version` ### `crystal_version=(crystal_version : String)` ### `display_help_and_exit(opts)` ### `frozen=(frozen)` ### `frozen?` ### `global_override_filename` ### `info` ### `install_path` ### `install_path=(install_path : String)` ### `jobs` ### `jobs=(jobs : Int32)` ### `local=(local)` ### `local?` ### `parse_args(args)` ### `postinstall_info` ### `run` ### `run_shards_subcommand(process_name, args)` ### `set_debug_log_level` ### `set_warning_log_level` ### `skip_ai_assistant=(skip_ai_assistant)` ### `skip_ai_assistant?` ### `skip_ai_docs=(skip_ai_docs)` ### `skip_ai_docs?` ### `skip_executables=(skip_executables)` ### `skip_executables?` ### `skip_postinstall=(skip_postinstall)` ### `skip_postinstall?` ### `skip_verify=(skip_verify)` ### `skip_verify?` ### `version_string` ### `with_development=(with_development)` ### `with_development?` ## Types - `Shards::AIDocsInfo` (class) - `Shards::AIDocsInstaller` (class) - `Shards::Any` (module) - `Shards::AssistantConfig` (module) - `Shards::AssistantConfigInfo` (class) - `Shards::AssistantVersions` (module) - `Shards::ChangeLogger` (class) - `Shards::Checksum` (module) - `Shards::ChecksumMismatch` (class) - `Shards::ClaudeConfig` (module) - `Shards::Command` (class) - `Shards::Commands` (module) - `Shards::Compliance` (module) - `Shards::ComplianceMCPServer` (class) - `Shards::Conflict` (class) - `Shards::CrystalResolver` (class) - `Shards::Dependency` (class) - `Shards::DiffReport` (class) - `Shards::Docs` (module) - `Shards::Error` (class) - `Shards::FossilBranchRef` (struct) - `Shards::FossilCommitRef` (struct) - `Shards::FossilRef` (struct) - `Shards::FossilResolver` (class) - `Shards::FossilTagRef` (struct) - `Shards::FossilTrunkRef` (struct) - `Shards::GitBranchRef` (struct) - `Shards::GitCommitRef` (struct) - `Shards::GitHeadRef` (struct) - `Shards::GitRef` (struct) - `Shards::GitResolver` (class) - `Shards::GitTagRef` (struct) - `Shards::Helpers` (module) - `Shards::HgBookmarkRef` (struct) - `Shards::HgBranchRef` (struct) - `Shards::HgCommitRef` (struct) - `Shards::HgCurrentRef` (struct) - `Shards::HgRef` (struct) - `Shards::HgResolver` (class) - `Shards::HgTagRef` (struct) - `Shards::IgnoreRule` (struct) - `Shards::Info` (class) - `Shards::InvalidLock` (class) - `Shards::LicensePolicy` (class) - `Shards::LicenseScanner` (class) - `Shards::Lock` (class) - `Shards::LockConflict` (class) - `Shards::LockfileDiffer` (class) - `Shards::MCPManager` (class) - `Shards::MolinilloSolver` (class) - `Shards::Override` (class) - `Shards::Package` (class) - `Shards::PackageScanResult` (struct) - `Shards::ParseError` (class) - `Shards::PathResolver` (class) - `Shards::Policy` (class) - `Shards::PolicyChecker` (class) - `Shards::PolicyReport` (class) - `Shards::PostinstallInfo` (class) - `Shards::PurlGenerator` (module) - `Shards::Ref` (struct) - `Shards::Requirement` (alias) - `Shards::Resolver` (class) - `Shards::Script` (module) - `Shards::Severity` (enum) - `Shards::SPDX` (module) - `Shards::Spec` (class) - `Shards::Target` (class) - `Shards::Version` (struct) - `Shards::VersionReq` (struct) - `Shards::Versions` (module) - `Shards::Vulnerability` (struct) - `Shards::VulnerabilityReport` (class) - `Shards::VulnerabilityScanner` (class) ## /Shards/AIDocsInfo.md # class Shards::AIDocsInfo Tracks installed AI documentation files and their checksums. Persisted at `.claude/.ai-docs-info.yml`, this tracker enables conflict detection during updates by storing two checksums per file: - `upstream_checksum`: the checksum of the file as shipped by the shard - `installed_checksum`: the checksum of the file as it exists on disk When both match, the file is unmodified and safe to auto-update. When they differ, the user has customized the file and it should not be overwritten. ## Constants - `CURRENT_VERSION` = `"1.0"` ## Constructors ### `new(path : String)` ## Class Methods ### `checksum(content : String) : String` Computes a SHA-256 checksum for the given string content. ### `checksum_file(path : String) : String` Computes a SHA-256 checksum for the file at the given path. ## Instance Methods ### `load` Loads tracker state from the YAML file at `#path`. ### `path` Absolute path to the `.ai-docs-info.yml` file. ### `save` Persists the current tracker state to the YAML file at `#path`. ### `shards` Map of shard name to its tracked entry. ## Types - `Shards::AIDocsInfo::FileEntry` (class) - `Shards::AIDocsInfo::ShardEntry` (class) ## /Shards/AIDocsInfo/FileEntry.md # class Shards::AIDocsInfo::FileEntry Represents a single tracked file with dual checksums. ## Constructors ### `new(upstream_checksum : String, installed_checksum : String)` ## Instance Methods ### `installed_checksum` ### `installed_checksum=(installed_checksum : String)` ### `upstream_checksum` ### `upstream_checksum=(upstream_checksum : String)` ### `user_modified?` Returns `true` if the installed file differs from the upstream version, indicating the user has made local modifications. ## /Shards/AIDocsInfo/ShardEntry.md # class Shards::AIDocsInfo::ShardEntry Tracks all AI doc files installed from a single shard. ## Constructors ### `new(version : String, files : Hash(String, Shards::AIDocsInfo::FileEntry) = Hash(String, FileEntry).new)` ## Instance Methods ### `files` ### `files=(files : Hash(String, FileEntry))` ### `version` ### `version=(version : String)` ## /Shards/AIDocsInstaller.md # class Shards::AIDocsInstaller Detects, installs, and manages AI documentation from shard dependencies. When dependencies are installed or updated, `AIDocsInstaller` scans each package for AI-relevant files (skills, agents, commands, CLAUDE.md, etc.) and copies them into the project's `.claude/` directory with shard-namespaced paths to avoid conflicts. It also handles MCP server configuration merging from `.mcp.json` files shipped by dependencies into a project-level `.mcp-shards.json`. ## Auto-detected locations The following paths are scanned in each dependency: - `.claude/skills/` -- Claude Code skill directories - `.claude/agents/` -- agent definition files - `.claude/commands/` -- slash command files - `CLAUDE.md` -- general AI context (converted to passive skill) - `AGENTS.md` -- agent specifications - `.mcp.json` -- MCP server configurations ## Namespacing Files are namespaced by shard name to prevent conflicts: - Skills: `--` - Agents: `--.md` - Commands: `:.md` - MCP servers: `/` ## Conflict detection Uses `AIDocsInfo` to track dual checksums per file. User-modified files are preserved during updates, with an `.upstream` copy saved for comparison. ## Constants - `SECURITY_SKIP_FILES` = `[".claude/settings.json", ".claude/settings.local.json"]` -- Settings files that are never distributed for security reasons. ## Constructors ### `new(project_path : String)` ## Instance Methods ### `has_ai_docs?(package : Package) : Bool` Returns `true` if the package contains any auto-detectable AI docs or has explicit `ai_docs.include` entries in its spec. ### `install(packages : Array(Package))` Installs AI documentation from the given packages into the project's `.claude/` directory. Skips packages without AI docs and respects the `--skip-ai-docs` flag. ### `install_mcp_config(package : Package, mcp_json_path : String)` Installs MCP server configuration from a shard's `.mcp.json` into the project's `.mcp-shards.json`. Server names are namespaced as `/` and relative command/args paths are rewritten to point into `lib//`. ### `project_path` Root path of the project receiving AI docs. ### `prune(removed_shard_names : Array(String))` Removes all AI documentation files for the given shard names. Cleans up skills, agents, commands, .upstream files, and MCP server entries. ## /Shards/Any.md # module Shards::Any ## Instance Methods ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/AssistantConfig.md # module Shards::AssistantConfig ## Constants - `COMPONENT_NAMES` = `["mcp", "skills", "agents", "settings"] of ::String` - `MCP_SERVER_NAME` = `"shards-compliance"` ## Class Methods ### `auto_install(path : String)` Called from install pipeline — auto-install or update as needed ### `component_for(path : String) : String` Classify a file path into its component group. Paths may have ./ prefix from the build script. ### `filter_by_components(files : Hash(String, String), components : Hash(String, Bool)) : Hash(String, String)` Filter files by enabled components ### `install(path : String, skip_components : Array(String) = [] of String, force : Bool = false)` Install assistant configuration files ### `install_mcp_config(path : String)` Install/merge MCP server entry into .mcp.json ### `legacy_install?(path : String) : Bool` Detect legacy mcp-server init installs (files exist but no tracking YAML) ### `remove(path : String)` Remove all tracked assistant config files ### `status(path : String)` Show status of installed assistant config ### `update(path : String, force : Bool = false, dry_run : Bool = false)` Update assistant configuration files ## /Shards/AssistantConfigInfo.md # class Shards::AssistantConfigInfo Tracks the installed assistant configuration state. Persisted at `.claude/.assistant-config.yml`, this tracker stores which version is installed, which components are enabled, and per-file checksums for detecting user modifications during upgrades. ## Constants - `CURRENT_VERSION` = `"1.0"` - `FILENAME` = `".assistant-config.yml"` ## Constructors ### `new(path : String)` ## Instance Methods ### `assistant` ### `assistant=(assistant : String)` ### `components` ### `components=(components : Hash(String, Bool))` ### `files` ### `files=(files : Hash(String, String))` ### `installed?` ### `installed_at` ### `installed_at=(installed_at : String)` ### `installed_version` ### `installed_version=(installed_version : String)` ### `load` ### `path` ### `save` ## /Shards/AssistantVersions.md # module Shards::AssistantVersions ## Constants - `VERSIONS` = `{{ run("./build_assistant_versions") }}` -- Embedded at compile time by walking src/assistant_versions/ ## Class Methods ### `all_versions` ### `current_files` Build current file state by overlaying all versions oldest-to-newest ### `files_changed_since(since_version : String) : Hash(String, String)` Get only files that changed since a given version ### `latest_version` ## /Shards/ChangeLogger.md # class Shards::ChangeLogger ## Constants - `AUDIT_DIR` = `".shards/audit"` - `LOG_FILE` = `"changelog.json"` ## Class Methods ### `load(project_path : String) : Array(JSON::Any)` ### `record(project_path : String, action : String, old_packages : Array(Package), new_packages : Array(Package), lockfile_path : String) : Nil` ## /Shards/Checksum.md # module Shards::Checksum ## Constants - `ALGORITHM_PREFIX` = `"sha256"` - `EXCLUDED_DIRS` = `{".git", ".hg", ".fossil", ".fslckout", "_FOSSIL_"}` ## Class Methods ### `compute(path : String) : String` Compute a deterministic SHA-256 checksum for a directory of source files. Returns a string like "sha256:abcdef1234..." ### `verify(path : String, expected : String) : Bool` Verify a checksum against a directory. Returns true if match, false if mismatch. ## /Shards/ChecksumMismatch.md # class Shards::ChecksumMismatch ## Constructors ### `new(package_name : String, expected : String, actual : String)` ## /Shards/ClaudeConfig.md # module Shards::ClaudeConfig ## Constants - `AGENT_COMPLIANCE_CHECKER` = `"---\nname: compliance-checker\ndescription: Specialized agent for running comprehensive compliance analysis on Crystal projects. Delegates to this agent when the user asks for a full compliance audit, security review, or pre-release check.\ntools: Bash, Read, Grep, Write\nmodel: sonnet\nmaxTurns: 15\n---\n\n# Compliance Checker Agent\n\nYou are a supply-chain compliance specialist for Crystal projects using shards-alpha. Your job is to run a comprehensive compliance analysis and produce a clear, actionable report.\n\n## Procedure\n\n### Step 1: Verify Project Setup\n\nCheck that `shard.yml` and `shard.lock` exist. If `shard.lock` is missing, run `shards-alpha install`.\n\n### Step 2: Run Vulnerability Audit\n\n```sh\nshards-alpha audit --format=json\n```\n\nRecord total vulnerabilities and breakdown by severity.\n\n### Step 3: Run License Scan\n\n```sh\nshards-alpha licenses --format=json --detect\n```\n\nRecord dependencies with valid SPDX licenses, missing licenses, and copyleft concerns.\n\n### Step 4: Run Policy Check\n\nIf `.shards-policy.yml` exists:\n\n```sh\nshards-alpha policy check --format=json\n```\n\nRecord errors and warnings. If no policy file exists, note the gap.\n\n### Step 5: Generate Compliance Report\n\nCompile findings into:\n\n**Executive Summary**\n- Overall status: PASS, ACTION_REQUIRED, or FAIL\n- Total dependency count\n\n**Vulnerability Findings**\n- List each vulnerability grouped by severity (critical first)\n\n**License Compliance**\n- List all dependencies with their licenses\n- Flag missing or problematic licenses\n\n**Policy Compliance**\n- List violations with remediation steps\n\n**Remediation Steps**\n- Specific version bumps for vulnerable dependencies\n- License additions for unlicensed dependencies\n- Policy file changes for violations\n\n### Step 6: Offer Additional Actions\n\n- Generate formal report: `shards-alpha compliance-report --format=html`\n- Generate SBOM: `shards-alpha sbom`\n- Create policy: `shards-alpha policy init`\n- View changes: `shards-alpha diff`\n\n## Important Notes\n\n- Run all commands from the project root.\n- Present findings in order of severity (most critical first).\n- Be specific in remediation advice."` - `AGENT_SECURITY_REVIEWER` = `"---\nname: security-reviewer\ndescription: Security-focused agent that analyzes dependencies for vulnerabilities and recommends patches. Delegates to this when the user asks about security posture or vulnerability remediation.\ntools: Bash, Read, Grep\nmodel: sonnet\nmaxTurns: 10\n---\n\n# Security Reviewer Agent\n\nYou are a dependency security analyst for Crystal projects using shards-alpha. Your focus is identifying vulnerabilities, prioritizing them by risk, and recommending specific remediation actions.\n\n## Procedure\n\n### Step 1: Run Vulnerability Audit\n\n```sh\nshards-alpha audit --format=json\n```\n\nIf exit code 0, report clean. If exit code 1, continue analysis.\n\n### Step 2: Categorize Results\n\nFor each vulnerability, extract: advisory ID, affected dependency, severity, summary, affected version range, fixed version. Group by severity (critical first).\n\n### Step 3: Prioritize by Risk\n\n1. **Critical** — Remote code execution, data exfiltration. Immediate action.\n2. **High** — Privilege escalation, auth bypass. Fix within days.\n3. **Medium** — Limited impact. Fix within a sprint.\n4. **Low** — Informational. Track and fix at convenience.\n\n### Step 4: Research Remediation\n\nCheck `shard.yml` for current version constraints. For each vulnerability determine the minimum fixing version.\n\n### Step 5: Recommend Fixes\n\n**Version Bump**: State the exact version constraint change needed.\n\n**Ignore with Justification**: If not applicable, recommend adding to `.shards-audit-ignore` with reason and 90-day expiry.\n\n**Dependency Replacement**: If unmaintained, recommend alternatives.\n\n### Step 6: Security Summary\n\n**Security Posture: [CLEAN | AT RISK | CRITICAL]**\n\nPresent: findings table, recommended shard.yml changes, ignore recommendations.\n\n## Important Notes\n\n- Never recommend ignoring critical/high vulnerabilities without strong justification.\n- Check if fixes introduce breaking changes before recommending major version bumps.\n- Present findings factually. Do not downplay security risks."` - `CLAUDE_MD` = `"# Shards-Alpha: Supply Chain Compliance for Crystal\n\nThis project uses shards-alpha, a Crystal package manager with built-in supply chain compliance tools.\n\n## Available Commands\n\n| Command | Description |\n|---------|-------------|\n| `shards-alpha install` | Install dependencies from shard.yml |\n| `shards-alpha update` | Update dependencies to latest compatible versions |\n| `shards-alpha audit` | Scan dependencies for known vulnerabilities (OSV database) |\n| `shards-alpha licenses` | List dependency licenses with SPDX compliance checking |\n| `shards-alpha policy check` | Check dependencies against policy rules |\n| `shards-alpha diff` | Show dependency changes between lockfile states |\n| `shards-alpha compliance-report` | Generate unified compliance report |\n| `shards-alpha sbom` | Generate Software Bill of Materials (SPDX/CycloneDX) |\n\n## Quick Compliance Check\n\n```sh\nshards-alpha audit # Check for vulnerabilities\nshards-alpha licenses --check # Verify license compliance\nshards-alpha policy check # Enforce dependency policies\n```\n\n## Key Files\n\n| File | Purpose |\n|------|---------|\n| `shard.yml` | Dependency specification |\n| `shard.lock` | Locked dependency versions |\n| `.shards-policy.yml` | Dependency policy rules (optional) |\n| `.shards-audit-ignore` | Suppressed vulnerability IDs (optional) |\n\n## MCP Compliance Server\n\nAn MCP server exposes all compliance tools for AI agent integration:\n\n```sh\nshards-alpha mcp-server # Start stdio MCP server\nshards-alpha mcp-server --interactive # Manual testing mode\n```\n\nSupports MCP protocol versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05."` - `FILES` = `{".claude/CLAUDE.md" => CLAUDE_MD, ".claude/settings.json" => SETTINGS_JSON, ".claude/skills/audit/SKILL.md" => SKILL_AUDIT, ".claude/skills/licenses/SKILL.md" => SKILL_LICENSES, ".claude/skills/policy-check/SKILL.md" => SKILL_POLICY_CHECK, ".claude/skills/diff-deps/SKILL.md" => SKILL_DIFF_DEPS, ".claude/skills/compliance-report/SKILL.md" => SKILL_COMPLIANCE_REPORT, ".claude/skills/sbom/SKILL.md" => SKILL_SBOM, ".claude/skills/shards-cli/SKILL.md" => SKILL_SHARDS_CLI, ".claude/skills/shards-cli/reference/commands.md" => REF_COMMANDS, ".claude/skills/shards-cli/reference/shard-yml-format.md" => REF_SHARD_YML, ".claude/skills/shards-cli/reference/ai-docs-guide.md" => REF_AI_DOCS, ".claude/agents/compliance-checker.md" => AGENT_COMPLIANCE_CHECKER, ".claude/agents/security-reviewer.md" => AGENT_SECURITY_REVIEWER}` - `REF_AI_DOCS` = `"# AI Documentation Distribution Guide\n\n## Overview\n\nShards can distribute AI coding agent documentation alongside library code. When you run `shards install`, AI docs from dependencies are automatically installed into your project's `.claude/` directory.\n\n## How It Works\n\nShards automatically detects these locations in dependencies:\n\n| Source in shard | What it is |\n|-----------------|------------|\n| `.claude/skills//` | Claude Code skills |\n| `.claude/agents/.md` | Agent definitions |\n| `CLAUDE.md` | General AI context |\n| `.mcp.json` | MCP server configs |\n\nFiles are namespaced by shard name to avoid conflicts:\n\n| Source | Destination |\n|--------|-------------|\n| `.claude/skills//` | `.claude/skills/--/` |\n| `.claude/agents/.md` | `.claude/agents/--.md` |\n| `CLAUDE.md` | `.claude/skills/--docs/SKILL.md` |\n| `.mcp.json` | Merged into `.mcp-shards.json` |\n\n## Publishing AI Docs\n\nCreate `.claude/skills/` in your shard with `SKILL.md` files containing YAML frontmatter:\n\n```markdown\n---\nname: getting-started\ndescription: How to get started with your_shard\nuser-invocable: false\n---\n# Getting Started\n...\n```\n\nOr simply add a `CLAUDE.md` at your shard root for basic documentation.\n\n## User Customization\n\n- **Unmodified files**: Auto-updated on `shards update`\n- **Modified files**: Preserved on update\n- **View changes**: `shards ai-docs diff `\n- **Reset to upstream**: `shards ai-docs reset `"` - `REF_COMMANDS` = `"# Shards CLI Commands Reference\n\n## shards install\n\nInstall dependencies from `shard.yml`. Creates `shard.lock` if it doesn't exist.\n\n```\nshards install [options]\n```\n\n## shards update\n\nUpdate dependencies to latest compatible versions.\n\n```\nshards update [shard_names...] [options]\n```\n\n## shards build\n\nBuild targets defined in `shard.yml`.\n\n```\nshards build [targets...] [-- build_options...]\n```\n\n## shards check\n\nVerify all dependencies are installed and match `shard.lock`.\n\n## shards list\n\nList installed dependencies.\n\n```\nshards list [--tree]\n```\n\n## shards lock\n\nLock dependencies without installing.\n\n```\nshards lock [--print] [--update [shards...]]\n```\n\n## shards outdated\n\nShow outdated dependencies.\n\n```\nshards outdated [--pre]\n```\n\n## shards prune\n\nRemove unused dependencies from `lib/`.\n\n## shards init\n\nGenerate a new `shard.yml`.\n\n## shards version\n\nPrint the shard version from `shard.yml`.\n\n```\nshards version [path]\n```\n\n## shards audit\n\nScan dependencies for known vulnerabilities via OSV database.\n\n```\nshards audit [--severity=LEVEL] [--format=FORMAT] [--fail-above=LEVEL] [--offline]\n```\n\n## shards licenses\n\nList dependency licenses with SPDX validation.\n\n```\nshards licenses [--check] [--detect] [--format=FORMAT] [--include-dev]\n```\n\n## shards policy\n\nManage dependency policies.\n\n```\nshards policy check [--strict] [--format=FORMAT]\nshards policy init\nshards policy show\n```\n\n## shards diff\n\nShow dependency changes between lockfile states.\n\n```\nshards diff [--from=REF] [--to=REF] [--format=FORMAT]\n```\n\n## shards compliance-report\n\nGenerate unified compliance report.\n\n```\nshards compliance-report [--format=FORMAT] [--sections=LIST] [--reviewer=EMAIL]\n```\n\n## shards sbom\n\nGenerate Software Bill of Materials.\n\n```\nshards sbom [--format=spdx|cyclonedx] [--output=FILE] [--include-dev]\n```\n\n## shards mcp-server\n\nStart MCP compliance server for AI agent integration.\n\n```\nshards mcp-server # Start stdio server\nshards mcp-server --interactive # Interactive testing mode\nshards mcp-server init # Configure .mcp.json and .claude/\nshards mcp-server --help # Show help\n```"` - `REF_SHARD_YML` = `"# shard.yml Format Reference\n\n## Required Fields\n\n```yaml\nname: my_shard # Shard name\nversion: 1.0.0 # Semantic version\n```\n\n## Optional Fields\n\n```yaml\ndescription: My shard description\nauthors:\n - Author Name \ncrystal: \">= 1.0.0, < 2.0.0\"\nlicense: MIT\nrepository: https://github.com/user/repo\n```\n\n## Dependencies\n\n```yaml\ndependencies:\n kemal:\n github: kemalcr/kemal\n version: ~> 1.0\n\n my_lib:\n git: https://example.com/repo.git\n branch: main\n\n local_dep:\n path: ../local_dep\n\ndevelopment_dependencies:\n ameba:\n github: crystal-ameba/ameba\n```\n\n### Dependency Sources\n\n| Key | Description |\n|-----|-------------|\n| `github: user/repo` | GitHub repository |\n| `gitlab: user/repo` | GitLab repository |\n| `bitbucket: user/repo` | Bitbucket repository |\n| `git: ` | Any git repository URL |\n| `path: ` | Local path dependency |\n\n### Version Constraints\n\n| Pattern | Meaning |\n|---------|---------|\n| `~> 1.0` | >= 1.0.0, < 2.0.0 |\n| `~> 1.0.3` | >= 1.0.3, < 1.1.0 |\n| `>= 1.0, < 2.0` | Range |\n| `1.0.0` | Exact version |\n\n## Build Targets\n\n```yaml\ntargets:\n my_app:\n main: src/my_app.cr\n```\n\n## Scripts\n\n```yaml\nscripts:\n postinstall: make ext\n```"` - `SETTINGS_JSON` = `"{\n \"permissions\": {\n \"allow\": [\n \"Bash(shards-alpha audit *)\",\n \"Bash(shards-alpha licenses *)\",\n \"Bash(shards-alpha policy *)\",\n \"Bash(shards-alpha diff *)\",\n \"Bash(shards-alpha compliance-report *)\",\n \"Bash(shards-alpha sbom *)\",\n \"Bash(shards-alpha mcp-server *)\",\n \"Bash(crystal build *)\",\n \"Bash(crystal spec *)\",\n \"Bash(crystal tool format *)\"\n ]\n }\n}"` - `SKILL_AUDIT` = `"---\nname: audit\ndescription: Scan project dependencies for known security vulnerabilities using the OSV database. Use when reviewing dependencies for security issues.\nallowed-tools: Bash, Read, Grep\nuser-invocable: true\nargument-hint: [--severity=high] [--offline]\n---\n\n# Audit Dependencies for Vulnerabilities\n\nRun a vulnerability scan against all locked dependencies using the OSV database.\n\n## Steps\n\n1. Verify that `shard.lock` exists in the project root. If it does not, inform the user they need to run `shards-alpha install` first.\n\n2. Run the audit command with the user's requested options:\n ```sh\n shards-alpha audit [OPTIONS]\n ```\n\n Common options to pass through from user arguments:\n - `--severity=LEVEL` — Filter results to only show vulnerabilities at or above this severity (low, medium, high, critical)\n - `--format=FORMAT` — Output format: `terminal` (default), `json`, `sarif`\n - `--fail-above=LEVEL` — Only exit non-zero for vulnerabilities at or above this severity\n - `--ignore=ID[,ID]` — Comma-separated advisory IDs to suppress\n - `--ignore-file=PATH` — Path to ignore file (default: `.shards-audit-ignore`)\n - `--offline` — Use cached vulnerability data only, no network requests\n - `--update-db` — Force a cache refresh before scanning\n\n3. Interpret the exit code:\n - Exit 0: No vulnerabilities found (or all filtered/ignored). Report this as a clean scan.\n - Exit 1: Vulnerabilities found matching the severity threshold.\n\n4. If vulnerabilities are found, summarize the results:\n - Group findings by severity (critical, high, medium, low)\n - For each vulnerability, report: advisory ID, affected dependency, affected versions, severity, and summary\n - Highlight any critical or high severity issues first\n\n5. Provide remediation advice:\n - Check if newer versions of affected dependencies are available that fix the vulnerability\n - Suggest specific version bumps in `shard.yml` where applicable\n - If a vulnerability cannot be fixed by upgrading, suggest adding it to `.shards-audit-ignore` with a reason and expiry date\n - Mention the `--fail-above` flag for CI pipelines that should only block on critical issues\n\n6. For JSON output (`--format=json`), parse the structured data to provide a more detailed breakdown. For SARIF output (`--format=sarif`), note that this is designed for GitHub Code Scanning integration.\n\n## Example Invocations\n\n```sh\n# Basic scan\nshards-alpha audit\n\n# Only show high and critical vulnerabilities\nshards-alpha audit --severity=high\n\n# CI-friendly: fail only on critical, output SARIF for GitHub\nshards-alpha audit --format=sarif --fail-above=critical\n\n# Offline scan with cached data\nshards-alpha audit --offline\n```"` - `SKILL_COMPLIANCE_REPORT` = `"---\nname: compliance-report\ndescription: Generate comprehensive supply-chain compliance reports. Use before releases or for audit documentation.\nallowed-tools: Bash, Read, Grep, Write\nuser-invocable: true\nargument-hint: [--sections=sbom,audit,licenses] [--reviewer=email]\n---\n\n# Generate Supply-Chain Compliance Report\n\nProduce a unified compliance report combining SBOM, vulnerability audit, license compliance, policy evaluation, integrity verification, and change history into a single document suitable for SOC2 and ISO 27001 auditors.\n\n## Steps\n\n1. Verify prerequisites:\n - `shard.yml` must exist in the project root\n - `shard.lock` must exist (run `shards-alpha install` if missing)\n - For policy sections, `.shards-policy.yml` should exist (optional but recommended)\n\n2. Run the compliance report command with the user's requested options:\n ```sh\n shards-alpha compliance-report [OPTIONS]\n ```\n\n Available options:\n - `--format=FORMAT` — Output format: `json` (default), `html`, `markdown`\n - `--output=PATH` — Output file path (default: `{project}-compliance-report.{ext}`)\n - `--sections=LIST` — Comma-separated sections to include (default: `all`)\n - `--reviewer=EMAIL` — Add reviewer attestation with timestamp to the report\n - `--since=DATE` — Filter change history to entries after this date\n - `--sign` — Create a detached GPG signature (`.sig` file)\n\n3. Available sections:\n\n | Section | Description |\n |---------|-------------|\n | `sbom` | SPDX 2.3 dependency inventory |\n | `audit` | OSV vulnerability scan results |\n | `licenses` | License inventory and compliance |\n | `policy` | Policy rule evaluation results |\n | `integrity` | SHA-256 checksum verification |\n | `changelog` | Dependency change history |\n\n4. Interpret the overall status:\n - **PASS** — No vulnerabilities, no policy violations, integrity verified\n - **ACTION_REQUIRED** — Medium-severity findings or warnings present\n - **FAIL** — Critical or high vulnerabilities, or policy/license failures\n\n5. Summarize the report for the user:\n - Overall compliance status\n - Total dependency count (direct and transitive)\n - Vulnerability summary by severity\n - License compliance status\n - Policy evaluation results\n\n## Example Invocations\n\n```sh\n# Full compliance report in HTML for auditors\nshards-alpha compliance-report --format=html --reviewer=security@company.com\n\n# Quick check with just SBOM and integrity sections\nshards-alpha compliance-report --sections=sbom,integrity\n\n# JSON report for CI artifact archival\nshards-alpha compliance-report --output=compliance-report.json\n\n# Markdown report for documentation\nshards-alpha compliance-report --format=markdown\n```"` - `SKILL_DIFF_DEPS` = `"---\nname: diff-deps\ndescription: Show dependency changes between lockfile states. Use when reviewing what changed after updates.\nallowed-tools: Bash, Read, Grep\nuser-invocable: true\nargument-hint: [--from=HEAD --to=current]\n---\n\n# Show Dependency Changes Between Lockfile States\n\nCompare two states of shard.lock to see what dependencies were added, removed, or updated.\n\n## Steps\n\n1. Verify that `shard.lock` exists in the project root. If it does not, inform the user there is nothing to diff.\n\n2. Run the diff command with the user's requested options:\n ```sh\n shards-alpha diff [OPTIONS]\n ```\n\n Available options:\n - `--from=REF` — Starting state (default: `HEAD`). Can be a git ref, file path ending in `.lock`, or `current`\n - `--to=REF` — Ending state (default: `current`). Same ref types as `--from`\n - `--format=FORMAT` — Output format: `terminal` (default), `json`, `markdown`\n\n3. Interpret the reference types:\n - `current` — Reads the current `shard.lock` from disk\n - A git ref (`HEAD`, `main`, `v1.0.0`, a commit SHA) — Extracts `shard.lock` from that point in git history via `git show`\n - A file path ending in `.lock` — Reads from an arbitrary lockfile on disk\n\n4. Summarize the changes:\n - **Added dependencies**: New dependencies not present in the \"from\" state. Report name, version, and source.\n - **Removed dependencies**: Dependencies present in \"from\" but absent in \"to\". Report name and previous version.\n - **Updated dependencies**: Dependencies present in both states but with different versions. Report name, old version, new version, and whether it was an upgrade or downgrade.\n - **Unchanged count**: How many dependencies remained the same.\n\n5. Provide context for the changes:\n - For major version bumps, warn about potential breaking changes\n - For added dependencies, note if they are transitive (pulled in by another dependency)\n - For removed dependencies, note if the removal might affect other parts of the project\n\n6. For markdown output (`--format=markdown`), mention this format is useful for including in PR descriptions to document dependency changes.\n\n## Example Invocations\n\n```sh\n# What changed since the last commit?\nshards-alpha diff\n\n# What changed since a release tag?\nshards-alpha diff --from=v1.0.0\n\n# Compare two specific lockfiles\nshards-alpha diff --from=before.lock --to=after.lock\n\n# Generate markdown for a PR description\nshards-alpha diff --from=main --format=markdown\n\n# JSON output for tooling\nshards-alpha diff --format=json\n```"` - `SKILL_LICENSES` = `"---\nname: licenses\ndescription: List and check dependency licenses for SPDX compliance. Use when auditing license compatibility or checking policy.\nallowed-tools: Bash, Read, Grep\nuser-invocable: true\nargument-hint: [--check] [--detect]\n---\n\n# List and Check Dependency Licenses\n\nAudit all locked dependency licenses for SPDX compliance and policy conformance.\n\n## Steps\n\n1. Verify that `shard.lock` exists in the project root. If it does not, inform the user they need to run `shards-alpha install` first.\n\n2. Run the licenses command with the user's requested options:\n ```sh\n shards-alpha licenses [OPTIONS]\n ```\n\n Available options to pass through:\n - `--format=FORMAT` — Output format: `terminal` (default), `json`, `csv`, `markdown`\n - `--check` — Exit 1 if any license policy violations are found\n - `--detect` — Use heuristic detection to identify licenses from LICENSE/COPYING files when shard.yml does not declare one\n - `--include-dev` — Include development dependencies in the scan\n - `--policy=PATH` — Path to a license policy YAML file\n\n3. Interpret the output:\n - Each dependency is listed with its name, version, declared license, and SPDX validity status\n - SPDX validation checks against 52 common SPDX identifiers and supports compound expressions (AND, OR, WITH operators)\n\n4. Summarize the findings:\n - Total number of dependencies scanned\n - Count of dependencies with valid SPDX licenses\n - Count of dependencies with missing or invalid licenses\n - Any policy violations if `--check` was used\n\n5. Flag potential issues:\n - Dependencies with no declared license (legal risk for commercial projects)\n - Dependencies with non-standard or unrecognized license identifiers\n - Copyleft licenses (GPL, AGPL) that may be incompatible with proprietary projects\n - If `--detect` was used, note which licenses were detected heuristically vs declared\n\n6. Provide recommendations:\n - For missing licenses, suggest the user contact the dependency maintainer or check the repository directly\n - For policy violations, explain which rule was violated and how to resolve it\n - For CSV or markdown output, note these formats are useful for legal review or PR descriptions\n\n## Example Invocations\n\n```sh\n# Basic license listing\nshards-alpha licenses\n\n# Check against policy, fail on violations\nshards-alpha licenses --check\n\n# Detect licenses from LICENSE files when not declared\nshards-alpha licenses --detect\n\n# Generate CSV for legal team review\nshards-alpha licenses --format=csv\n\n# Full scan including dev dependencies with detection\nshards-alpha licenses --detect --include-dev --format=json\n```"` - `SKILL_POLICY_CHECK` = `"---\nname: policy-check\ndescription: Check dependencies against policy rules in .shards-policy.yml. Use when verifying compliance before releases.\nallowed-tools: Bash, Read, Grep, Write\nuser-invocable: true\nargument-hint: [--strict]\n---\n\n# Check Dependencies Against Policy Rules\n\nEvaluate all locked dependencies against the rules defined in `.shards-policy.yml`.\n\n## Steps\n\n1. Check if `.shards-policy.yml` exists in the project root:\n - If it exists, read it to understand the active policy rules before running the check.\n - If it does not exist, ask the user if they want to create one with `shards-alpha policy init`, which generates a starter policy file.\n\n2. Run the policy check with the user's requested options:\n ```sh\n shards-alpha policy check [OPTIONS]\n ```\n\n Available options:\n - `--strict` — Treat warnings as errors (useful for CI gates)\n - `--format=FORMAT` — Output format: `terminal` (default), `json`\n\n Other policy subcommands:\n - `shards-alpha policy init` — Create a starter `.shards-policy.yml`\n - `shards-alpha policy show` — Display a summary of the current policy\n\n3. Interpret the results:\n - **Error violations** block installation: blocked dependencies, denied sources, minimum version failures\n - **Warning violations** are displayed but do not block: missing licenses, postinstall script auditing\n\n4. Summarize the findings:\n - Total rules evaluated\n - Number of errors (blocking violations)\n - Number of warnings (non-blocking violations)\n - List each violation with the dependency name, rule that was violated, and the reason\n\n5. For each violation, suggest a fix:\n - **Blocked dependency**: Remove it from shard.yml or update the policy to allow it with a documented reason\n - **Disallowed source host**: Move the dependency to an allowed host or add the host to `rules.sources.allowed_hosts`\n - **Disallowed organization**: Add the org to `rules.sources.allowed_orgs` for that host\n - **Minimum version failure**: Update the dependency version in shard.yml to meet the minimum\n - **Missing license**: Add a license to the dependency's shard.yml or set `rules.security.require_license: false`\n - **Postinstall script warning**: Review the script for safety, then either allow it or set `rules.security.block_postinstall: true` to block\n\n6. If the user wants to modify the policy, offer to edit `.shards-policy.yml` directly with the needed changes.\n\n## Policy File Structure\n\nThe policy file `.shards-policy.yml` supports these rule categories:\n- `rules.sources` — Allowed hosts, allowed organizations, deny path dependencies\n- `rules.dependencies` — Blocked dependencies with reasons, minimum version requirements\n- `rules.security` — Require licenses, block/audit postinstall scripts\n- `rules.custom` — Regex patterns to allow or block dependency names\n\n## Example Invocations\n\n```sh\n# Basic policy check\nshards-alpha policy check\n\n# Strict mode for CI (warnings become errors)\nshards-alpha policy check --strict\n\n# JSON output for tooling\nshards-alpha policy check --format=json\n\n# Create a starter policy\nshards-alpha policy init\n\n# View current policy summary\nshards-alpha policy show\n```"` - `SKILL_SBOM` = `"---\nname: sbom\ndescription: Generate a Software Bill of Materials (SBOM) in SPDX or CycloneDX format. Use for supply-chain transparency.\nallowed-tools: Bash, Read\nuser-invocable: true\nargument-hint: [--format=spdx|cyclonedx]\n---\n\n# Generate Software Bill of Materials (SBOM)\n\nProduce a complete inventory of all project dependencies in an industry-standard SBOM format.\n\n## Steps\n\n1. Verify that `shard.lock` exists in the project root. If it does not, inform the user they need to run `shards-alpha install` first.\n\n2. Run the SBOM generation command:\n ```sh\n shards-alpha sbom [OPTIONS]\n ```\n\n Available options:\n - `--format=FORMAT` — SBOM format: `spdx` (default) or `cyclonedx`\n - `--output=FILE` — Output file path\n - `--include-dev` — Include development dependencies in the SBOM\n\n3. Supported formats:\n\n **SPDX 2.3 (default)**: Linux Foundation standard, required by US EO 14028.\n **CycloneDX 1.6**: OWASP standard focused on security and risk analysis.\n\n4. Summarize the generated SBOM:\n - Total number of components listed\n - Document creation timestamp\n - Output file location\n - Whether dev dependencies were included or excluded\n\n## Example Invocations\n\n```sh\n# Generate SPDX SBOM (default)\nshards-alpha sbom\n\n# Generate CycloneDX SBOM\nshards-alpha sbom --format=cyclonedx\n\n# Custom output path\nshards-alpha sbom --output=artifacts/sbom.spdx.json\n\n# Include development dependencies\nshards-alpha sbom --include-dev\n```"` - `SKILL_SHARDS_CLI` = `"---\nname: shards-cli\ndescription: Crystal Shards package manager CLI reference. Provides guidance on shard.yml format, dependency management, installation, building, and AI docs distribution.\nuser-invocable: false\n---\n\n# Crystal Shards CLI\n\nShards is the dependency manager for Crystal. It reads `shard.yml` to resolve, install, and update dependencies from source repositories.\n\n## Common Workflows\n\n### Install dependencies\n```\nshards install # Install from shard.yml, using shard.lock if present\nshards install --production # Frozen + without development dependencies\nshards install --skip-ai-docs # Skip AI documentation installation\n```\n\n### Update dependencies\n```\nshards update # Update all to latest compatible versions\nshards update kemal # Update only kemal\n```\n\n### Build targets\n```\nshards build # Build all targets\nshards build my_app # Build specific target\nshards build --release # Build with --release flag\n```\n\n### Supply chain compliance\n```\nshards audit # Vulnerability scan\nshards licenses # License compliance\nshards policy check # Policy enforcement\nshards diff # Dependency changes\nshards compliance-report # Full compliance report\nshards sbom # Software Bill of Materials\n```\n\n### Other commands\n```\nshards check # Verify all dependencies are installed\nshards list # List installed dependencies\nshards list --tree # List with dependency tree\nshards outdated # Show outdated dependencies\nshards prune # Remove unused dependencies from lib/\nshards version # Print shard version\nshards init # Generate a new shard.yml\n```\n\n## Key Flags\n\n| Flag | Description |\n|------|-------------|\n| `--frozen` | Strictly install locked versions from shard.lock |\n| `--without-development` | Skip development dependencies |\n| `--production` | Same as `--frozen --without-development` |\n| `--skip-postinstall` | Skip postinstall scripts |\n| `--skip-ai-docs` | Skip AI documentation installation |\n| `--jobs=N` | Parallel downloads (default: 8) |\n\n## Reference\n\n- [shard.yml format](reference/shard-yml-format.md)\n- [All CLI commands](reference/commands.md)\n- [AI docs distribution guide](reference/ai-docs-guide.md)"` ## Class Methods ### `install(path : String) : Array(String)` ## /Shards/Command.md # class Shards::Command ## Constructors ### `new(path)` ## Class Methods ### `run(path, *args, **kwargs)` ## Instance Methods ### `check_crystal_version(packages)` ### `check_symlink_privilege` ### `handle_resolver_errors` ### `lockfile?` ### `lockfile_path` ### `locks` ### `override` ### `override_path` ### `path` ### `spec` ### `spec_filename` ### `spec_path` ### `touch_install_path` ### `write_lockfile(packages)` ## /Shards/Commands.md # module Shards::Commands ## Types - `Shards::Commands::AIDocs` (class) - `Shards::Commands::Assistant` (class) - `Shards::Commands::Audit` (class) - `Shards::Commands::Build` (class) - `Shards::Commands::Check` (class) - `Shards::Commands::ComplianceReport` (class) - `Shards::Commands::Diff` (class) - `Shards::Commands::Docs` (class) - `Shards::Commands::Init` (class) - `Shards::Commands::Install` (class) - `Shards::Commands::Licenses` (class) - `Shards::Commands::List` (class) - `Shards::Commands::Lock` (class) - `Shards::Commands::MCP` (class) - `Shards::Commands::Outdated` (class) - `Shards::Commands::Policy` (class) - `Shards::Commands::Prune` (class) - `Shards::Commands::Run` (class) - `Shards::Commands::RunScript` (class) - `Shards::Commands::SBOM` (class) - `Shards::Commands::Update` (class) - `Shards::Commands::Version` (class) ## /Shards/Commands/AIDocs.md # class Shards::Commands::AIDocs Manages AI documentation installed from shard dependencies. Subcommands: - `status` (default): show installed AI docs and their state - `diff `: compare local modifications against upstream - `reset [file]`: discard local changes, restore upstream - `update [shard]`: force re-install, overwriting local changes - `merge-mcp`: merge `.mcp-shards.json` entries into `.mcp.json` ## Instance Methods ### `run(args : Array(String))` Dispatches to the appropriate subcommand based on *args*. ## /Shards/Commands/Assistant.md # class Shards::Commands::Assistant ## Constants - `HELP_TEXT` = `"shards-alpha assistant — Manage Claude Code assistant configuration\n\nUsage:\n shards-alpha assistant [command] [options]\n\nCommands:\n init Install skills, agents, settings, and MCP config\n update Update to latest version (preserves local modifications)\n status Show installed version and state (default)\n remove Remove all tracked assistant files\n\nOptions:\n --no-mcp Skip MCP server configuration (.mcp.json)\n --no-skills Skip Claude Code skills\n --no-agents Skip Claude Code agents\n --no-settings Skip settings.json and CLAUDE.md\n --force Overwrite existing/modified files\n --dry-run Preview changes without writing (update only)"` ## Class Methods ### `run(path : String, args : Array(String))` ## /Shards/Commands/Audit.md # class Shards::Commands::Audit ## Constants - `IGNORE_FILENAME` = `".shards-audit-ignore"` ## Instance Methods ### `run(format : String = "terminal", severity : String | Nil = nil, ignore_ids : Array(String) = [] of String, ignore_file : String | Nil = nil, fail_above : String | Nil = nil, offline : Bool = false, update_db : Bool = false)` ## /Shards/Commands/Build.md # class Shards::Commands::Build ## Instance Methods ### `run(targets, options)` ## /Shards/Commands/Check.md # class Shards::Commands::Check ## Instance Methods ### `apply_overrides(deps : Array(Dependency))` FIXME: duplicates MolinilloSolver#apply_overrides ### `on_override(dependency : Dependency) : Dependency | Nil` FIXME: duplicates MolinilloSolver#on_override ### `run` ## /Shards/Commands/ComplianceReport.md # class Shards::Commands::ComplianceReport ## Instance Methods ### `run(args : Array(String))` ## /Shards/Commands/Diff.md # class Shards::Commands::Diff ## Instance Methods ### `run(args : Array(String))` ## /Shards/Commands/Docs.md # class Shards::Commands::Docs Generates project documentation with theming and AI assistant integration. Wraps `crystal docs` and post-processes the output to: - Inject CSS custom properties for theming - Apply project-local theme overrides from `docs-theme/` - Add "Open in AI" buttons (Claude, ChatGPT, Gemini) to each page - Generate parallel Markdown files for AI consumption ## Constants - `AI_BUTTONS_CSS` = `".ai-assistant-bar {\n display: flex;\n gap: 8px;\n align-items: center;\n margin: 15px 0;\n padding: 10px 0;\n border-top: 1px solid var(--h2-border, #E6E6E6);\n flex-wrap: wrap;\n}\n.ai-assistant-bar .ai-label {\n font-size: 13px;\n color: var(--ai-btn-text, #555);\n margin-right: 4px;\n}\n.ai-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: 1px solid var(--ai-btn-border, #ddd);\n border-radius: 6px;\n background: var(--ai-btn-bg, #f0f0f0);\n color: var(--ai-btn-text, #555);\n text-decoration: none;\n font-size: 13px;\n cursor: pointer;\n transition: background .15s, border-color .15s;\n}\n.ai-btn:hover {\n background: var(--ai-btn-hover-bg, #e0e0e0);\n border-color: var(--ai-btn-border, #ccc);\n}\n.ai-btn:visited {\n color: var(--ai-btn-text, #555);\n}\n.ai-btn svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n}\n.ai-btn.claude-btn:hover { border-color: #D97706; }\n.ai-btn.chatgpt-btn:hover { border-color: #10A37F; }\n.ai-btn.gemini-btn:hover { border-color: #4285F4; }\n.ai-btn.md-btn:hover { border-color: var(--accent-secondary, #624288); }\n.docs-resource-bar {\n display: flex;\n gap: 8px;\n align-items: center;\n margin: 0 0 16px;\n flex-wrap: wrap;\n}\n.docs-resource-bar .resource-btn:hover {\n border-color: var(--accent-secondary, #624288);\n}\n.ashard-story {\n margin: 0 0 18px;\n padding: 16px 18px;\n border: 1px solid rgba(98, 66, 136, 0.16);\n border-radius: 14px;\n background:\n linear-gradient(135deg, rgba(238, 231, 248, 0.95), rgba(248, 244, 253, 0.95)),\n radial-gradient(circle at top right, rgba(98, 66, 136, 0.12), transparent 42%);\n box-shadow: 0 18px 40px rgba(71, 38, 110, 0.08);\n}\n.ashard-story h2 {\n margin: 0 0 10px;\n padding: 0;\n border: 0;\n}\n.ashard-story p {\n margin: 0 0 10px;\n}\n.ashard-story p:last-child {\n margin-bottom: 0;\n}\n.ashard-story code {\n font-size: .95em;\n}\n@media (prefers-color-scheme: dark) {\n .ashard-story {\n border-color: rgba(176, 146, 212, 0.22);\n background:\n linear-gradient(135deg, rgba(42, 31, 58, 0.95), rgba(28, 24, 36, 0.96)),\n radial-gradient(circle at top right, rgba(176, 146, 212, 0.15), transparent 42%);\n box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);\n }\n}"` - `AI_BUTTONS_JS` = `""` - `CSS_VARIABLES` = `":root {\n /* Sidebar */\n --sidebar-bg: #2E1052;\n --sidebar-text: #F8F4FD;\n --sidebar-link-hover: #866BA6;\n --sidebar-shadow: rgba(0,0,0,.35);\n --sidebar-input-shadow: rgba(0,0,0,.25);\n --sidebar-input-focus-shadow: rgba(0,0,0,.5);\n --sidebar-focus-outline: #D1B7F1;\n --sidebar-width: 30em;\n\n /* Project header */\n --project-name-color: #f4f4f4;\n\n /* Main content */\n --body-bg: #FFFFFF;\n --body-text: #333;\n --body-font: \"Avenir\", \"Tahoma\", \"Lucida Sans\", \"Lucida Grande\", Verdana, Arial, sans-serif;\n --link-color: #263F6C;\n --link-visited: #112750;\n --heading-color: #444444;\n\n /* Type name banner */\n --type-name-color: #47266E;\n --type-name-bg: #F8F8F8;\n --type-name-border: #EBEBEB;\n\n /* Code and signatures */\n --code-font: Menlo, Monaco, Consolas, 'Courier New', Courier, monospace;\n --code-bg: rgba(40,35,30,0.05);\n --pre-bg: #fdfdfd;\n --pre-border: #eee;\n --pre-text: #333;\n --signature-bg: #f8f8f8;\n --signature-color: #47266E;\n --signature-border: #f0f0f0;\n --signature-hover-bg: #D5CAE3;\n --signature-hover-border: #624288;\n\n /* Accent colors */\n --accent-primary: #47266E;\n --accent-secondary: #624288;\n --accent-highlight: #D5CAE3;\n --kind-color: #866BA6;\n\n /* Inherited methods */\n --inherited-link: #47266E;\n --inherited-link-hover: #6C518B;\n --inherited-tooltip-bg: #D5CAE3;\n\n /* Syntax highlighting */\n --syntax-comment: #969896;\n --syntax-number: #0086b3;\n --syntax-type: #0086b3;\n --syntax-string: #183691;\n --syntax-interpolation: #7f5030;\n --syntax-keyword: #a71d5d;\n --syntax-operator: #a71d5d;\n --syntax-method: #795da3;\n\n /* Borders */\n --h2-border: #E6E6E6;\n --table-border: #eee;\n\n /* Search results */\n --search-current-border: #ddd;\n --search-current-bg: rgba(200,200,200,0.4);\n --search-args-color: #dddddd;\n\n /* Permalink */\n --permalink-color: #624288;\n\n /* AI buttons */\n --ai-btn-bg: #f0f0f0;\n --ai-btn-border: #ddd;\n --ai-btn-text: #555;\n --ai-btn-hover-bg: #e0e0e0;\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n --body-bg: #1b1b1b;\n --body-text: white;\n --link-color: #8cb4ff;\n --link-visited: #5f8de3;\n --heading-color: white;\n --type-name-color: white;\n --type-name-bg: #202020;\n --type-name-border: #353535;\n --code-bg: #202020;\n --pre-bg: #202020;\n --pre-border: #353535;\n --pre-text: white;\n --signature-bg: #202020;\n --signature-color: white;\n --signature-border: #353535;\n --signature-hover-bg: #443d4d;\n --signature-hover-border: #b092d4;\n --accent-primary: white;\n --accent-highlight: #443d4d;\n --kind-color: #b092d4;\n --inherited-link: #B290D9;\n --inherited-link-hover: #D4B7F4;\n --inherited-tooltip-bg: #443d4d;\n --syntax-comment: #a1a1a1;\n --syntax-number: #00ade6;\n --syntax-type: #00ade6;\n --syntax-string: #7799ff;\n --syntax-interpolation: #b38668;\n --syntax-keyword: #ff66ae;\n --syntax-operator: #ff66ae;\n --syntax-method: #b9a5d6;\n --h2-border: #353535;\n --table-border: #353535;\n --permalink-color: #b092d4;\n --ai-btn-bg: #2a2a2a;\n --ai-btn-border: #444;\n --ai-btn-text: #ccc;\n --ai-btn-hover-bg: #3a3a3a;\n }\n}"` ## Instance Methods ### `run(args : Array(String))` ## Types - `Shards::Commands::Docs::AgentFileEntry` (alias) ## /Shards/Commands/Docs/AgentFileEntry.md # alias Shards::Commands::Docs::AgentFileEntry ## /Shards/Commands/Init.md # class Shards::Commands::Init ## Instance Methods ### `run` ## /Shards/Commands/Install.md # class Shards::Commands::Install ## Instance Methods ### `run` ## /Shards/Commands/Licenses.md # class Shards::Commands::Licenses ## Instance Methods ### `run(format : String = "terminal", policy_path : String | Nil = nil, check : Bool = false, include_dev : Bool = false, detect : Bool = false)` ## /Shards/Commands/List.md # class Shards::Commands::List ## Instance Methods ### `run(tree : Bool = false)` ## /Shards/Commands/Lock.md # class Shards::Commands::Lock ## Instance Methods ### `run(shards : Array(String), print = false, update = false)` ## /Shards/Commands/MCP.md # class Shards::Commands::MCP ## Instance Methods ### `run(args : Array(String))` ## /Shards/Commands/Outdated.md # class Shards::Commands::Outdated ## Instance Methods ### `run(prereleases : Bool = false)` ## /Shards/Commands/Policy.md # class Shards::Commands::Policy ## Constants - `DEFAULT_POLICY_TEMPLATE` = `"version: 1\n\nrules:\n sources:\n allowed_hosts: []\n deny_path_dependencies: false\n\n dependencies:\n blocked: []\n minimum_versions: {}\n\n security:\n require_license: false\n block_postinstall: false\n audit_postinstall: false"` ## Instance Methods ### `run(args : Array(String))` ## /Shards/Commands/Prune.md # class Shards::Commands::Prune ## Instance Methods ### `run` ## /Shards/Commands/Run.md # class Shards::Commands::Run ## Instance Methods ### `run(targets, options, run_options)` ## /Shards/Commands/RunScript.md # class Shards::Commands::RunScript Runs postinstall scripts that are pending or have changed since last execution. When called without arguments, runs all pending scripts. When given shard names, runs only those specific scripts. This command exists because postinstall scripts only auto-run on first install. If a script changes during `shards update`, the user must explicitly run it with this command. ## Instance Methods ### `run(shard_names : Array(String))` Runs postinstall scripts for the specified shards, or all pending if none given. ## /Shards/Commands/SBOM.md # class Shards::Commands::SBOM ## Instance Methods ### `run(format : String, output : String | Nil, include_dev : Bool)` ## /Shards/Commands/Update.md # class Shards::Commands::Update ## Instance Methods ### `run(shards : Array(String))` ## /Shards/Commands/Version.md # class Shards::Commands::Version ## Class Methods ### `run(path)` ## Instance Methods ### `run` ## /Shards/Compliance.md # module Shards::Compliance ## Types - `Shards::Compliance::Attestation` (struct) - `Shards::Compliance::HtmlTemplate` (module) - `Shards::Compliance::ProjectInfo` (struct) - `Shards::Compliance::ReportBuilder` (class) - `Shards::Compliance::ReportData` (struct) - `Shards::Compliance::ReportFormatter` (class) - `Shards::Compliance::SectionData` (struct) - `Shards::Compliance::Summary` (struct) - `Shards::Compliance::VulnerabilityCounts` (struct) ## /Shards/Compliance/Attestation.md # struct Shards::Compliance::Attestation ## Constructors ### `new(reviewer : String, reviewed_at : Time, notes : Nil | String = nil)` ## Instance Methods ### `notes` ### `reviewed_at` ### `reviewer` ## /Shards/Compliance/HtmlTemplate.md # module Shards::Compliance::HtmlTemplate ## Constants - `CSS` = `" * { box-sizing: border-box; margin: 0; padding: 0; }\n body { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; max-width: 1200px; margin: 0 auto; padding: 2rem; color: #333; }\n header { border-bottom: 2px solid #e0e0e0; padding-bottom: 1rem; margin-bottom: 2rem; }\n h1 { font-size: 1.8rem; color: #1a1a2e; }\n h2 { font-size: 1.3rem; margin: 1.5rem 0 1rem; color: #16213e; cursor: pointer; }\n .report-meta { display: flex; gap: 2rem; margin-top: 0.5rem; color: #666; font-size: 0.9rem; }\n .status-badge { display: inline-block; padding: 0.4rem 1rem; border-radius: 4px; font-weight: bold; color: white; text-transform: uppercase; }\n .status-badge.pass { background: #28a745; }\n .status-badge.fail { background: #dc3545; }\n .status-badge.action_required { background: #ffc107; color: #333; }\n table { width: 100%; border-collapse: collapse; margin: 1rem 0; }\n th, td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid #e0e0e0; }\n th { background: #f8f9fa; font-weight: 600; }\n tr.pass td:nth-child(3) { color: #28a745; }\n tr.warn td:nth-child(3) { color: #ffc107; }\n .summary { margin-bottom: 2rem; }\n .metrics { max-width: 400px; }\n section { margin-bottom: 2rem; }\n .section-content { margin-left: 1rem; }\n .attestation { border-top: 2px solid #e0e0e0; padding-top: 1rem; }\n footer { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #e0e0e0; color: #999; font-size: 0.85rem; }\n @media print { .section-header { cursor: default; } body { max-width: none; } }"` - `JS` = `" document.querySelectorAll('.section-header').forEach(function(h) {\n h.addEventListener('click', function() {\n var content = h.nextElementSibling;\n if (content) { content.style.display = content.style.display === 'none' ? '' : 'none'; }\n });\n });"` ## Class Methods ### `render(data : ReportData) : String` ## /Shards/Compliance/ProjectInfo.md # struct Shards::Compliance::ProjectInfo ## Constructors ### `new(name : String, version : String, crystal_version : String)` ## Instance Methods ### `crystal_version` ### `name` ### `version` ## /Shards/Compliance/ReportBuilder.md # class Shards::Compliance::ReportBuilder ## Constructors ### `new(path : String, spec : Shards::Spec, locks : Shards::Lock, sections : Array(String) = ["all"], since : Nil | String = nil, reviewer : Nil | String = nil)` ## Instance Methods ### `build` ### `locks` ### `path` ### `requested_sections` ### `reviewer` ### `since` ### `spec` ## /Shards/Compliance/ReportData.md # struct Shards::Compliance::ReportData ## Constructors ### `new(project : Shards::Compliance::ProjectInfo, summary : Shards::Compliance::Summary, sections : Shards::Compliance::SectionData, reviewer : Nil | String = nil, attestation : Shards::Compliance::Attestation | Nil = nil, version : String = "1.0", generated_at : Time = Time.utc, generator : String = "shards-alpha #{VERSION}")` ## Instance Methods ### `attestation` ### `generated_at` ### `generator` ### `project` ### `reviewer` ### `sections` ### `summary` ### `version` ## /Shards/Compliance/ReportFormatter.md # class Shards::Compliance::ReportFormatter ## Constructors ### `new(format : String, template_path : Nil | String = nil)` ## Instance Methods ### `format` ### `template_path` ### `write(data : ReportData, output_path : String) : Nil` ## /Shards/Compliance/SectionData.md # struct Shards::Compliance::SectionData ## Constructors ### `new` ## Instance Methods ### `change_history` ### `change_history=(change_history : JSON::Any | Nil)` ### `integrity` ### `integrity=(integrity : JSON::Any | Nil)` ### `license_audit` ### `license_audit=(license_audit : JSON::Any | Nil)` ### `policy_compliance` ### `policy_compliance=(policy_compliance : JSON::Any | Nil)` ### `sbom` ### `sbom=(sbom : JSON::Any | Nil)` ### `vulnerability_audit` ### `vulnerability_audit=(vulnerability_audit : JSON::Any | Nil)` ## /Shards/Compliance/Summary.md # struct Shards::Compliance::Summary ## Constructors ### `new(total_dependencies : Int32, direct_dependencies : Int32, transitive_dependencies : Int32, vulnerabilities : Shards::Compliance::VulnerabilityCounts, license_compliance : String, policy_compliance : String, integrity_verified : Bool | Nil, overall_status : String)` ## Instance Methods ### `direct_dependencies` ### `integrity_verified` ### `license_compliance` ### `overall_status` ### `policy_compliance` ### `total_dependencies` ### `transitive_dependencies` ### `vulnerabilities` ## /Shards/Compliance/VulnerabilityCounts.md # struct Shards::Compliance::VulnerabilityCounts ## Constructors ### `new(critical : Int32 = 0, high : Int32 = 0, medium : Int32 = 0, low : Int32 = 0)` ## Instance Methods ### `critical` ### `critical=(critical : Int32)` ### `high` ### `high=(high : Int32)` ### `low` ### `low=(low : Int32)` ### `medium` ### `medium=(medium : Int32)` ## /Shards/ComplianceMCPServer.md # class Shards::ComplianceMCPServer ## Constants - `CAPABILITIES` = `MCProtocol::ServerCapabilities.new(tools: MCProtocol::ServerCapabilitiesTools.new)` - `HELP_TEXT` = `"shards-alpha mcp-server — MCP compliance server (JSON-RPC 2.0 over stdio)\n\nUsage:\n shards-alpha mcp-server [command] [options]\n\nCommands:\n init Configure .mcp.json for MCP server\n (default) Start the MCP server (stdio transport)\n\nOptions:\n --interactive Run in interactive mode for manual testing\n --help, -h Show this help message\n\nTools provided:\n audit Scan dependencies for known vulnerabilities (OSV)\n licenses List dependency licenses with SPDX validation\n policy_check Check dependencies against policy rules\n diff Show dependency changes between lockfile states\n compliance_report Generate unified compliance report\n sbom Generate Software Bill of Materials (SPDX/CycloneDX)\n\nExamples:\n shards-alpha mcp-server init # Configure .mcp.json\n shards-alpha mcp-server # Start server (for MCP clients)\n shards-alpha mcp-server --interactive # Manual testing mode\n\nFor Claude Code skills, agents, and settings, use:\n shards-alpha assistant init"` - `LATEST_VERSION` = `SUPPORTED_VERSIONS.first` - `MCP_SERVER_NAME` = `"shards-compliance"` - `SERVER_INFO` = `MCProtocol::Implementation.new(name: "shards-compliance", version: Shards::VERSION)` - `SUPPORTED_VERSIONS` = `["2025-11-25", "2025-06-18", "2025-03-26", "2024-11-05"]` -- Supported MCP protocol versions, newest first. - `TOOLS` = `[MCProtocol::Tool.new(name: "audit", description: "Scan dependencies for known vulnerabilities using the OSV database. Returns vulnerability details with severity levels.", inputSchema: MCProtocol::ToolInputSchema.new(properties: JSON::Any.new({"severity" => JSON::Any.new({"type" => JSON::Any.new("string"), "enum" => JSON::Any.new(["low", "medium", "high", "critical"].map do |s| JSON::Any.new(s) end), "description" => JSON::Any.new("Minimum severity filter")}), "fail_above" => JSON::Any.new({"type" => JSON::Any.new("string"), "enum" => JSON::Any.new(["low", "medium", "high", "critical"].map do |s| JSON::Any.new(s) end), "description" => JSON::Any.new("Exit non-zero if vulnerabilities at or above this severity are found")}), "ignore" => JSON::Any.new({"type" => JSON::Any.new("string"), "description" => JSON::Any.new("Comma-separated advisory IDs to suppress")}), "offline" => JSON::Any.new({"type" => JSON::Any.new("boolean"), "description" => JSON::Any.new("Use cached vulnerability data only")})}))), MCProtocol::Tool.new(name: "licenses", description: "List all dependency licenses with SPDX identifier validation. Optionally check compliance against a license policy.", inputSchema: MCProtocol::ToolInputSchema.new(properties: JSON::Any.new({"check" => JSON::Any.new({"type" => JSON::Any.new("boolean"), "description" => JSON::Any.new("Exit non-zero if policy violations found")}), "detect" => JSON::Any.new({"type" => JSON::Any.new("boolean"), "description" => JSON::Any.new("Use heuristic detection from LICENSE files")}), "include_dev" => JSON::Any.new({"type" => JSON::Any.new("boolean"), "description" => JSON::Any.new("Include development dependencies")})}))), MCProtocol::Tool.new(name: "policy_check", description: "Check dependencies against policy rules defined in .shards-policy.yml. Validates allowed licenses, version constraints, and source requirements.", inputSchema: MCProtocol::ToolInputSchema.new(properties: JSON::Any.new({"strict" => JSON::Any.new({"type" => JSON::Any.new("boolean"), "description" => JSON::Any.new("Treat warnings as errors")})}))), MCProtocol::Tool.new(name: "diff", description: "Show dependency changes between lockfile states. Compares added, removed, and upgraded dependencies.", inputSchema: MCProtocol::ToolInputSchema.new(properties: JSON::Any.new({"from" => JSON::Any.new({"type" => JSON::Any.new("string"), "description" => JSON::Any.new("Starting ref (git ref, file path, or 'current'). Default: HEAD")}), "to" => JSON::Any.new({"type" => JSON::Any.new("string"), "description" => JSON::Any.new("Ending ref. Default: current working tree")})}))), MCProtocol::Tool.new(name: "compliance_report", description: "Generate a unified supply chain compliance report combining SBOM, audit, licenses, policy, integrity, and changelog sections.", inputSchema: MCProtocol::ToolInputSchema.new(properties: JSON::Any.new({"sections" => JSON::Any.new({"type" => JSON::Any.new("string"), "description" => JSON::Any.new("Comma-separated sections to include: sbom,audit,licenses,policy,integrity,changelog (default: all)")}), "reviewer" => JSON::Any.new({"type" => JSON::Any.new("string"), "description" => JSON::Any.new("Reviewer email for attestation")})}))), MCProtocol::Tool.new(name: "sbom", description: "Generate a Software Bill of Materials (SBOM) listing all dependencies with versions, licenses, and relationships.", inputSchema: MCProtocol::ToolInputSchema.new(properties: JSON::Any.new({"format" => JSON::Any.new({"type" => JSON::Any.new("string"), "enum" => JSON::Any.new(["spdx", "cyclonedx"].map do |s| JSON::Any.new(s) end), "description" => JSON::Any.new("SBOM format (default: spdx)")}), "include_dev" => JSON::Any.new({"type" => JSON::Any.new("boolean"), "description" => JSON::Any.new("Include development dependencies")})})))]` ## Constructors ### `new(path : String, interactive : Bool = false)` ## Class Methods ### `init_claude_config(path : String)` ### `init_mcp_config(path : String)` ### `run(path : String, args : Array(String) = [] of String)` ## Instance Methods ### `build_cli_args(tool_name : String, arguments : JSON::Any | Nil) : Array(String)` Build CLI arguments from tool name and parameters ### `negotiate_version(client_version : String | Nil) : String` Negotiate the best protocol version. If the client requests a version we support, use it. If the client requests a version newer than our latest, use our latest. If the client requests an older version we don't support, use our oldest. If no version is provided, use the latest. ### `run` ## /Shards/Conflict.md # class Shards::Conflict ## Constructors ### `new(package : Package)` ## Instance Methods ### `package` ## /Shards/CrystalResolver.md # class Shards::CrystalResolver ## Constants - `INSTANCE` = `new("crystal", "")` ## Class Methods ### `key` ## Instance Methods ### `available_releases` ### `install_sources(version : Version, install_path : String)` ### `read_spec(version : Version) : String | Nil` ### `report_version(version : Version) : String` ## /Shards/Dependency.md # class Shards::Dependency ## Constructors ### `new(name : String, resolver : Resolver, requirement : Requirement = Any)` ## Class Methods ### `from_yaml(pull : YAML::PullParser)` ## Instance Methods ### `==(other : self)` Returns `true` if this reference is the same as *other*. Invokes `same?`. ### `as_package?` ### `checksum` ### `checksum=(checksum : String | Nil)` ### `matches?(version : Version)` ### `name` ### `name=(name : String)` ### `prerelease?` ### `requirement` ### `requirement=(requirement : Requirement)` ### `resolver` ### `resolver=(resolver : Resolver)` ### `to_s(io)` ### `to_yaml(yaml : YAML::Builder)` ## /Shards/DiffReport.md # class Shards::DiffReport ## Constructors ### `new(changes : Array(Shards::LockfileDiffer::Change), from_label : String = "HEAD", to_label : String = "working tree")` ## Instance Methods ### `any_changes?` ### `changes` ### `from_label` ### `to_json(io : IO = STDOUT) : Nil` ### `to_label` ### `to_markdown(io : IO = STDOUT) : Nil` ### `to_terminal(io : IO = STDOUT) : Nil` ## /Shards/Docs.md # module Shards::Docs # Shards Documentation Shards is the dependency manager for the Crystal programming language. It reads `shard.yml` to resolve, install, and update dependencies from source repositories. ## Features - **Dependency resolution** via `shard.yml` with semantic versioning - **Lock files** (`shard.lock`) for reproducible builds - **Build targets** for compiling Crystal executables - **Postinstall scripts** with version-aware execution tracking - **AI documentation distribution** from shard dependencies - **MCP server distribution** via `.mcp-shards.json` See `Shards::Docs` submodules for detailed guides on each feature area. ## Types - `Shards::Docs::AIDocumentation` (module) - `Shards::Docs::CLIReference` (module) - `Shards::Docs::DocsGeneration` (module) - `Shards::Docs::MCPDistribution` (module) - `Shards::Docs::MCPLifecycle` (module) - `Shards::Docs::PostinstallScripts` (module) - `Shards::Docs::PublishingGuide` (module) - `Shards::Docs::SBOMGeneration` (module) - `Shards::Docs::ShardYmlFormat` (module) ## /Shards/Docs/AIDocumentation.md # module Shards::Docs::AIDocumentation ## AI Documentation Distribution Shards can distribute AI coding agent documentation alongside library code. When you run `shards install`, AI docs from dependencies are automatically installed into the project's `.claude/` directory. ### How It Works The `AIDocsInstaller` scans each installed dependency for AI-relevant files and copies them into the project with shard-namespaced paths. ### Auto-detected locations These paths are scanned in each dependency: | Source in shard | What it is | |---|---| | `.claude/skills//` | Claude Code skills | | `.claude/agents/.md` | Agent definitions | | `.claude/commands/.md` | Slash commands | | `CLAUDE.md` | General AI context | | `AGENTS.md` | Agent specifications | | `.mcp.json` | MCP server configs | ### Installation mapping Files are namespaced by shard name to prevent conflicts: | Source | Destination | |---|---| | `.claude/skills//` | `.claude/skills/--/` | | `.claude/agents/.md` | `.claude/agents/--.md` | | `.claude/commands/.md` | `.claude/commands/:.md` | | `CLAUDE.md` (no skills) | `.claude/skills/--docs/SKILL.md` | | `CLAUDE.md` (with skills) | `.claude/skills/--docs/reference/CLAUDE.md` | | `AGENTS.md` | `.claude/skills/--docs/reference/AGENTS.md` | | `.mcp.json` | merged into `.mcp-shards.json` | When a shard ships `CLAUDE.md` but no explicit skills, the content is wrapped as a passive skill with frontmatter (`user-invocable: false`). ### Conflict detection `AIDocsInfo` tracks two checksums per file (upstream and installed). User-modified files are preserved during updates, with a `.upstream` copy saved for comparison. See `AIDocsInfo::FileEntry#user_modified?`. ### Security `.claude/settings.json` and `.claude/settings.local.json` are never distributed, even if present in a dependency. ### shard.yml configuration The `ai_docs` section is optional. Auto-detection handles standard locations. Use it only for customization: ```yaml ai_docs: include: - docs/claude/custom_guide.md exclude: - .claude/skills/internal_dev_tool/ ``` See `Spec::AIDocs`, `AIDocsInstaller`, `AIDocsInfo`. ## /Shards/Docs/CLIReference.md # module Shards::Docs::CLIReference ## CLI Commands Reference ### Core commands | Command | Description | |---|---| | `shards install` | Install dependencies from `shard.yml` | | `shards update [names...]` | Update dependencies to latest compatible | | `shards build [targets...]` | Build targets defined in `shard.yml` | | `shards run [target]` | Build and run a target | | `shards check` | Verify all dependencies are installed | | `shards list [--tree]` | List installed dependencies | | `shards lock [--update]` | Lock dependencies without installing | | `shards outdated [--pre]` | Show outdated dependencies | | `shards prune` | Remove unused dependencies | | `shards version [path]` | Print the shard version | | `shards init` | Generate a new `shard.yml` | ### AI docs commands | Command | Description | |---|---| | `shards ai-docs` | Show installed AI docs status | | `shards ai-docs diff ` | Diff local changes vs upstream | | `shards ai-docs reset [file]` | Reset to upstream version | | `shards ai-docs update [shard]` | Force re-install AI docs | | `shards ai-docs merge-mcp` | Merge shard MCP configs into `.mcp.json` | | `shards run-script [names...]` | Run pending postinstall scripts | | `shards docs [options]` | Generate themed docs with AI buttons | | `shards sbom [options]` | Generate SBOM (SPDX/CycloneDX) | ### MCP lifecycle commands | Command | Description | |---|---| | `shards mcp` | Show MCP server status (default) | | `shards mcp start [name]` | Start all or one MCP server | | `shards mcp stop [name]` | Stop all or one MCP server | | `shards mcp restart [name]` | Restart all or one MCP server | | `shards mcp logs ` | Tail server logs (`--no-follow`, `--lines=N`) | ### Global flags | Flag | Description | |---|---| | `--frozen` | Strictly install locked versions | | `--without-development` | Skip dev dependencies | | `--production` | `--frozen --without-development` | | `--skip-postinstall` | Skip postinstall scripts | | `--skip-executables` | Skip executable installation | | `--skip-ai-docs` | Skip AI documentation installation | | `--local` | Use local cache only | | `--jobs=N` | Parallel downloads (default: 8) | See individual command classes in `Commands`. ## /Shards/Docs/DocsGeneration.md # module Shards::Docs::DocsGeneration ## Documentation Generation and Theming The `shards docs` command wraps `crystal docs` to add theming support, AI assistant integration buttons, LLM-oriented text exports, and publishable copies of project agent files. ### Usage ``` shards docs # Generate docs with defaults shards docs --skip-ai-buttons # No AI buttons shards docs --skip-agent-files # Do not copy .claude/.mcp resources shards docs --skip-llms # Do not generate llms.txt exports shards docs -o my_docs # Custom output directory ``` All standard `crystal docs` options are passed through. ### Theming with CSS Variables `shards docs` injects CSS custom properties into the generated stylesheet. To create a custom theme, create `docs-theme/style.css` in your project root and override the variables: ```css :root { --sidebar-bg: #1a1a2e; --sidebar-text: #e0e0e0; --accent-primary: #e94560; --type-name-color: #e94560; --signature-color: #e94560; --link-color: #0f3460; } ``` Available CSS variables cover sidebar colors, main content colors, code/signature styling, syntax highlighting, and more. See `Commands::Docs::CSS_VARIABLES` for the full list. ### AI Assistant Buttons Each generated page includes buttons to discuss the API with: - **Claude** (claude.ai) - **ChatGPT** (chatgpt.com) - **Gemini** (gemini.google.com) - **View as Markdown** (opens the parallel `.md` file) The buttons extract page content and construct a prompt that includes the type name, project name, and documentation. ### Markdown Files Parallel `.md` files are generated for every HTML page, making the documentation easily consumable by AI coding assistants, CLI tools, and any system that prefers plain text. `shards docs` also emits: - `llms.txt` — concise machine-oriented index of the generated docs - `llms-full.txt` — concatenated markdown export of the docs set - `llms.json` — manifest of markdown and agent resources If the project contains `.claude/` files or `.mcp.json`, they are copied into `agent-files/` inside the docs output with HTML/JSON/Markdown indexes so the published docs site can distribute them directly. See `Commands::Docs`. ## /Shards/Docs/MCPDistribution.md # module Shards::Docs::MCPDistribution ## MCP Server Distribution Shards that ship `.mcp.json` can distribute MCP (Model Context Protocol) server configurations to consuming projects. ### How it works When a dependency contains `.mcp.json`, the `AIDocsInstaller`: 1. Parses the JSON and extracts `mcpServers` entries 2. Namespaces server names as `/` 3. Rewrites relative command/args paths to `lib//...` 4. Merges into `.mcp-shards.json` at the project root The user's `.mcp.json` is never modified automatically. To merge shard servers into the user's config: ``` shards ai - docs merge - mcp ``` ### Example .mcp.json in a shard ```json { "mcpServers": { "db-explorer": { "command": "./bin/mcp-server", "args": ["--mode", "readonly"] } } } ``` After installation, this becomes `/db-explorer` in `.mcp-shards.json` with the command rewritten to `lib//bin/mcp-server`. See `AIDocsInstaller#install_mcp_config`, `Commands::AIDocs`. ## /Shards/Docs/MCPLifecycle.md # module Shards::Docs::MCPLifecycle ## MCP Server Lifecycle Management The `shards mcp` command manages the runtime lifecycle of MCP servers distributed via `.mcp-shards.json`. This completes the pipeline from distribution (handled by `shards install`) to execution. ### Commands ``` shards mcp # Show server status (default) shards mcp start [server_name] # Start all or one server shards mcp stop [server_name] # Stop all or one server shards mcp restart [server_name] # Restart all or one server shards mcp logs [--no-follow] [--lines=N] ``` ### Runtime state All managed state lives in `.shards/mcp/`: - `servers.json`: PID, port, timestamps per server - `.log`: per-server stdout/stderr logs - `bin/`: cached builds for `crystal_main` servers ### Process management Servers are spawned via `Process.new` (non-blocking) with output redirected to log files. PID tracking uses `LibC.kill(pid, 0)`. Shutdown sends SIGTERM, waits 5 seconds, then SIGKILL if needed. Stale PIDs are detected and cleaned on every status check. ### Name resolution Server names use the existing namespacing from `.mcp-shards.json` (e.g., `my_shard/explorer`). Partial name matching is supported: `explorer` finds `my_shard/explorer` if unambiguous. See `MCPManager`, `Commands::MCP`. ## /Shards/Docs/PostinstallScripts.md # module Shards::Docs::PostinstallScripts ## Postinstall Scripts Shards supports postinstall scripts defined in `shard.yml`: ```yaml scripts: postinstall: make ext ``` ### Version-aware execution Postinstall scripts use `PostinstallInfo` for tracking: - **First install**: the script runs automatically, and its hash is recorded - **Subsequent installs** (same script): skipped silently - **Script changed**: a warning is emitted, the user must run `shards run-script ` explicitly This prevents unexpected re-execution of potentially destructive scripts while still notifying users when scripts change. ### Manual execution ``` shards run - script # run all pending scripts shards run - script my_shard # run for specific shard ``` See `PostinstallInfo`, `Commands::RunScript`, `Package#postinstall`. ## /Shards/Docs/PublishingGuide.md # module Shards::Docs::PublishingGuide ## Publishing AI Docs for Your Shard ### Recommended: ship skills Create `.claude/skills/` in your shard repository: ``` your_shard/ .claude/ skills/ getting-started/ SKILL.md api-reference/ SKILL.md src/ shard.yml ``` Each `SKILL.md` needs frontmatter: ```markdown --- name: getting-started description: How to get started with your_shard user-invocable: false --- # Getting Started ... ``` ### Simple: ship CLAUDE.md For basic documentation, add a `CLAUDE.md` at your shard root. It is auto-converted to a passive skill during installation. ### Optional: customize with shard.yml ```yaml ai_docs: include: - docs/claude/advanced_guide.md exclude: - .claude/skills/internal_dev_tool/ ``` ### Ship MCP servers Add `.mcp.json` to your shard root with standard MCP configuration. Relative paths in `command` and `args` are automatically rewritten. See `AIDocsInstaller`, `Docs::AIDocumentation`, `Docs::MCPDistribution`. ## /Shards/Docs/SBOMGeneration.md # module Shards::Docs::SBOMGeneration ## Software Bill of Materials (SBOM) Generation The `shards sbom` command generates a machine-readable inventory of all dependencies in SPDX 2.3 or CycloneDX 1.6 JSON format for compliance auditing (SOC 2, ISO 27001). ### Usage ``` shards sbom # SPDX 2.3 JSON (default) shards sbom --format=cyclonedx # CycloneDX 1.6 JSON shards sbom --output=custom.json # Custom output path shards sbom --include-dev # Include dev dependencies ``` ### Data sources The command reads `shard.lock` for locked versions, then loads each dependency's `shard.yml` from `lib//` for metadata (license, authors, description). Package URLs (purls) are derived from resolver source URLs, with GitHub/GitLab/Bitbucket sources mapped to their respective purl types. See `Commands::SBOM`. ## /Shards/Docs/ShardYmlFormat.md # module Shards::Docs::ShardYmlFormat ## shard.yml Format ### Required fields ```yaml name: my_shard version: 1.0.0 ``` ### Dependencies ```yaml dependencies: kemal: github: kemalcr/kemal version: ~> 1.0 local_dep: path: ../local_dep development_dependencies: ameba: github: crystal-ameba/ameba ``` ### Dependency sources | Key | Description | |---|---| | `github: user/repo` | GitHub repository | | `gitlab: user/repo` | GitLab repository | | `bitbucket: user/repo` | Bitbucket repository | | `git: ` | Any git URL | | `hg: ` | Mercurial | | `fossil: ` | Fossil | | `path: ` | Local path | ### Version constraints | Pattern | Meaning | |---|---| | `*` | Any version | | `1.0.0` | Exact version | | `>= 1.0.0` | Minimum version | | `~> 1.0` | >= 1.0.0, < 2.0.0 | | `~> 1.0.3` | >= 1.0.3, < 1.1.0 | ### Build targets ```yaml targets: my_app: main: src/my_app.cr ``` ### Scripts ```yaml scripts: postinstall: make ext ``` ### AI documentation (optional) ```yaml ai_docs: include: - docs/claude/custom_guide.md exclude: - .claude/skills/internal_dev_tool/ ``` See `Spec`, `Spec::AIDocs`, `Dependency`. ## /Shards/Error.md # class Shards::Error ## /Shards/FossilBranchRef.md # struct Shards::FossilBranchRef ## Constructors ### `new(branch : String)` ## Instance Methods ### `to_fossil_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/FossilCommitRef.md # struct Shards::FossilCommitRef ## Constructors ### `new(commit : String)` ## Instance Methods ### `=~(other : FossilCommitRef)` ### `commit` ### `full_info` ### `to_fossil_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/FossilRef.md # struct Shards::FossilRef ## Instance Methods ### `full_info` ## /Shards/FossilResolver.md # class Shards::FossilResolver ## Class Methods ### `key` ### `normalize_key_source(key : String, source : String) : Tuple(String, String)` ## Instance Methods ### `available_releases` ### `commit_sha1_at(ref : FossilRef)` ### `fossil_url` ### `install_sources(version : Version, install_path : String)` ### `latest_version_for_ref(ref : FossilRef | Nil) : Version` ### `local_fossil_file` ### `local_path` ### `matches_ref?(ref : FossilRef, version : Version)` ### `parse_requirement(params : Hash(String, String)) : Requirement` ### `read_spec(version : Version) : String | Nil` ### `report_version(version : Version) : String` ### `update_local_cache` ## Types - `Shards::FossilResolver::FossilVersion` (struct) ## /Shards/FossilResolver/FossilVersion.md # struct Shards::FossilResolver::FossilVersion ## Constructors ### `new(value : String, commit : String | Nil = nil)` ## Instance Methods ### `clone` ### `commit` ### `copy_with(value _value = @value, commit _commit = @commit)` ### `value` ## /Shards/FossilTagRef.md # struct Shards::FossilTagRef ## Constructors ### `new(tag : String)` ## Instance Methods ### `to_fossil_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/FossilTrunkRef.md # struct Shards::FossilTrunkRef ## Instance Methods ### `to_fossil_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/GitBranchRef.md # struct Shards::GitBranchRef ## Constructors ### `new(branch : String)` ## Instance Methods ### `to_git_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/GitCommitRef.md # struct Shards::GitCommitRef ## Constructors ### `new(commit : String)` ## Instance Methods ### `=~(other : GitCommitRef)` ### `commit` ### `full_info` ### `to_git_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/GitHeadRef.md # struct Shards::GitHeadRef ## Instance Methods ### `to_git_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/GitRef.md # struct Shards::GitRef ## Instance Methods ### `full_info` ## /Shards/GitResolver.md # class Shards::GitResolver ## Class Methods ### `key` ### `normalize_key_source(key : String, source : String) : Tuple(String, String)` ## Instance Methods ### `available_releases` ### `commit_sha1_at(ref : GitRef)` ### `git_url` ### `install_sources(version : Version, install_path : String)` ### `latest_version_for_ref(ref : GitRef | Nil) : Version` ### `local_path` ### `matches_ref?(ref : GitRef, version : Version)` ### `parse_requirement(params : Hash(String, String)) : Requirement` ### `read_spec(version : Version) : String | Nil` ### `report_version(version : Version) : String` ### `update_local_cache` ## Types - `Shards::GitResolver::GitVersion` (struct) ## /Shards/GitResolver/GitVersion.md # struct Shards::GitResolver::GitVersion ## Constructors ### `new(value : String, commit : String | Nil = nil)` ## Instance Methods ### `clone` ### `commit` ### `copy_with(value _value = @value, commit _commit = @commit)` ### `value` ## /Shards/GitTagRef.md # struct Shards::GitTagRef ## Constructors ### `new(tag : String)` ## Instance Methods ### `to_git_ref` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/Helpers.md # module Shards::Helpers ## Class Methods ### `developer_mode?` ### `exe(name)` ### `privilege_enabled?(privilege_name : String) : Bool` ### `rm_rf(path : String) : Nil` ### `rm_rf_children(dir : String) : Nil` ## /Shards/HgBookmarkRef.md # struct Shards::HgBookmarkRef ## Constructors ### `new(bookmark : String)` ## Instance Methods ### `to_hg_ref` ### `to_hg_revset` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/HgBranchRef.md # struct Shards::HgBranchRef ## Constructors ### `new(branch : String)` ## Instance Methods ### `to_hg_ref` ### `to_hg_revset` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/HgCommitRef.md # struct Shards::HgCommitRef ## Constructors ### `new(commit : String)` ## Instance Methods ### `=~(other : HgCommitRef)` ### `commit` ### `full_info` ### `to_hg_ref` ### `to_hg_revset` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/HgCurrentRef.md # struct Shards::HgCurrentRef ## Instance Methods ### `to_hg_ref` ### `to_hg_revset` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/HgRef.md # struct Shards::HgRef ## Instance Methods ### `full_info` ## /Shards/HgResolver.md # class Shards::HgResolver ## Class Methods ### `key` ### `normalize_key_source(key : String, source : String) : Tuple(String, String)` ## Instance Methods ### `available_releases` ### `commit_sha1_at(ref : HgRef)` ### `hg_url` ### `install_sources(version : Version, install_path : String)` ### `latest_version_for_ref(ref : HgRef | Nil) : Version` ### `local_path` ### `matches_ref?(ref : HgRef, version : Version)` ### `parse_requirement(params : Hash(String, String)) : Requirement` ### `read_spec(version : Version) : String | Nil` ### `report_version(version : Version) : String` ### `update_local_cache` ## Types - `Shards::HgResolver::HgVersion` (struct) ## /Shards/HgResolver/HgVersion.md # struct Shards::HgResolver::HgVersion ## Constructors ### `new(value : String, commit : String | Nil = nil)` ## Instance Methods ### `clone` ### `commit` ### `copy_with(value _value = @value, commit _commit = @commit)` ### `value` ## /Shards/HgTagRef.md # struct Shards::HgTagRef ## Constructors ### `new(tag : String)` ## Instance Methods ### `to_hg_ref` ### `to_hg_revset` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/IgnoreRule.md # struct Shards::IgnoreRule Ignore rule loaded from .shards-audit-ignore or --ignore flag. ## Constructors ### `new(id : String, reason : Nil | String = nil, expires : Time | Nil = nil)` ## Instance Methods ### `active?` ### `expired?` ### `expires` ### `id` ### `reason` ## /Shards/Info.md # class Shards::Info ## Constructors ### `new(install_path : String = Shards.install_path)` ## Instance Methods ### `info_path` ### `install_path` ### `installed` ### `reload` ### `save` ## /Shards/InvalidLock.md # class Shards::InvalidLock ## Constructors ### `new` ## /Shards/LicensePolicy.md # class Shards::LicensePolicy ## Constants - `DEFAULT_POLICY_FILENAME` = `".shards-license-policy.yml"` ## Class Methods ### `compute_summary(results : Array(DependencyResult)) : Summary` ### `evaluate(packages : Array(Package), root_spec : Spec, policy : PolicyConfig | Nil, detect : Bool = false) : PolicyReport` ### `evaluate_against_policy(license : String | Nil, policy : PolicyConfig | Nil) : Verdict` ### `load_policy(path : String | Nil) : PolicyConfig | Nil` ## Types - `Shards::LicensePolicy::DependencyResult` (struct) - `Shards::LicensePolicy::Override` (struct) - `Shards::LicensePolicy::PolicyConfig` (struct) - `Shards::LicensePolicy::PolicyReport` (struct) - `Shards::LicensePolicy::Summary` (struct) - `Shards::LicensePolicy::Verdict` (enum) ## /Shards/LicensePolicy/DependencyResult.md # struct Shards::LicensePolicy::DependencyResult ## Constructors ### `new(name : String, version : String, declared_license : String | Nil, detected_license : String | Nil, effective_license : String | Nil, license_source : Symbol, verdict : Verdict, override_reason : String | Nil, spdx_valid : Bool, category : SPDX::Category, scan_result : LicenseScanner::ScanResult | Nil)` ## Instance Methods ### `category` ### `clone` ### `copy_with(name _name = @name, version _version = @version, declared_license _declared_license = @declared_license, detected_license _detected_license = @detected_license, effective_license _effective_license = @effective_license, license_source _license_source = @license_source, verdict _verdict = @verdict, override_reason _override_reason = @override_reason, spdx_valid _spdx_valid = @spdx_valid, category _category = @category, scan_result _scan_result = @scan_result)` ### `declared_license` ### `detected_license` ### `effective_license` ### `license_source` ### `name` ### `override_reason` ### `scan_result` ### `spdx_valid` ### `verdict` ### `version` ## /Shards/LicensePolicy/Override.md # struct Shards::LicensePolicy::Override ## Constructors ### `new(license : String, reason : String | Nil)` ## Instance Methods ### `clone` ### `copy_with(license _license = @license, reason _reason = @reason)` ### `license` ### `reason` ## /Shards/LicensePolicy/PolicyConfig.md # struct Shards::LicensePolicy::PolicyConfig ## Constructors ### `new(allowed : Set(String), denied : Set(String), require_license : Bool, overrides : Hash(String, Override))` ## Instance Methods ### `allowed` ### `clone` ### `copy_with(allowed _allowed = @allowed, denied _denied = @denied, require_license _require_license = @require_license, overrides _overrides = @overrides)` ### `denied` ### `overrides` ### `require_license` ## /Shards/LicensePolicy/PolicyReport.md # struct Shards::LicensePolicy::PolicyReport ## Constructors ### `new(root_name : String, root_version : String, root_license : String | Nil, dependencies : Array(DependencyResult), policy_used : Bool, summary : Summary)` ## Instance Methods ### `clone` ### `copy_with(root_name _root_name = @root_name, root_version _root_version = @root_version, root_license _root_license = @root_license, dependencies _dependencies = @dependencies, policy_used _policy_used = @policy_used, summary _summary = @summary)` ### `dependencies` ### `policy_used` ### `root_license` ### `root_name` ### `root_version` ### `summary` ## /Shards/LicensePolicy/Summary.md # struct Shards::LicensePolicy::Summary ## Constructors ### `new(total : Int32, allowed : Int32, denied : Int32, unlicensed : Int32, unknown : Int32, overridden : Int32)` ## Instance Methods ### `allowed` ### `clone` ### `copy_with(total _total = @total, allowed _allowed = @allowed, denied _denied = @denied, unlicensed _unlicensed = @unlicensed, unknown _unknown = @unknown, overridden _overridden = @overridden)` ### `denied` ### `overridden` ### `total` ### `unknown` ### `unlicensed` ## /Shards/LicensePolicy/Verdict.md # enum Shards::LicensePolicy::Verdict ## Constants - `Allowed` = `0` - `Denied` = `1` - `Unlicensed` = `2` - `Unknown` = `3` - `Overridden` = `4` ## Instance Methods ### `allowed?` Returns `true` if this enum value equals `Allowed` ### `denied?` Returns `true` if this enum value equals `Denied` ### `overridden?` Returns `true` if this enum value equals `Overridden` ### `unknown?` Returns `true` if this enum value equals `Unknown` ### `unlicensed?` Returns `true` if this enum value equals `Unlicensed` ## /Shards/LicenseScanner.md # class Shards::LicenseScanner ## Constants - `LICENSE_FILE_PATTERNS` = `["LICENSE", "LICENSE.md", "LICENSE.txt", "LICENCE", "LICENCE.md", "LICENCE.txt", "LICENSE-MIT", "LICENSE-APACHE", "COPYING", "COPYING.md", "COPYING.txt"]` - `LICENSE_PATTERNS` = `[{/MIT License|Permission is hereby granted, free of charge/i, "MIT"}, {/Apache License.*Version 2\.0/i, "Apache-2.0"}, {/BSD 2-Clause|Redistribution and use.*two conditions/i, "BSD-2-Clause"}, {/BSD 3-Clause|Redistribution and use.*three conditions/i, "BSD-3-Clause"}, {/ISC License/i, "ISC"}, {/Mozilla Public License.*2\.0/i, "MPL-2.0"}, {/GNU General Public License.*version 3/i, "GPL-3.0-only"}, {/GNU General Public License.*version 2/i, "GPL-2.0-only"}, {/GNU Lesser General Public License.*version 3/i, "LGPL-3.0-only"}, {/GNU Lesser General Public License.*version 2\.1/i, "LGPL-2.1-only"}, {/GNU Affero General Public License.*version 3/i, "AGPL-3.0-only"}, {/The Unlicense|unlicense\.org/i, "Unlicense"}, {/Creative Commons Zero|CC0 1\.0/i, "CC0-1.0"}, {/zlib License/i, "Zlib"}]` ## Class Methods ### `detect_license(content : String) : Tuple(String | Nil, Symbol)` ### `find_license_file(dir : String) : String | Nil` ### `scan(install_path : String) : ScanResult` ## Types - `Shards::LicenseScanner::ScanResult` (struct) ## /Shards/LicenseScanner/ScanResult.md # struct Shards::LicenseScanner::ScanResult ## Constructors ### `new(license_file_path : String | Nil, detected_license : String | Nil, detection_confidence : Symbol)` ## Instance Methods ### `clone` ### `copy_with(license_file_path _license_file_path = @license_file_path, detected_license _detected_license = @detected_license, detection_confidence _detection_confidence = @detection_confidence)` ### `detected_license` ### `detection_confidence` ### `license_file_path` ## /Shards/Lock.md # class Shards::Lock ## Constants - `CURRENT_VERSION` = `"2.0"` ## Constructors ### `new(version : String, shards : Array(Package))` ## Class Methods ### `from_file(path)` ### `from_yaml(str)` ### `write(packages : Array(Package), override_path : String | Nil, path : String)` ### `write(packages : Array(Package), override_path : String | Nil, io : IO)` ## Instance Methods ### `shards` ### `shards=(shards : Array(Package))` ### `version` ### `version=(version : String)` ## /Shards/LockConflict.md # class Shards::LockConflict ## Constructors ### `new(message)` ## /Shards/LockfileDiffer.md # class Shards::LockfileDiffer ## Class Methods ### `diff(from_packages : Array(Package), to_packages : Array(Package)) : Array(Change)` Compare two package sets and produce changes ## Types - `Shards::LockfileDiffer::Change` (struct) - `Shards::LockfileDiffer::Status` (enum) ## /Shards/LockfileDiffer/Change.md # struct Shards::LockfileDiffer::Change ## Constructors ### `new(name : String, status : Status, from_version : String | Nil, to_version : String | Nil, from_commit : String | Nil, to_commit : String | Nil, from_source : String | Nil, to_source : String | Nil, from_resolver_key : String | Nil, to_resolver_key : String | Nil)` ## Instance Methods ### `clone` ### `copy_with(name _name = @name, status _status = @status, from_version _from_version = @from_version, to_version _to_version = @to_version, from_commit _from_commit = @from_commit, to_commit _to_commit = @to_commit, from_source _from_source = @from_source, to_source _to_source = @to_source, from_resolver_key _from_resolver_key = @from_resolver_key, to_resolver_key _to_resolver_key = @to_resolver_key)` ### `from_commit` ### `from_resolver_key` ### `from_source` ### `from_version` ### `name` ### `status` ### `to_commit` ### `to_resolver_key` ### `to_source` ### `to_version` ## /Shards/LockfileDiffer/Status.md # enum Shards::LockfileDiffer::Status ## Constants - `Added` = `0` - `Updated` = `1` - `Removed` = `2` - `Unchanged` = `3` ## Instance Methods ### `added?` Returns `true` if this enum value equals `Added` ### `removed?` Returns `true` if this enum value equals `Removed` ### `unchanged?` Returns `true` if this enum value equals `Unchanged` ### `updated?` Returns `true` if this enum value equals `Updated` ## /Shards/MCPManager.md # class Shards::MCPManager ## Constants - `BIN_DIR` = `"bin"` - `Log` = `::Log.for("shards.mcp")` - `MCP_SHARDS_CONFIG` = `".mcp-shards.json"` - `RUNTIME_DIR` = `".shards/mcp"` - `STATE_FILE` = `"servers.json"` ## Constructors ### `new(path : String)` ## Instance Methods ### `load_configs` ### `logs(name : String, follow : Bool = true, lines : Int32 = 20)` ### `path` ### `restart(name : String | Nil = nil)` ### `sanitize_name(name : String) : String` ### `start(name : String | Nil = nil)` ### `status` ### `stop(name : String | Nil = nil)` ## Types - `Shards::MCPManager::ServerConfig` (struct) - `Shards::MCPManager::ServerState` (struct) - `Shards::MCPManager::ServerStatusInfo` (struct) - `Shards::MCPManager::StateFile` (struct) ## /Shards/MCPManager/ServerConfig.md # struct Shards::MCPManager::ServerConfig ## Constructors ### `new(name : String, command : Nil | String, args : Array(String), crystal_main : Nil | String, transport : String, env : Hash(String, String))` ## Instance Methods ### `args` ### `command` ### `crystal_main` ### `env` ### `name` ### `transport` ## /Shards/MCPManager/ServerState.md # struct Shards::MCPManager::ServerState ## Constructors ### `new(name : String, pid : Int64, transport : String, port : Int32 | Nil, log_file : String, command : String, args : Array(String), started_at : String)` ### `new(pull : JSON::PullParser)` ### `new(*, __pull_for_json_serializable pull : JSON::PullParser)` ## Instance Methods ### `args` ### `args=(args : Array(String))` ### `command` ### `command=(command : String)` ### `log_file` ### `log_file=(log_file : String)` ### `name` ### `name=(name : String)` ### `pid` ### `pid=(pid : Int64)` ### `port` ### `port=(port : Int32 | Nil)` ### `started_at` ### `started_at=(started_at : String)` ### `transport` ### `transport=(transport : String)` ## /Shards/MCPManager/ServerStatusInfo.md # struct Shards::MCPManager::ServerStatusInfo ## Constructors ### `new(name : String, running : Bool, pid : Int64 | Nil, transport : String, started_at : Time | Nil)` ## Instance Methods ### `name` ### `pid` ### `running` ### `started_at` ### `transport` ## /Shards/MCPManager/StateFile.md # struct Shards::MCPManager::StateFile ## Constructors ### `new(pull : JSON::PullParser)` ### `new` ### `new(*, __pull_for_json_serializable pull : JSON::PullParser)` ## Instance Methods ### `servers` ### `servers=(servers : Hash(String, ServerState))` ### `version` ### `version=(version : String)` ## /Shards/MolinilloSolver.md # class Shards::MolinilloSolver ## Constructors ### `new(spec : Spec, override : Override | Nil = nil, *, prereleases : Bool = false)` ## Class Methods ### `crystal_version_req(specification : Shards::Spec)` ## Instance Methods ### `after_resolution` Called after resolution ends (either successfully or with an error). By default, prints a newline. @return [void] ### `apply_overrides(deps : Array(Dependency))` ### `before_resolution` Called before resolution begins. @return [void] ### `dependencies_for(specification : S) : Array(R)` Returns the dependencies of `specification`. @note This method should be 'pure', i.e. the return value should depend only on the `specification` parameter. @param [Object] specification @return [Array] the dependencies that are required by the given `specification`. ### `indicate_progress` Called roughly every {#progress_rate}, this method should convey progress to the user. @return [void] ### `locks=(locks : Array(Package) | Nil)` ### `name_for(spec : Shards::Spec)` ### `name_for(dependency : Shards::Dependency)` Returns the name for the given `dependency`. @note This method should be 'pure', i.e. the return value should depend only on the `dependency` parameter. @param [Object] dependency @return [String] the name for the given `dependency`. ### `name_for_explicit_dependency_source` @return [String] the name of the source of explicit dependencies, i.e. those passed to {Resolver#resolve} directly. ### `name_for_locking_dependency_source` @return [String] the name of the source of 'locked' dependencies, i.e. those passed to {Resolver#resolve} directly as the `base` ### `on_override(dependency : Dependency | Shards::Spec) : Dependency | Nil` ### `prepare(development : Bool | Nil = true)` ### `requirement_satisfied_by?(dependency, activated, spec)` ### `search_for(dependency : R) : Array(S)` Search for the specifications that match the given dependency. The specifications in the returned array will be considered in reverse order, so the latest version ought to be last. @note This method should be 'pure', i.e. the return value should depend only on the `dependency` parameter. @param [Object] dependency @return [Array] the specifications that satisfy the given `dependency`. ### `solve` ## /Shards/Override.md # class Shards::Override ## Constructors ### `new(pull : YAML::PullParser, validate = false) : self` ### `new(dependencies : Array(Dependency))` ## Class Methods ### `from_file(path, validate = false)` ### `from_yaml(input, filename = OVERRIDE_FILENAME, validate = false)` ## Instance Methods ### `dependencies` ## /Shards/Package.md # class Shards::Package ## Constructors ### `new(name : String, resolver : Shards::Resolver, version : Shards::Version, is_override : Bool = false, checksum : String | Nil = nil)` ## Instance Methods ### `==(other : self)` Returns `true` if this reference is the same as *other*. Invokes `same?`. ### `checksum` ### `checksum=(checksum : String | Nil)` ### `compute_checksum` ### `find_executable_file(install_path, name)` ### `install` ### `install_executables` ### `install_path` ### `installed?` ### `is_override` ### `name` ### `postinstall` ### `report_version` ### `resolver` ### `run_script(name, skip)` ### `spec` ### `to_s(io)` ### `to_yaml(builder)` ### `version` ## /Shards/PackageScanResult.md # struct Shards::PackageScanResult Holds the scan result for a single package. ## Constructors ### `new(package : Shards::Package, purl : Nil | String, vulnerabilities : Array(Shards::Vulnerability) = [] of Vulnerability)` ## Instance Methods ### `package` ### `purl` ### `vulnerabilities` ### `vulnerable?` ## /Shards/ParseError.md # class Shards::ParseError ## Constructors ### `new(message, input : String, filename : String, line_number, column_number)` ## Instance Methods ### `column_number` ### `filename` ### `input` ### `line_number` ### `resolver` ### `resolver=(resolver : Resolver | Nil)` ### `to_s(io)` ## /Shards/PathResolver.md # class Shards::PathResolver ## Class Methods ### `key` ## Instance Methods ### `available_releases` ### `install_sources(version, install_path)` ### `local_path` ### `read_spec(version = nil) : String | Nil` ### `report_version(version : Version) : String` ### `spec(version = nil)` ## /Shards/Policy.md # class Shards::Policy ## Constants - `CURRENT_VERSION` = `"1"` ## Constructors ### `from_file(path : String) : self` ### `from_yaml(input : String, filename = POLICY_FILENAME) : self` ### `new(pull : YAML::PullParser)` ### `new(version : String = CURRENT_VERSION, sources : Shards::Policy::SourceRules = SourceRules.new, dependencies : Shards::Policy::DependencyRules = DependencyRules.new, freshness : Shards::Policy::FreshnessRules = FreshnessRules.new, security : Shards::Policy::SecurityRules = SecurityRules.new, custom : Array(Shards::Policy::CustomRule) = [] of CustomRule)` ## Instance Methods ### `custom` ### `dependencies` ### `freshness` ### `security` ### `sources` ### `version` ## Types - `Shards::Policy::BlockedDep` (class) - `Shards::Policy::CustomRule` (class) - `Shards::Policy::DependencyRules` (class) - `Shards::Policy::FreshnessRules` (class) - `Shards::Policy::SecurityRules` (class) - `Shards::Policy::SourceRules` (class) ## /Shards/Policy/BlockedDep.md # class Shards::Policy::BlockedDep ## Constructors ### `new(name : String, reason : Nil | String = nil)` ## Instance Methods ### `name` ### `reason` ## /Shards/Policy/CustomRule.md # class Shards::Policy::CustomRule ## Constructors ### `new(name : String, pattern_str : String, action_str : String, reason : Nil | String = nil)` ## Instance Methods ### `action` ### `name` ### `pattern` ### `reason` ## /Shards/Policy/DependencyRules.md # class Shards::Policy::DependencyRules ## Constructors ### `new(blocked : Array(Shards::Policy::BlockedDep) = [] of BlockedDep, minimum_versions : Hash(String, String) = {} of String => String)` ## Instance Methods ### `blocked` ### `minimum_versions` ## /Shards/Policy/FreshnessRules.md # class Shards::Policy::FreshnessRules ## Constructors ### `new(max_age_days : Int32 | Nil = nil, require_recent_commit : Int32 | Nil = nil)` ## Instance Methods ### `max_age_days` ### `require_recent_commit` ## /Shards/Policy/SecurityRules.md # class Shards::Policy::SecurityRules ## Constructors ### `new(require_license : Bool = false, require_checksum : Bool = false, block_postinstall : Bool = false, audit_postinstall : Bool = false)` ## Instance Methods ### `audit_postinstall?` ### `block_postinstall?` ### `require_checksum?` ### `require_license?` ## /Shards/Policy/SourceRules.md # class Shards::Policy::SourceRules ## Constructors ### `new(allowed_hosts : Array(String) = [] of String, allowed_orgs : Hash(String, Array(String)) = {} of String => Array(String), deny_path_dependencies : Bool = false)` ## Instance Methods ### `allowed_hosts` ### `allowed_orgs` ### `deny_path_dependencies?` ### `empty?` ## /Shards/PolicyChecker.md # class Shards::PolicyChecker ## Constructors ### `new(policy : Policy)` ## Instance Methods ### `check(packages : Array(Package)) : PolicyReport` Main entry point: check all packages against all rules ### `policy` ### `report` ## /Shards/PolicyReport.md # class Shards::PolicyReport ## Constructors ### `new` ## Instance Methods ### `add_violation(package : String, rule : String, severity : Severity, message : String)` ### `clean?` ### `errors` ### `exit_code(strict : Bool = false) : Int32` ### `has_errors?` ### `has_warnings?` ### `to_json_output(io : IO)` ### `to_terminal(io : IO, colors : Bool = Shards.colors?)` ### `violations` ### `warnings` ## Types - `Shards::PolicyReport::Severity` (enum) - `Shards::PolicyReport::Violation` (struct) ## /Shards/PolicyReport/Severity.md # enum Shards::PolicyReport::Severity ## Constants - `Error` = `0` - `Warning` = `1` ## Instance Methods ### `error?` Returns `true` if this enum value equals `Error` ### `warning?` Returns `true` if this enum value equals `Warning` ## /Shards/PolicyReport/Violation.md # struct Shards::PolicyReport::Violation ## Constructors ### `new(package : String, rule : String, severity : Severity, message : String)` ## Instance Methods ### `clone` ### `copy_with(package _package = @package, rule _rule = @rule, severity _severity = @severity, message _message = @message)` ### `message` ### `package` ### `rule` ### `severity` ## /Shards/PostinstallInfo.md # class Shards::PostinstallInfo Tracks postinstall script execution state across installs. Persisted at `lib/.shards.postinstall`, this tracker stores a hash of each shard's postinstall command and whether it has been executed. This enables version-aware postinstall behavior: - First install: run the script, record its hash - Subsequent installs with same script: skip silently - Script changed: warn the user, require explicit `shards run-script` ## Constants - `CURRENT_VERSION` = `"1.0"` ## Constructors ### `new(path : String)` ## Class Methods ### `hash_script(command : String) : String` Computes a SHA-256 hash of a postinstall command string. ## Instance Methods ### `load` Loads tracker state from the YAML file at `#path`. ### `path` Absolute path to the `.shards.postinstall` file. ### `save` Persists the current tracker state to the YAML file at `#path`. ### `shards` Map of shard name to its postinstall entry. ## Types - `Shards::PostinstallInfo::Entry` (class) ## /Shards/PostinstallInfo/Entry.md # class Shards::PostinstallInfo::Entry Tracks the state of a single shard's postinstall script. ## Constructors ### `new(script_hash : String, has_run : Bool = false)` ## Instance Methods ### `has_run` Whether the script has been executed. ### `has_run=(has_run : Bool)` Whether the script has been executed. ### `script_hash` SHA-256 hash of the postinstall command string. ### `script_hash=(script_hash : String)` SHA-256 hash of the postinstall command string. ## /Shards/PurlGenerator.md # module Shards::PurlGenerator ## Class Methods ### `generate(pkg : Package) : String | Nil` Returns a Package URL (purl) string for the given package, or nil for path dependencies that have no meaningful remote identity. ### `parse_owner_repo(source : String) : Tuple(String | Nil, String | Nil)` Parses "owner/repo" from a git source URL. ## /Shards/Ref.md # struct Shards::Ref ## Constructors ### `new` ## Instance Methods ### `initialize` ## /Shards/Requirement.md # alias Shards::Requirement ## /Shards/Resolver.md # class Shards::Resolver ## Constructors ### `new(name : String, source : String)` ## Class Methods ### `build(key : String, name : String, source : String)` ### `clear_resolver_cache` ### `find_class(key : String) : Resolver.class | Nil` ### `find_resolver(key : String, name : String, source : String)` ### `normalize_key_source(key : String, source : String)` ### `register_resolver(key, resolver)` ## Instance Methods ### `==(other : Resolver)` ### `available_releases` ### `install_sources(version : Version, install_path : String)` ### `latest_version_for_ref(ref : Ref | Nil) : Version` ### `matches_ref?(ref : Ref, version : Version)` ### `name` ### `parse_requirement(params : Hash(String, String)) : Requirement` ### `read_spec(version : Version) : String | Nil` ### `report_version(version : Version) : String` ### `source` ### `spec(version : Version) : Spec` ### `to_s(io : IO)` Appends a short String representation of this object which includes its class name and its object address. ``` class Person def initialize(@name : String, @age : Int32) end end Person.new("John", 32).to_s # => # ``` ### `update_local_cache` ### `versions_for(req : Requirement) : Array(Version)` ### `yaml_source_entry` ## /Shards/SPDX.md # module Shards::SPDX ## Constants - `LICENSES` = `{"MIT" => LicenseInfo.new("MIT", "MIT License", true, Category::Permissive), "Apache-2.0" => LicenseInfo.new("Apache-2.0", "Apache License 2.0", true, Category::Permissive), "BSD-2-Clause" => LicenseInfo.new("BSD-2-Clause", "BSD 2-Clause \"Simplified\" License", true, Category::Permissive), "BSD-3-Clause" => LicenseInfo.new("BSD-3-Clause", "BSD 3-Clause \"New\" or \"Revised\" License", true, Category::Permissive), "ISC" => LicenseInfo.new("ISC", "ISC License", true, Category::Permissive), "Zlib" => LicenseInfo.new("Zlib", "zlib License", true, Category::Permissive), "0BSD" => LicenseInfo.new("0BSD", "BSD Zero Clause License", true, Category::Permissive), "WTFPL" => LicenseInfo.new("WTFPL", "Do What The F*ck You Want To Public License", false, Category::Permissive), "CC-BY-4.0" => LicenseInfo.new("CC-BY-4.0", "Creative Commons Attribution 4.0 International", false, Category::Permissive), "PostgreSQL" => LicenseInfo.new("PostgreSQL", "PostgreSQL License", true, Category::Permissive), "BlueOak-1.0.0" => LicenseInfo.new("BlueOak-1.0.0", "Blue Oak Model License 1.0.0", false, Category::Permissive), "Artistic-2.0" => LicenseInfo.new("Artistic-2.0", "Artistic License 2.0", true, Category::Permissive), "BSL-1.0" => LicenseInfo.new("BSL-1.0", "Boost Software License 1.0", true, Category::Permissive), "MS-PL" => LicenseInfo.new("MS-PL", "Microsoft Public License", true, Category::Permissive), "ECL-2.0" => LicenseInfo.new("ECL-2.0", "Educational Community License v2.0", true, Category::Permissive), "BSD-1-Clause" => LicenseInfo.new("BSD-1-Clause", "BSD 1-Clause License", true, Category::Permissive), "AFL-3.0" => LicenseInfo.new("AFL-3.0", "Academic Free License v3.0", true, Category::Permissive), "Python-2.0" => LicenseInfo.new("Python-2.0", "Python License 2.0", true, Category::Permissive), "Ruby" => LicenseInfo.new("Ruby", "Ruby License", false, Category::Permissive), "Unicode-DFS-2016" => LicenseInfo.new("Unicode-DFS-2016", "Unicode License Agreement - Data Files and Software (2016)", false, Category::Permissive), "Vim" => LicenseInfo.new("Vim", "Vim License", false, Category::Permissive), "NCSA" => LicenseInfo.new("NCSA", "University of Illinois/NCSA Open Source License", true, Category::Permissive), "X11" => LicenseInfo.new("X11", "X11 License", false, Category::Permissive), "Libpng" => LicenseInfo.new("Libpng", "libpng License", false, Category::Permissive), "curl" => LicenseInfo.new("curl", "curl License", false, Category::Permissive), "Unlicense" => LicenseInfo.new("Unlicense", "The Unlicense", true, Category::PublicDomain), "CC0-1.0" => LicenseInfo.new("CC0-1.0", "Creative Commons Zero v1.0 Universal", false, Category::PublicDomain), "MPL-2.0" => LicenseInfo.new("MPL-2.0", "Mozilla Public License 2.0", true, Category::WeakCopyleft), "LGPL-2.1-only" => LicenseInfo.new("LGPL-2.1-only", "GNU Lesser General Public License v2.1 only", true, Category::WeakCopyleft), "LGPL-2.1-or-later" => LicenseInfo.new("LGPL-2.1-or-later", "GNU Lesser General Public License v2.1 or later", true, Category::WeakCopyleft), "LGPL-3.0-only" => LicenseInfo.new("LGPL-3.0-only", "GNU Lesser General Public License v3.0 only", true, Category::WeakCopyleft), "LGPL-3.0-or-later" => LicenseInfo.new("LGPL-3.0-or-later", "GNU Lesser General Public License v3.0 or later", true, Category::WeakCopyleft), "EPL-2.0" => LicenseInfo.new("EPL-2.0", "Eclipse Public License 2.0", true, Category::WeakCopyleft), "CC-BY-SA-4.0" => LicenseInfo.new("CC-BY-SA-4.0", "Creative Commons Attribution Share Alike 4.0 International", false, Category::WeakCopyleft), "EUPL-1.2" => LicenseInfo.new("EUPL-1.2", "European Union Public License 1.2", true, Category::WeakCopyleft), "MS-RL" => LicenseInfo.new("MS-RL", "Microsoft Reciprocal License", true, Category::WeakCopyleft), "CDDL-1.0" => LicenseInfo.new("CDDL-1.0", "Common Development and Distribution License 1.0", true, Category::WeakCopyleft), "CPAL-1.0" => LicenseInfo.new("CPAL-1.0", "Common Public Attribution License 1.0", true, Category::WeakCopyleft), "EPL-1.0" => LicenseInfo.new("EPL-1.0", "Eclipse Public License 1.0", true, Category::WeakCopyleft), "MulanPSL-2.0" => LicenseInfo.new("MulanPSL-2.0", "Mulan Permissive Software License, Version 2", true, Category::WeakCopyleft), "GPL-2.0-only" => LicenseInfo.new("GPL-2.0-only", "GNU General Public License v2.0 only", true, Category::StrongCopyleft), "GPL-2.0-or-later" => LicenseInfo.new("GPL-2.0-or-later", "GNU General Public License v2.0 or later", true, Category::StrongCopyleft), "GPL-3.0-only" => LicenseInfo.new("GPL-3.0-only", "GNU General Public License v3.0 only", true, Category::StrongCopyleft), "GPL-3.0-or-later" => LicenseInfo.new("GPL-3.0-or-later", "GNU General Public License v3.0 or later", true, Category::StrongCopyleft), "AGPL-3.0-only" => LicenseInfo.new("AGPL-3.0-only", "GNU Affero General Public License v3.0", true, Category::StrongCopyleft), "AGPL-3.0-or-later" => LicenseInfo.new("AGPL-3.0-or-later", "GNU Affero General Public License v3.0 or later", true, Category::StrongCopyleft), "OSL-3.0" => LicenseInfo.new("OSL-3.0", "Open Software License 3.0", true, Category::StrongCopyleft), "CC-BY-NC-4.0" => LicenseInfo.new("CC-BY-NC-4.0", "Creative Commons Attribution NonCommercial 4.0 International", false, Category::NonCommercial), "CC-BY-NC-SA-4.0" => LicenseInfo.new("CC-BY-NC-SA-4.0", "Creative Commons Attribution NonCommercial ShareAlike 4.0 International", false, Category::NonCommercial), "SSPL-1.0" => LicenseInfo.new("SSPL-1.0", "Server Side Public License, v 1", false, Category::Proprietary), "BSL-1.1" => LicenseInfo.new("BSL-1.1", "Business Source License 1.1", false, Category::Proprietary)}` ## Class Methods ### `category_for(id : String) : Category` ### `lookup(id : String) : LicenseInfo | Nil` ### `parse(expression : String) : Expression` ### `valid_id?(id : String) : Bool` ## Types - `Shards::SPDX::AndExpression` (class) - `Shards::SPDX::Category` (enum) - `Shards::SPDX::Expression` (class) - `Shards::SPDX::LicenseInfo` (struct) - `Shards::SPDX::OrExpression` (class) - `Shards::SPDX::Parser` (class) - `Shards::SPDX::SimpleExpression` (class) - `Shards::SPDX::WithExpression` (class) ## /Shards/SPDX/AndExpression.md # class Shards::SPDX::AndExpression ## Constructors ### `new(left : Expression, right : Expression)` ## Instance Methods ### `left` ### `license_ids` ### `right` ### `satisfied_by?(allowed : Set(String)) : Bool` ## /Shards/SPDX/Category.md # enum Shards::SPDX::Category ## Constants - `Permissive` = `0` - `WeakCopyleft` = `1` - `StrongCopyleft` = `2` - `NonCommercial` = `3` - `PublicDomain` = `4` - `Proprietary` = `5` - `Unknown` = `6` ## Instance Methods ### `non_commercial?` Returns `true` if this enum value equals `NonCommercial` ### `permissive?` Returns `true` if this enum value equals `Permissive` ### `proprietary?` Returns `true` if this enum value equals `Proprietary` ### `public_domain?` Returns `true` if this enum value equals `PublicDomain` ### `strong_copyleft?` Returns `true` if this enum value equals `StrongCopyleft` ### `unknown?` Returns `true` if this enum value equals `Unknown` ### `weak_copyleft?` Returns `true` if this enum value equals `WeakCopyleft` ## /Shards/SPDX/Expression.md # class Shards::SPDX::Expression ## Instance Methods ### `license_ids` ### `satisfied_by?(allowed : Set(String)) : Bool` ## /Shards/SPDX/LicenseInfo.md # struct Shards::SPDX::LicenseInfo ## Constructors ### `new(id : String, name : String, osi_approved : Bool, category : Category)` ## Instance Methods ### `category` ### `clone` ### `copy_with(id _id = @id, name _name = @name, osi_approved _osi_approved = @osi_approved, category _category = @category)` ### `id` ### `name` ### `osi_approved` ## /Shards/SPDX/OrExpression.md # class Shards::SPDX::OrExpression ## Constructors ### `new(left : Expression, right : Expression)` ## Instance Methods ### `left` ### `license_ids` ### `right` ### `satisfied_by?(allowed : Set(String)) : Bool` ## /Shards/SPDX/Parser.md # class Shards::SPDX::Parser ## Class Methods ### `parse(input : String) : Expression` ## Instance Methods ### `parse` ## /Shards/SPDX/SimpleExpression.md # class Shards::SPDX::SimpleExpression ## Constructors ### `new(id : String, or_later : Bool = false)` ## Instance Methods ### `id` ### `license_ids` ### `or_later` ### `satisfied_by?(allowed : Set(String)) : Bool` ## /Shards/SPDX/WithExpression.md # class Shards::SPDX::WithExpression ## Constructors ### `new(license : SimpleExpression, exception : String)` ## Instance Methods ### `exception` ### `license` ### `license_ids` ### `satisfied_by?(allowed : Set(String)) : Bool` ## /Shards/Script.md # module Shards::Script ## Class Methods ### `run(path, command, script_name, dependency_name)` ## Types - `Shards::Script::Error` (class) ## /Shards/Script/Error.md # class Shards::Script::Error ## /Shards/Severity.md # enum Shards::Severity Severity levels with ordering support. ## Constants - `Unknown` = `0` - `Low` = `1` - `Medium` = `2` - `High` = `3` - `Critical` = `4` ## Constructors ### `parse(str : String) : Severity` ## Instance Methods ### `at_or_above?(threshold : Severity) : Bool` Returns true if this severity is at or above the given threshold. ### `critical?` Returns `true` if this enum value equals `Critical` ### `high?` Returns `true` if this enum value equals `High` ### `low?` Returns `true` if this enum value equals `Low` ### `medium?` Returns `true` if this enum value equals `Medium` ### `unknown?` Returns `true` if this enum value equals `Unknown` ## /Shards/Spec.md # class Shards::Spec ## Constructors ### `new(name : String, version : Version, resolver : Resolver | Nil = nil)` ## Class Methods ### `from_file(path, validate = false)` ### `from_yaml(input, filename = SPEC_FILENAME, validate = false)` ## Instance Methods ### `ai_assistant` ### `ai_docs` ### `authors` ### `crystal` ### `dependencies` ### `description` ### `development_dependencies` ### `executables` ### `libraries` ### `license` ### `license_url` ### `mismatched_version?` ### `name` ### `name=(name : String)` ### `name?` ### `original_version` ### `original_version?` ### `read_from_yaml?` ### `resolver` ### `resolver=(resolver : Resolver | Nil)` ### `scripts` ### `targets` ### `to_s(io)` ### `version` ### `version=(version : Version)` ### `version?` ## Types - `Shards::Spec::AIAssistant` (class) - `Shards::Spec::AIDocs` (class) - `Shards::Spec::Author` (class) - `Shards::Spec::Library` (class) ## /Shards/Spec/AIAssistant.md # class Shards::Spec::AIAssistant Optional `ai_assistant` section in `shard.yml` for enabling automatic installation/update of AI assistant configuration during `shards install`. ```yaml ai_assistant: auto_install: true ``` ## Constructors ### `new(pull : YAML::PullParser)` ### `new(auto_install : Bool = false)` ## Instance Methods ### `auto_install` ## /Shards/Spec/AIDocs.md # class Shards::Spec::AIDocs Optional `ai_docs` section in `shard.yml` for customizing AI documentation distribution. When absent, auto-detection handles standard locations. ```yaml ai_docs: include: - docs/claude/custom_guide.md exclude: - .claude/skills/internal_dev_tool/ ``` ## Constructors ### `new(pull : YAML::PullParser)` ### `new(include __arg1 : Array(String) = [] of String, exclude : Array(String) = [] of String)` ## Instance Methods ### `exclude` Paths to exclude from auto-detected AI docs. ### `include` Extra files to include beyond auto-detected locations. ## /Shards/Spec/Author.md # class Shards::Spec::Author ## Constructors ### `new(pull : YAML::PullParser)` ### `new(name)` ## Instance Methods ### `email` ### `email=(email : String | Nil)` ### `name` ### `name=(name : String)` ## /Shards/Spec/Library.md # class Shards::Spec::Library ## Constructors ### `new(soname : String, version : String)` ### `new(pull : YAML::PullParser)` ## Instance Methods ### `soname` ### `soname=(soname : String)` ### `version` ### `version=(version : String)` ## /Shards/Target.md # class Shards::Target ## Constructors ### `new(name : String, main : String)` ### `new(pull : YAML::PullParser) : self` ## Instance Methods ### `main` ### `main=(main : String)` ### `name` ### `name=(name : String)` ## /Shards/Version.md # struct Shards::Version ## Constructors ### `new(value : String)` ## Instance Methods ### `has_metadata?` ### `prerelease?` ### `to_s(io)` ### `to_yaml(yaml)` ### `value` ## /Shards/VersionReq.md # struct Shards::VersionReq ## Constructors ### `new(patterns)` ## Instance Methods ### `patterns` ### `prerelease?` ### `to_s(io)` ### `to_yaml(yaml)` ## /Shards/Versions.md # module Shards::Versions ## Class Methods ### `compare(a : Version, b : Version)` ### `compare(a : String, b : String)` ### `has_metadata?(str : String)` ### `matches?(version : Version, requirement : VersionReq)` ### `prerelease?(str : String)` ### `resolve(versions : Array(Version), requirement : VersionReq)` ### `sort(versions)` ## /Shards/Vulnerability.md # struct Shards::Vulnerability Represents a single vulnerability found by OSV. ## Constructors ### `new(id : String, summary : String, details : String, severity : Shards::Severity, cvss_score : Float64 | Nil, affected_versions : Array(String), references : Array(String), aliases : Array(String), published : Time | Nil, modified : Time | Nil)` ## Instance Methods ### `affected_versions` ### `aliases` ### `cvss_score` ### `details` ### `id` ### `modified` ### `published` ### `references` ### `severity` ### `summary` ## /Shards/VulnerabilityReport.md # class Shards::VulnerabilityReport ## Constructors ### `new(results : Array(Shards::PackageScanResult), ignore_rules : Array(Shards::IgnoreRule) = [] of IgnoreRule, min_severity : Shards::Severity = Severity::Unknown, fail_above : Severity | Nil = nil)` ## Instance Methods ### `exit_code` Returns appropriate exit code. 0 = no vulnerabilities above threshold 1 = vulnerabilities found above threshold ### `fail_above` ### `filtered_results` Returns filtered results (after applying ignore rules and severity filter). ### `ignore_rules` ### `min_severity` ### `results` ### `to_json(io : IO)` ### `to_sarif(io : IO)` ### `to_terminal(io : IO = STDOUT)` ### `vulnerability_count` Total vulnerability count after filtering. ## /Shards/VulnerabilityScanner.md # class Shards::VulnerabilityScanner ## Constants - `CACHE_DIR` = `".shards/audit/cache"` - `CACHE_TTL` = `1.hour` - `OSV_BATCH_URL` = `"https://api.osv.dev/v1/querybatch"` - `OSV_QUERY_URL` = `"https://api.osv.dev/v1/query"` ## Constructors ### `new(path : String, offline : Bool = false)` ## Class Methods ### `load_ignore_rules(path : String) : Array(IgnoreRule)` ## Instance Methods ### `results` ### `scan(packages : Array(Package)) : Array(PackageScanResult)` Main entry point: scans all packages for vulnerabilities. Returns an array of PackageScanResult, one per package. ### `update_cache(packages : Array(Package))` Force refresh all cached data. ## /YAML.md # module YAML The YAML module provides serialization and deserialization of YAML version 1.1 to/from native Crystal data structures, with the additional independent types specified in http://yaml.org/type/ NOTE: To use `YAML`, you must explicitly import it with `require "yaml"` ### Parsing with `#parse` and `#parse_all` `YAML.parse` will return an `Any`, which is a convenient wrapper around all possible YAML core types, making it easy to traverse a complex YAML structure but requires some casts from time to time, mostly via some method invocations. ``` require "yaml" data = YAML.parse <<-YAML --- foo: bar: baz: - qux - fox YAML data["foo"]["bar"]["baz"][1].as_s # => "fox" ``` `YAML.parse` can read from an `IO` directly (such as a file) which saves allocating a string: ``` require "yaml" yaml = File.open("path/to/file.yml") do |file| YAML.parse(file) end ``` ### Parsing with `from_yaml` A type `T` can be deserialized from YAML by invoking `T.from_yaml(string_or_io)`. For this to work, `T` must implement `new(ctx : YAML::PullParser, node : YAML::Nodes::Node)` and decode a value from the given *node*, using *ctx* to store and retrieve anchored values (see `YAML::PullParser` for an explanation of this). Crystal primitive types, `Time`, `Bytes` and `Union` implement this method. `YAML::Serializable` can be used to implement this method for user types. ### Dumping with `YAML.dump` or `#to_yaml` `YAML.dump` generates the YAML representation for an object. An `IO` can be passed and it will be written there, otherwise it will be returned as a string. Similarly, `#to_yaml` (with or without an `IO`) on any object does the same. For this to work, the type given to `YAML.dump` must implement `to_yaml(builder : YAML::Nodes::Builder`). Crystal primitive types, `Time` and `Bytes` implement this method. `YAML::Serializable` can be used to implement this method for user types. ``` yaml = YAML.dump({hello: "world"}) # => "---\nhello: world\n" File.open("foo.yml", "w") { |f| YAML.dump({hello: "world"}, f) } # writes it to the file # or: yaml = {hello: "world"}.to_yaml # => "---\nhello: world\n" File.open("foo.yml", "w") { |f| {hello: "world"}.to_yaml(f) } # writes it to the file ``` ## Types - `YAML::PullParser` (class) ## /YAML/PullParser.md # class YAML::PullParser A pull parser allows parsing a YAML document by events. When creating an instance, the parser is positioned in the first event. To get the event kind invoke `kind`. If the event is a scalar you can invoke `value` to get its **string** value. Other methods like `tag`, `anchor` and `scalar_style` let you inspect other information from events. Invoking `read_next` reads the next event. ## Instance Methods ### `each_in_mapping` Iterates a mapping, yielding on each new entry until the mapping is terminated. ### `each_in_sequence` Iterates a sequence, yielding on each new entry until the sequence is terminated. ### `read_empty_or` ## /agent-files/claude/CLAUDE.md # Shards-Alpha Project Context Shards-alpha is the Crystal language package manager extended with supply-chain compliance tools. It is a drop-in replacement for the upstream `shards` binary, adding security auditing, license compliance, dependency policy enforcement, SBOM generation, change tracking, and a unified compliance reporting system suitable for SOC2 and ISO 27001 audits. ## Key Commands | Command | Description | |---------|-------------| | `shards-alpha install` | Install dependencies from shard.yml, creating or using shard.lock | | `shards-alpha update [shards...]` | Update dependencies and shard.lock | | `shards-alpha build [targets] [opts]` | Build targets defined in shard.yml | | `shards-alpha audit [options]` | Scan dependencies for known vulnerabilities (OSV database) | | `shards-alpha licenses [options]` | List dependency licenses, check SPDX compliance | | `shards-alpha policy [check\|init\|show]` | Manage and enforce dependency policies | | `shards-alpha diff [options]` | Show dependency changes between lockfile states | | `shards-alpha compliance-report [options]` | Generate unified supply-chain compliance report | | `shards-alpha sbom [options]` | Generate Software Bill of Materials (SPDX or CycloneDX) | | `shards-alpha mcp-server [options]` | Start MCP compliance server for AI agent integration | | `shards-alpha assistant [init\|update\|status\|remove]` | Manage Claude Code assistant configuration (skills, agents, settings) | ## Build ```sh crystal build src/shards.cr -o bin/shards-alpha ``` ## Test ```sh # Unit tests crystal spec spec/unit/ # Integration tests crystal spec spec/integration/ # Single test file crystal spec spec/unit/audit_spec.cr ``` ## Format ```sh crystal tool format src/ spec/ ``` ## Key Directories | Directory | Contents | |-----------|----------| | `src/` | Main source files (dependency, lock, config, etc.) | | `src/commands/` | CLI command implementations (audit, licenses, policy, etc.) | | `src/mcp/` | MCP compliance server implementation | | `src/assistant_versions/` | Versioned assistant config files (embedded at compile time) | | `src/compliance/` | Compliance report generation internals | | `spec/unit/` | Unit tests | | `spec/integration/` | Integration tests | | `docs/` | Documentation (compliance guide, plans) | ## Configuration Files | File | Purpose | |------|---------| | `shard.yml` | Project dependency specification | | `shard.lock` | Locked dependency versions with SHA-256 checksums | | `.shards-policy.yml` | Dependency policy rules (allowed hosts, blocked deps, etc.) | | `.shards-audit-ignore` | Suppressed vulnerability advisory IDs with expiry dates | | `.mcp.json` | MCP server configuration for Claude Code integration | | `.claude/.assistant-config.yml` | Assistant config tracking (version, components, checksums) | ## MCP Compliance Server The MCP server (`src/mcp/compliance_server.cr`) exposes 6 compliance tools over JSON-RPC 2.0 (stdio transport): `audit`, `licenses`, `policy_check`, `diff`, `compliance_report`, and `sbom`. It supports MCP protocol version negotiation across versions 2024-11-05, 2025-03-26, 2025-06-18, and 2025-11-25. The server negotiates the highest version both client and server support. Start the server: ```sh shards-alpha mcp-server # stdio mode shards-alpha mcp-server --interactive # manual testing shards-alpha mcp-server init # add to .mcp.json ``` ## Assistant Configuration The `assistant` command (`src/commands/assistant.cr`) manages Claude Code skills, agents, and settings. File contents are embedded at compile time from `src/assistant_versions/` via `{{ run() }}` macro. Key files: - `src/assistant_versions.cr` — Version overlay logic (compile-time embedded) - `src/build_assistant_versions.cr` — Compile-time script that walks version directories - `src/assistant_config.cr` — Install/update/remove logic with modification detection - `src/assistant_config_info.cr` — Tracking YAML class (`.claude/.assistant-config.yml`) To add a new version: create `src/assistant_versions//` with only changed files. The binary picks them up at compile time. ```sh shards-alpha assistant init # Install all components shards-alpha assistant init --no-agents # Skip agents shards-alpha assistant update # Upgrade, preserve local edits shards-alpha assistant status # Show installed version and state shards-alpha assistant remove # Remove tracked files ``` Projects can auto-install via `shard.yml`: ```yaml ai_assistant: auto_install: true ``` ## Language and Style - Written in Crystal (https://crystal-lang.org) - All source must pass `crystal tool format` - Specs use Crystal's built-in `spec` framework - Error handling uses `Shards::Error` and `Shards::ParseError` - CLI option parsing is in `src/cli.cr`; each command is a class in `src/commands/` ## /agent-files/claude/agents/compliance-checker.md --- name: compliance-checker description: Specialized agent for running comprehensive compliance analysis on Crystal projects. Delegates to this agent when the user asks for a full compliance audit, security review, or pre-release check. tools: Bash, Read, Grep, Write model: sonnet maxTurns: 15 --- # Compliance Checker Agent You are a supply-chain compliance specialist for Crystal projects using shards-alpha. Your job is to run a comprehensive compliance analysis and produce a clear, actionable report. ## Procedure ### Step 1: Verify Project Setup Check that the required files exist: ```sh ls shard.yml shard.lock ``` - If `shard.yml` is missing, stop and inform the user this is not a valid Crystal shard project. - If `shard.lock` is missing, run `shards-alpha install` to generate it before proceeding. Also check for an optional policy file: ```sh ls .shards-policy.yml ``` Note whether a policy file exists. If it does not, mention this in your report as a recommendation. ### Step 2: Run Vulnerability Audit ```sh shards-alpha audit --format=json ``` Parse the JSON output. Record: - Total vulnerabilities found - Breakdown by severity (critical, high, medium, low) - Each vulnerability's advisory ID, affected package, affected versions, and description If the command exits with code 1, vulnerabilities were found. Exit code 0 means clean. ### Step 3: Run License Scan ```sh shards-alpha licenses --format=json --detect ``` Parse the JSON output. Record: - Total dependencies scanned - Count with valid SPDX licenses - Count with missing or unrecognized licenses - Any copyleft licenses that may have compatibility concerns ### Step 4: Run Policy Check If `.shards-policy.yml` exists: ```sh shards-alpha policy check --format=json ``` Record: - Number of policy violations (errors and warnings) - Each violation with the rule, dependency, and reason If no policy file exists, skip this step and note the gap. ### Step 5: Generate Compliance Report Compile all findings into a structured summary with these sections: **Executive Summary** - Overall status: PASS, ACTION_REQUIRED, or FAIL - PASS: No vulnerabilities, no policy violations, all licenses valid - ACTION_REQUIRED: Medium-severity findings or warnings - FAIL: Critical/high vulnerabilities, policy errors, or license failures - Total dependency count **Vulnerability Findings** - List each vulnerability grouped by severity (critical first) - Include advisory ID, affected package, and brief description **License Compliance** - List all dependencies with their licenses - Flag any missing or problematic licenses **Policy Compliance** - List any violations with remediation steps - If no policy file exists, recommend creating one with `shards-alpha policy init` **Remediation Steps** For each finding, provide a specific, actionable fix: - Version bumps for vulnerable dependencies - License additions for unlicensed dependencies - Policy file changes for policy violations ### Step 6: Offer Additional Actions After presenting the report, offer the user these options: - Generate a formal compliance report file: `shards-alpha compliance-report --format=html --reviewer=EMAIL` - Generate an SBOM: `shards-alpha sbom` - Create or update the policy file: `shards-alpha policy init` - View dependency changes: `shards-alpha diff` ## Important Notes - Always run commands from the project root directory where `shard.yml` is located. - Present findings in order of severity (most critical first). - Be specific in remediation advice: suggest exact version numbers, exact config changes. - If a scan produces no findings in a category, explicitly state that the category is clean rather than omitting it. ## /agent-files/claude/agents/security-reviewer.md --- name: security-reviewer description: Security-focused agent that analyzes dependencies for vulnerabilities and recommends patches. Delegates to this when the user asks about security posture or vulnerability remediation. tools: Bash, Read, Grep model: sonnet maxTurns: 10 --- # Security Reviewer Agent You are a dependency security analyst for Crystal projects using shards-alpha. Your focus is identifying vulnerabilities, prioritizing them by risk, and recommending specific remediation actions. ## Procedure ### Step 1: Run Vulnerability Audit ```sh shards-alpha audit --format=json ``` Parse the full JSON output to extract every reported vulnerability. If the exit code is 0, report that no known vulnerabilities were found and the dependency tree is currently clean. You may still proceed to check for other security signals. If the exit code is 1, vulnerabilities were found. Continue to the analysis steps. ### Step 2: Parse and Categorize Results For each vulnerability found, extract: - **Advisory ID** (e.g., GHSA-xxxx-yyyy-zzzz or CVE-YYYY-NNNNN) - **Affected dependency** name and installed version - **Severity** level (critical, high, medium, low) - **Summary** description of the vulnerability - **Affected version range** (which versions are vulnerable) - **Fixed version** (if available) Group vulnerabilities by severity, processing critical first, then high, medium, and low. ### Step 3: Prioritize by Risk Rank findings using this priority framework: 1. **Critical severity** — Actively exploitable, remote code execution, data exfiltration. Requires immediate action. 2. **High severity** — Significant security impact, privilege escalation, authentication bypass. Fix within days. 3. **Medium severity** — Limited impact or requires specific conditions. Fix within a sprint. 4. **Low severity** — Informational or theoretical risk. Track and fix at convenience. For each vulnerability, assess: - Is the affected code path actually used by this project? - Is the vulnerability exploitable in the project's deployment context? - Are there known exploits in the wild? ### Step 4: Research Remediation For each vulnerable dependency, check if newer versions fix the issue: ```sh shards-alpha outdated ``` Read `shard.yml` to understand the current version constraints: ```sh cat shard.yml ``` For each vulnerable dependency, determine: - What is the current version constraint in shard.yml? - What is the minimum version that fixes the vulnerability? - Is the fix a patch release (safe to upgrade) or a major version (may have breaking changes)? ### Step 5: Recommend Specific Fixes For each vulnerability, provide one of these remediation paths: **Path A: Version Bump (Preferred)** - State the exact version constraint change needed in `shard.yml` - Example: "Change `github: example/web` version from `~> 1.2.0` to `~> 1.2.5` to pick up the fix in v1.2.5" **Path B: Ignore with Justification** - If the vulnerability is not applicable to this project's usage, recommend adding it to `.shards-audit-ignore` - Provide the exact entry to add, including a reason and an expiry date (typically 90 days out) - Example entry: ```yaml - id: GHSA-xxxx-yyyy-zzzz reason: "Not applicable: we don't use the affected WebSocket code path" expires: 2026-05-15 ``` **Path C: Dependency Replacement** - If the dependency is unmaintained and the vulnerability has no fix, recommend an alternative dependency ### Step 6: Present Security Summary Format your final report as: **Security Posture: [CLEAN | AT RISK | CRITICAL]** - CLEAN: No known vulnerabilities - AT RISK: Medium/low vulnerabilities present - CRITICAL: High/critical vulnerabilities requiring immediate action **Findings Table:** List each vulnerability with: severity, advisory ID, dependency, installed version, fixed version, and recommended action. **Recommended shard.yml Changes:** Show the exact diff of version constraint changes needed. **Ignore Recommendations:** List any advisories that should be added to `.shards-audit-ignore` with justification. ## Important Notes - Never recommend ignoring critical or high severity vulnerabilities without a strong, documented justification. - Always check if the fix introduces breaking changes before recommending a major version bump. - If `shards-alpha audit` fails to run (e.g., network issues), suggest `--offline` mode as a fallback using cached data. - Present findings factually. Do not downplay security risks. ## /agent-files/claude/skills/audit/SKILL.md --- name: audit description: Scan project dependencies for known security vulnerabilities using the OSV database. Use when reviewing dependencies for security issues. allowed-tools: Bash, Read, Grep user-invocable: true argument-hint: [--severity=high] [--offline] --- # Audit Dependencies for Vulnerabilities Run a vulnerability scan against all locked dependencies using the OSV database. ## Steps 1. Verify that `shard.lock` exists in the project root. If it does not, inform the user they need to run `shards-alpha install` first. 2. Run the audit command with the user's requested options: ```sh shards-alpha audit [OPTIONS] ``` Common options to pass through from user arguments: - `--severity=LEVEL` — Filter results to only show vulnerabilities at or above this severity (low, medium, high, critical) - `--format=FORMAT` — Output format: `terminal` (default), `json`, `sarif` - `--fail-above=LEVEL` — Only exit non-zero for vulnerabilities at or above this severity - `--ignore=ID[,ID]` — Comma-separated advisory IDs to suppress - `--ignore-file=PATH` — Path to ignore file (default: `.shards-audit-ignore`) - `--offline` — Use cached vulnerability data only, no network requests - `--update-db` — Force a cache refresh before scanning 3. Interpret the exit code: - Exit 0: No vulnerabilities found (or all filtered/ignored). Report this as a clean scan. - Exit 1: Vulnerabilities found matching the severity threshold. 4. If vulnerabilities are found, summarize the results: - Group findings by severity (critical, high, medium, low) - For each vulnerability, report: advisory ID, affected dependency, affected versions, severity, and summary - Highlight any critical or high severity issues first 5. Provide remediation advice: - Check if newer versions of affected dependencies are available that fix the vulnerability - Suggest specific version bumps in `shard.yml` where applicable - If a vulnerability cannot be fixed by upgrading, suggest adding it to `.shards-audit-ignore` with a reason and expiry date - Mention the `--fail-above` flag for CI pipelines that should only block on critical issues 6. For JSON output (`--format=json`), parse the structured data to provide a more detailed breakdown. For SARIF output (`--format=sarif`), note that this is designed for GitHub Code Scanning integration. ## Example Invocations ```sh # Basic scan shards-alpha audit # Only show high and critical vulnerabilities shards-alpha audit --severity=high # CI-friendly: fail only on critical, output SARIF for GitHub shards-alpha audit --format=sarif --fail-above=critical # Offline scan with cached data shards-alpha audit --offline ``` ## /agent-files/claude/skills/compliance-report/SKILL.md --- name: compliance-report description: Generate comprehensive supply-chain compliance reports. Use before releases or for audit documentation. allowed-tools: Bash, Read, Grep, Write user-invocable: true argument-hint: [--sections=sbom,audit,licenses] [--reviewer=email] --- # Generate Supply-Chain Compliance Report Produce a unified compliance report combining SBOM, vulnerability audit, license compliance, policy evaluation, integrity verification, and change history into a single document suitable for SOC2 and ISO 27001 auditors. ## Steps 1. Verify prerequisites: - `shard.yml` must exist in the project root - `shard.lock` must exist (run `shards-alpha install` if missing) - For policy sections, `.shards-policy.yml` should exist (optional but recommended) 2. Run the compliance report command with the user's requested options: ```sh shards-alpha compliance-report [OPTIONS] ``` Available options: - `--format=FORMAT` — Output format: `json` (default), `html`, `markdown` - `--output=PATH` — Output file path (default: `{project}-compliance-report.{ext}`) - `--sections=LIST` — Comma-separated sections to include (default: `all`) - `--reviewer=EMAIL` — Add reviewer attestation with timestamp to the report - `--since=DATE` — Filter change history to entries after this date - `--sign` — Create a detached GPG signature (`.sig` file) 3. Explain the available sections and their audit framework mappings: | Section | Description | SOC2 Control | ISO 27001 Control | |---------|-------------|--------------|-------------------| | `sbom` | SPDX 2.3 dependency inventory | CC3.2 | A.8.9, A.8.30 | | `audit` | OSV vulnerability scan results | CC7.1 | A.8.8 | | `licenses` | License inventory and compliance | CC3.2 | A.5.19 | | `policy` | Policy rule evaluation results | CC6.1 | A.8.28 | | `integrity` | SHA-256 checksum verification | CC6.1 | A.8.9 | | `changelog` | Dependency change history | CC8.1 | A.8.9 | 4. Interpret the overall status in the report's executive summary: - **PASS** — No vulnerabilities, no policy violations, integrity verified - **ACTION_REQUIRED** — Medium-severity findings or warnings present that need attention - **FAIL** — Critical or high vulnerabilities found, or policy/license failures detected 5. Summarize the report for the user: - Overall compliance status - Total dependency count (direct and transitive) - Vulnerability summary by severity - License compliance status - Policy evaluation results - Integrity verification status 6. Note that generated reports are automatically archived in `.shards/audit/reports/` with timestamps for historical tracking. 7. If the format is HTML, mention it produces a professional print-ready document with color-coded status badges and expandable sections. ## Example Invocations ```sh # Full compliance report in HTML for auditors shards-alpha compliance-report --format=html --reviewer=security@company.com # Quick check with just SBOM and integrity sections shards-alpha compliance-report --sections=sbom,integrity # JSON report for CI artifact archival shards-alpha compliance-report --output=compliance-report.json # Markdown report for documentation shards-alpha compliance-report --format=markdown # Report with GPG signature for tamper evidence shards-alpha compliance-report --format=json --sign ``` ## /agent-files/claude/skills/diff-deps/SKILL.md --- name: diff-deps description: Show dependency changes between lockfile states. Use when reviewing what changed after updates. allowed-tools: Bash, Read, Grep user-invocable: true argument-hint: [--from=HEAD --to=current] --- # Show Dependency Changes Between Lockfile States Compare two states of shard.lock to see what dependencies were added, removed, or updated. ## Steps 1. Verify that `shard.lock` exists in the project root. If it does not, inform the user there is nothing to diff. 2. Run the diff command with the user's requested options: ```sh shards-alpha diff [OPTIONS] ``` Available options: - `--from=REF` — Starting state (default: `HEAD`). Can be a git ref, file path ending in `.lock`, or `current` - `--to=REF` — Ending state (default: `current`). Same ref types as `--from` - `--format=FORMAT` — Output format: `terminal` (default), `json`, `markdown` 3. Interpret the reference types: - `current` — Reads the current `shard.lock` from disk - A git ref (`HEAD`, `main`, `v1.0.0`, a commit SHA) — Extracts `shard.lock` from that point in git history via `git show` - A file path ending in `.lock` — Reads from an arbitrary lockfile on disk 4. Summarize the changes: - **Added dependencies**: New dependencies not present in the "from" state. Report name, version, and source. - **Removed dependencies**: Dependencies present in "from" but absent in "to". Report name and previous version. - **Updated dependencies**: Dependencies present in both states but with different versions. Report name, old version, new version, and whether it was an upgrade or downgrade. - **Unchanged count**: How many dependencies remained the same. 5. Provide context for the changes: - For major version bumps, warn about potential breaking changes - For added dependencies, note if they are transitive (pulled in by another dependency) - For removed dependencies, note if the removal might affect other parts of the project 6. For markdown output (`--format=markdown`), mention this format is useful for including in PR descriptions to document dependency changes. ## Example Invocations ```sh # What changed since the last commit? shards-alpha diff # What changed since a release tag? shards-alpha diff --from=v1.0.0 # Compare two specific lockfiles shards-alpha diff --from=before.lock --to=after.lock # Generate markdown for a PR description shards-alpha diff --from=main --format=markdown # JSON output for tooling shards-alpha diff --format=json ``` ## /agent-files/claude/skills/licenses/SKILL.md --- name: licenses description: List and check dependency licenses for SPDX compliance. Use when auditing license compatibility or checking policy. allowed-tools: Bash, Read, Grep user-invocable: true argument-hint: [--check] [--detect] --- # List and Check Dependency Licenses Audit all locked dependency licenses for SPDX compliance and policy conformance. ## Steps 1. Verify that `shard.lock` exists in the project root. If it does not, inform the user they need to run `shards-alpha install` first. 2. Run the licenses command with the user's requested options: ```sh shards-alpha licenses [OPTIONS] ``` Available options to pass through: - `--format=FORMAT` — Output format: `terminal` (default), `json`, `csv`, `markdown` - `--check` — Exit 1 if any license policy violations are found - `--detect` — Use heuristic detection to identify licenses from LICENSE/COPYING files when shard.yml does not declare one - `--include-dev` — Include development dependencies in the scan - `--policy=PATH` — Path to a license policy YAML file 3. Interpret the output: - Each dependency is listed with its name, version, declared license, and SPDX validity status - SPDX validation checks against 52 common SPDX identifiers and supports compound expressions (AND, OR, WITH operators) 4. Summarize the findings: - Total number of dependencies scanned - Count of dependencies with valid SPDX licenses - Count of dependencies with missing or invalid licenses - Any policy violations if `--check` was used 5. Flag potential issues: - Dependencies with no declared license (legal risk for commercial projects) - Dependencies with non-standard or unrecognized license identifiers - Copyleft licenses (GPL, AGPL) that may be incompatible with proprietary projects - If `--detect` was used, note which licenses were detected heuristically vs declared 6. Provide recommendations: - For missing licenses, suggest the user contact the dependency maintainer or check the repository directly - For policy violations, explain which rule was violated and how to resolve it - For CSV or markdown output, note these formats are useful for legal review or PR descriptions ## Example Invocations ```sh # Basic license listing shards-alpha licenses # Check against policy, fail on violations shards-alpha licenses --check # Detect licenses from LICENSE files when not declared shards-alpha licenses --detect # Generate CSV for legal team review shards-alpha licenses --format=csv # Full scan including dev dependencies with detection shards-alpha licenses --detect --include-dev --format=json ``` ## /agent-files/claude/skills/policy-check/SKILL.md --- name: policy-check description: Check dependencies against policy rules in .shards-policy.yml. Use when verifying compliance before releases. allowed-tools: Bash, Read, Grep, Write user-invocable: true argument-hint: [--strict] --- # Check Dependencies Against Policy Rules Evaluate all locked dependencies against the rules defined in `.shards-policy.yml`. ## Steps 1. Check if `.shards-policy.yml` exists in the project root: - If it exists, read it to understand the active policy rules before running the check. - If it does not exist, ask the user if they want to create one with `shards-alpha policy init`, which generates a starter policy file. 2. Run the policy check with the user's requested options: ```sh shards-alpha policy check [OPTIONS] ``` Available options: - `--strict` — Treat warnings as errors (useful for CI gates) - `--format=FORMAT` — Output format: `terminal` (default), `json` Other policy subcommands: - `shards-alpha policy init` — Create a starter `.shards-policy.yml` - `shards-alpha policy show` — Display a summary of the current policy 3. Interpret the results: - **Error violations** block installation: blocked dependencies, denied sources, minimum version failures - **Warning violations** are displayed but do not block: missing licenses, postinstall script auditing 4. Summarize the findings: - Total rules evaluated - Number of errors (blocking violations) - Number of warnings (non-blocking violations) - List each violation with the dependency name, rule that was violated, and the reason 5. For each violation, suggest a fix: - **Blocked dependency**: Remove it from shard.yml or update the policy to allow it with a documented reason - **Disallowed source host**: Move the dependency to an allowed host or add the host to `rules.sources.allowed_hosts` - **Disallowed organization**: Add the org to `rules.sources.allowed_orgs` for that host - **Minimum version failure**: Update the dependency version in shard.yml to meet the minimum - **Missing license**: Add a license to the dependency's shard.yml or set `rules.security.require_license: false` - **Postinstall script warning**: Review the script for safety, then either allow it or set `rules.security.block_postinstall: true` to block 6. If the user wants to modify the policy, offer to edit `.shards-policy.yml` directly with the needed changes. ## Policy File Structure The policy file `.shards-policy.yml` supports these rule categories: - `rules.sources` — Allowed hosts, allowed organizations, deny path dependencies - `rules.dependencies` — Blocked dependencies with reasons, minimum version requirements - `rules.security` — Require licenses, block/audit postinstall scripts - `rules.custom` — Regex patterns to allow or block dependency names ## Example Invocations ```sh # Basic policy check shards-alpha policy check # Strict mode for CI (warnings become errors) shards-alpha policy check --strict # JSON output for tooling shards-alpha policy check --format=json # Create a starter policy shards-alpha policy init # View current policy summary shards-alpha policy show ``` ## /agent-files/claude/skills/sbom/SKILL.md --- name: sbom description: Generate a Software Bill of Materials (SBOM) in SPDX or CycloneDX format. Use for supply-chain transparency. allowed-tools: Bash, Read user-invocable: true argument-hint: [--format=spdx|cyclonedx] --- # Generate Software Bill of Materials (SBOM) Produce a complete inventory of all project dependencies in an industry-standard SBOM format. ## Steps 1. Verify that `shard.lock` exists in the project root. If it does not, inform the user they need to run `shards-alpha install` first to resolve and lock dependencies. 2. Run the SBOM generation command with the user's requested options: ```sh shards-alpha sbom [OPTIONS] ``` Available options: - `--format=FORMAT` — SBOM format: `spdx` (default) or `cyclonedx` - `--output=FILE` — Output file path (default: `{project}-sbom.spdx.json` or `{project}-sbom.cdx.json`) - `--include-dev` — Include development dependencies in the SBOM 3. Explain the two supported formats: **SPDX 2.3 (default)**: - Industry standard maintained by the Linux Foundation - Required by many government procurement policies (e.g., US Executive Order 14028) - Includes package identifiers, licenses, relationships, and checksums - Output is SPDX 2.3 JSON format **CycloneDX 1.6**: - OWASP standard focused on security and risk analysis - Widely supported by vulnerability scanning tools - Includes component inventory, licenses, and dependency graph - Output is CycloneDX 1.6 JSON format 4. Summarize the generated SBOM: - Total number of components listed - Document creation timestamp and tool information - Note the output file location - Mention whether development dependencies were included or excluded 5. Provide context on SBOM usage: - SBOMs are increasingly required for software supply chain transparency - They can be submitted to customers, auditors, or vulnerability scanning services - Both formats are machine-readable and can be ingested by tools like Grype, Trivy, or OWASP Dependency-Track ## Example Invocations ```sh # Generate SPDX SBOM (default) shards-alpha sbom # Generate CycloneDX SBOM shards-alpha sbom --format=cyclonedx # Custom output path shards-alpha sbom --output=artifacts/sbom.spdx.json # Include development dependencies shards-alpha sbom --include-dev # CycloneDX with dev deps and custom output shards-alpha sbom --format=cyclonedx --include-dev --output=full-sbom.cdx.json ``` ## /agent-files/claude/skills/shards-cli/SKILL.md --- name: shards-cli description: Crystal Shards package manager CLI reference. Provides guidance on shard.yml format, dependency management, installation, building, and AI docs distribution. user-invocable: false --- # Crystal Shards CLI Shards is the dependency manager for Crystal. It reads `shard.yml` to resolve, install, and update dependencies from source repositories. ## Common Workflows ### Install dependencies ``` shards install # Install from shard.yml, using shard.lock if present shards install --production # Frozen + without development dependencies shards install --skip-ai-docs # Skip AI documentation installation ``` ### Update dependencies ``` shards update # Update all to latest compatible versions shards update kemal # Update only kemal ``` ### Build targets ``` shards build # Build all targets shards build my_app # Build specific target shards build --release # Build with --release flag ``` ### Other commands ``` shards check # Verify all dependencies are installed shards list # List installed dependencies shards list --tree # List with dependency tree shards outdated # Show outdated dependencies shards prune # Remove unused dependencies from lib/ shards version # Print shard version shards init # Generate a new shard.yml shards lock # Lock dependencies without installing ``` ### AI docs management ``` shards ai-docs # Show installed AI docs status shards ai-docs diff # Diff local changes vs upstream shards ai-docs reset # Reset to upstream version shards ai-docs update [shard] # Force re-install AI docs shards ai-docs merge-mcp # Merge shard MCP configs into .mcp.json ``` ### Postinstall scripts ``` shards run-script # Run all pending postinstall scripts shards run-script # Run postinstall for a specific shard ``` ### Documentation generation ``` shards docs # Generate themed docs with AI buttons shards docs --skip-ai-buttons # Without AI assistant buttons shards docs -o my_docs # Custom output directory ``` Theme your docs by creating `docs-theme/style.css` with CSS variable overrides. ### SBOM generation ``` shards sbom # Generate SPDX 2.3 JSON (default) shards sbom --format=cyclonedx # Generate CycloneDX 1.6 JSON shards sbom --output=custom.json # Custom output path shards sbom --include-dev # Include development dependencies ``` ## Key Flags | Flag | Description | |------|-------------| | `--frozen` | Strictly install locked versions from shard.lock | | `--without-development` | Skip development dependencies | | `--production` | Same as `--frozen --without-development` | | `--skip-postinstall` | Skip postinstall scripts | | `--skip-executables` | Skip executable installation | | `--skip-ai-docs` | Skip AI documentation installation | | `--local` | Use local cache only, don't fetch | | `--jobs=N` | Parallel downloads (default: 8) | ## Important Files | File | Purpose | |------|---------| | `shard.yml` | Dependency specification | | `shard.lock` | Locked dependency versions | | `lib/` | Installed dependencies | | `lib/.shards.info` | Installation state tracker | | `.claude/.ai-docs-info.yml` | AI docs installation tracker | | `.mcp-shards.json` | MCP servers from dependencies | | `docs-theme/style.css` | Custom CSS theme for generated docs | ## Reference - [shard.yml format](reference/shard-yml-format.md) - [All CLI commands](reference/commands.md) - [AI docs distribution guide](reference/ai-docs-guide.md) ## /agent-files/claude/skills/shards-cli/reference/ai-docs-guide.md # AI Documentation Distribution Guide ## Overview Shards can distribute AI coding agent documentation alongside library code. When you run `shards install`, AI docs from dependencies are automatically installed into your project's `.claude/` directory. This enables library publishers to ship skills, context docs, agents, and MCP configurations so that AI coding assistants can effectively help developers use their libraries. ## How It Works ### Auto-Detection Shards automatically detects these locations in dependencies: | Source in shard | What it is | |-----------------|------------| | `.claude/skills//` | Claude Code skills | | `.claude/agents/.md` | Agent definitions | | `.claude/commands/.md` | Slash commands | | `CLAUDE.md` | General AI context | | `AGENTS.md` | Agent specifications | | `.mcp.json` | MCP server configs | ### Installation Mapping Files are namespaced by shard name to avoid conflicts: | Source | Destination | |--------|-------------| | `.claude/skills//` | `.claude/skills/--/` | | `.claude/agents/.md` | `.claude/agents/--.md` | | `.claude/commands/.md` | `.claude/commands/:.md` | | `CLAUDE.md` (no skills) | `.claude/skills/--docs/SKILL.md` (as passive skill) | | `CLAUDE.md` (with skills) | `.claude/skills/--docs/reference/CLAUDE.md` | | `AGENTS.md` | `.claude/skills/--docs/reference/AGENTS.md` | | `.mcp.json` | Merged into `.mcp-shards.json` | ### CLAUDE.md Conversion When a shard ships `CLAUDE.md` but no explicit skills, it's automatically wrapped as a passive skill with frontmatter: ```markdown --- name: --docs description: Documentation and usage context for the Crystal library. user-invocable: false --- ``` ## Publishing AI Docs ### Recommended: Ship Skills Create `.claude/skills/` in your shard: ``` your_shard/ .claude/ skills/ getting-started/ SKILL.md api-reference/ SKILL.md reference/ endpoints.md src/ shard.yml ``` Each `SKILL.md` needs frontmatter: ```markdown --- name: getting-started description: How to get started with your_shard user-invocable: false --- # Getting Started ... ``` ### Simple: Ship CLAUDE.md For basic documentation, just add a `CLAUDE.md` at your shard root. It will be auto-converted to a passive skill. ### Optional: shard.yml Configuration The `ai_docs` section is optional and only needed for customization: ```yaml ai_docs: include: - docs/claude/advanced_guide.md exclude: - .claude/skills/internal_dev_tool/ ``` ### Security These files are always skipped: - `.claude/settings.json` - `.claude/settings.local.json` ## User Customization Users can modify installed AI docs. The system tracks changes: - **Unmodified files**: Auto-updated on `shards update` - **Modified files**: Preserved on update, `.upstream` copy saved for comparison - **View changes**: `shards ai-docs diff ` - **Reset to upstream**: `shards ai-docs reset ` - **Force update**: `shards ai-docs update ` ## MCP Server Distribution Shards with `.mcp.json` have their servers merged into `.mcp-shards.json`: - Server names are namespaced: `/` - Relative command paths are rewritten to `lib//...` - Run `shards ai-docs merge-mcp` to merge into your `.mcp.json` ## Disabling ``` shards install --skip-ai-docs ``` ## /agent-files/claude/skills/shards-cli/reference/commands.md # Shards CLI Commands Reference ## shards install Install dependencies from `shard.yml`. Creates `shard.lock` if it doesn't exist, otherwise uses locked versions. ``` shards install [options] ``` Behavior: - Conservative: prefers locked versions when possible - Installs in reverse topological order (transitive deps first) - Runs postinstall scripts after installation - Creates `shard.lock` on first run - Raises `LockConflict` if dependencies changed in frozen mode ## shards update Update dependencies to latest compatible versions. ``` shards update [shard_names...] [options] ``` - `shards update` -- update all dependencies - `shards update kemal pg` -- update only kemal and pg - Always rewrites `shard.lock` ## shards build Build targets defined in `shard.yml`. ``` shards build [targets...] [-- build_options...] ``` - `shards build` -- build all targets - `shards build my_app -- --release` -- build with Crystal flags - Auto-runs `shards install` if dependencies missing ## shards run Build and run a target. ``` shards run [target] [-- run_options...] ``` ## shards check Verify all dependencies are installed and match `shard.lock`. ``` shards check ``` ## shards list List installed dependencies. ``` shards list [--tree] ``` ## shards lock Lock dependencies without installing. ``` shards lock [--print] [--update [shards...]] ``` ## shards outdated Show outdated dependencies. ``` shards outdated [--pre] ``` ## shards prune Remove unused dependencies from `lib/`. Also cleans up AI docs for removed shards. ``` shards prune ``` ## shards init Generate a new `shard.yml`. ``` shards init ``` ## shards version Print the shard version from `shard.yml`. ``` shards version [path] ``` ## shards run-script Run postinstall scripts that are pending or changed. ``` shards run-script [shard_names...] ``` - `shards run-script` -- run all pending scripts - `shards run-script my_shard` -- run for specific shard Postinstall scripts only auto-run on first install. If the script changes in an update, you'll see a warning and must run it manually. ## shards ai-docs Manage AI documentation installed from dependencies. ``` shards ai-docs [subcommand] [args...] ``` ### Subcommands | Subcommand | Description | |------------|-------------| | `status` (default) | Show installed AI docs status | | `diff ` | Show differences between local and upstream | | `reset [file]` | Reset to upstream version | | `update [shard]` | Force re-install (overwrite local changes) | | `merge-mcp` | Merge `.mcp-shards.json` into `.mcp.json` | ## shards docs Generate project documentation with theming and AI assistant integration. ``` shards docs [options] ``` Wraps `crystal docs` and post-processes the output: - Injects CSS custom properties for theming - Applies `docs-theme/style.css` if present - Adds "Open in Claude/ChatGPT/Gemini" buttons to each page - Generates parallel `.md` files for AI consumption ### Options All `crystal docs` options are passed through. Additional options: | Option | Description | |--------|-------------| | `--skip-ai-buttons` | Don't inject AI assistant buttons | ### Theming Create `docs-theme/style.css` in your project root to override CSS variables: ```css :root { --sidebar-bg: #1a1a2e; --accent-primary: #e94560; --type-name-color: #e94560; --link-color: #0f3460; } ``` ## shards sbom Generate a Software Bill of Materials (SBOM) for compliance auditing. ``` shards sbom [options] ``` Reads `shard.lock` and each dependency's `shard.yml` to produce a machine-readable SBOM in SPDX 2.3 or CycloneDX 1.6 JSON format. ### Options | Option | Description | |--------|-------------| | `--format=spdx` | SPDX 2.3 JSON output (default) | | `--format=cyclonedx` | CycloneDX 1.6 JSON output | | `--output=FILE` | Override default output path | | `--include-dev` | Include development dependencies | ### Default output filenames - SPDX: `.spdx.json` - CycloneDX: `.cdx.json` Package URLs (purls) are generated from resolver sources: GitHub, GitLab, Bitbucket, and Codeberg sources use their respective purl types; other git sources use `pkg:generic`. ## /agent-files/claude/skills/shards-cli/reference/shard-yml-format.md # shard.yml Format Reference ## Required Fields ```yaml name: my_shard # Shard name (must match repo name convention) version: 1.0.0 # Semantic version ``` ## Optional Fields ```yaml description: | Multi-line description of the shard. authors: - Author Name crystal: ">= 1.0.0, < 2.0.0" # Crystal version constraint license: MIT repository: https://github.com/user/repo documentation: https://user.github.io/repo ``` ## Dependencies ```yaml dependencies: kemal: github: kemalcr/kemal version: ~> 1.0 # >= 1.0.0, < 2.0.0 my_lib: git: https://example.com/repo.git branch: main local_dep: path: ../local_dep development_dependencies: ameba: github: crystal-ameba/ameba version: ~> 1.5 ``` ### Dependency Sources | Key | Description | |-----|-------------| | `github: user/repo` | GitHub repository | | `gitlab: user/repo` | GitLab repository | | `bitbucket: user/repo` | Bitbucket repository | | `git: ` | Any git repository URL | | `hg: ` | Mercurial repository | | `fossil: ` | Fossil repository | | `path: ` | Local path dependency | ### Version Constraints | Pattern | Meaning | |---------|---------| | `*` | Any version | | `1.0.0` | Exact version | | `>= 1.0.0` | Minimum version | | `~> 1.0` | >= 1.0.0, < 2.0.0 | | `~> 1.0.3` | >= 1.0.3, < 1.1.0 | | `>= 1.0, < 2.0` | Range | ### Branch/Tag Refs ```yaml dependencies: my_shard: github: user/repo branch: develop # Track a branch # or tag: v1.0.0 # Pin to a tag # or commit: abc123 # Pin to a commit ``` ## Build Targets ```yaml targets: my_app: main: src/my_app.cr cli_tool: main: src/cli.cr ``` ## Executables ```yaml executables: - my_app - cli_tool ``` Executables are installed from `bin/` in the shard directory. ## Libraries (C bindings) ```yaml libraries: libsqlite3: ">= 3.0.0" libpcre2-8: "*" ``` ## Scripts ```yaml scripts: postinstall: make ext ``` Postinstall scripts run after first installation. Changed scripts require `shards run-script ` to re-execute. ## AI Documentation (optional) ```yaml ai_docs: include: # Extra files beyond auto-detected - docs/claude/custom_guide.md exclude: # Skip specific auto-detected files - .claude/skills/internal_dev_tool/ ``` The `ai_docs` section is optional. By default, shards auto-detects: - `.claude/skills/` directories - `.claude/agents/` files - `.claude/commands/` files - `CLAUDE.md` at shard root - `AGENTS.md` at shard root - `.mcp.json` at shard root ## /agent-files/index.md # Agent Files Published agent-oriented resources that ship alongside the generated API documentation. - **agent**: [claude/agents/compliance-checker.md](claude/agents/compliance-checker.md) - **agent**: [claude/agents/security-reviewer.md](claude/agents/security-reviewer.md) - **context**: [claude/CLAUDE.md](claude/CLAUDE.md) - **mcp_config**: [mcp.json](mcp.json) - **settings**: [claude/settings.json](claude/settings.json) - **skill**: [claude/skills/audit/SKILL.md](claude/skills/audit/SKILL.md) - **skill**: [claude/skills/compliance-report/SKILL.md](claude/skills/compliance-report/SKILL.md) - **skill**: [claude/skills/diff-deps/SKILL.md](claude/skills/diff-deps/SKILL.md) - **skill**: [claude/skills/licenses/SKILL.md](claude/skills/licenses/SKILL.md) - **skill**: [claude/skills/policy-check/SKILL.md](claude/skills/policy-check/SKILL.md) - **skill**: [claude/skills/sbom/SKILL.md](claude/skills/sbom/SKILL.md) - **skill**: [claude/skills/shards-cli/SKILL.md](claude/skills/shards-cli/SKILL.md) - **skill**: [claude/skills/shards-cli/reference/ai-docs-guide.md](claude/skills/shards-cli/reference/ai-docs-guide.md) - **skill**: [claude/skills/shards-cli/reference/commands.md](claude/skills/shards-cli/reference/commands.md) - **skill**: [claude/skills/shards-cli/reference/shard-yml-format.md](claude/skills/shards-cli/reference/shard-yml-format.md) ## /index.md # Ashard # Ashard [](https://github.com/crystal-lang/shards/actions?query=workflow:CI+event:push+branch:master) Ashard is the public name for this Shards-compatible fork of the [Crystal language](https://crystal-lang.org) dependency manager. The name is meant to read naturally as "a shard": tooling that wraps around a shard, stays compatible with the `Shards` ecosystem, and adds the agent-first workflows we want for Amber v2 and the broader amberverse. We may personify the name more in the future as the Amber v2 tool family takes shape, but the current promise is simple: Ashard should still feel like home to anyone who already knows Shards. ## Usage Crystal applications and libraries are expected to have a `shard.yml` file at their root looking like this: ``` name: amberverse_app version: 0.1.0 dependencies: amber_support: path: vendors/amber_support development_dependencies: ashard_spec: path: tools/ashard_spec license: MIT ``` When libraries are installed from Git repositories, the repository is expected to have version tags following a [semver](http://semver.org/)-like format, prefixed with a `v`. Examples: `v1.2.3`, `v2.0.0-rc1` or `v2017.04.1`. Please see the [SPEC](docs/shard.yml.adoc) for more details about the `shard.yml` format. ## Install Upstream Shards is usually distributed with Crystal itself. This fork is currently distributed as `shards-alpha` while the public product name remains Ashard. You can download a source tarball from the same page (or clone the repository) then run `make release=1`and copy `bin/shards-alpha` into your `PATH`. For example `/usr/local/bin`. You are now ready to create a `shard.yml` for your projects (see details in [SPEC](docs/shard.yml.adoc)). You can type `shards-alpha init` to have an example `shard.yml` file created for your project. Run `shards-alpha install` to install your dependencies, which will lock your dependencies into a `shard.lock` file. You should check both `shard.yml` and `shard.lock` into version control, so further `shards-alpha install` will always install locked versions, achieving reproducible installations across computers. Run `shards-alpha --help` to list other commands with their options. Happy Hacking! ## Public Name The public name for this additive fork is Ashard. For the current release-candidate period, the shipped binary and package names remain `shards-alpha` so existing installs and automation keep working. The product story we should publish is: - Ashard is the public project name - `shards-alpha` is the current compatibility-preserving binary/package name More specifically: - Ashard is intended to read as "a shard" in ordinary English - The name signals tooling that sits around a shard instead of replacing the shard ecosystem with a separate one - The codebase still exposes the `Shards` namespace because compatibility is the contract - Over time we may personify the name more, alongside the rest of the Amber v2 tooling family, for people building inside the amberverse For the docs publishing story, see [docs/crystal-docs-gap-analysis.md](docs/crystal-docs-gap-analysis.md). It explains what Crystal Docs already provides and what Ashard adds on top. ## Compatibility Promise This repository has two operating modes: - `master` mirrors upstream `crystal-lang/shards` - `alpha` carries additive tooling currently distributed as `shards-alpha` The goal is not to replace core Shards behavior. The goal is to stay compatible with normal `shards` dependency-management workflows while layering additional tooling on top. We now validate that promise against `amber_cli` before treating upstream syncs or release-facing changes as safe. See [docs/upstream-compatibility.md](docs/upstream-compatibility.md) for the local and CI workflow, including `make compatibility`. ## Ashard Features Ashard currently ships as the `shards-alpha` binary and extends the standard Crystal dependency manager with features for AI-assisted development. It distributes AI documentation and MCP server configurations alongside library code, so consuming projects get everything they need from `shards-alpha install`. ### AI Documentation Distribution Shard authors can ship AI context files (`CLAUDE.md`, skills, agents, commands) that are automatically installed into the consumer's `.claude/` directory with shard-namespaced paths. ``` shards-alpha install # AI docs are installed alongside dependencies shards-alpha ai-docs # Check status of installed AI documentation ``` Auto-detected locations in each dependency: | Shard path | Installed as | |---|---| | `.claude/skills/<name>/` | `.claude/skills/<shard>--<name>/` | | `.claude/agents/<name>.md` | `.claude/agents/<shard>--<name>.md` | | `.claude/commands/<name>.md` | `.claude/commands/<shard>:<name>.md` | | `CLAUDE.md` | `.claude/skills/<shard>--docs/SKILL.md` | | `AGENTS.md` | `.claude/skills/<shard>--docs/reference/AGENTS.md` | | `.mcp.json` | Merged into `.mcp-shards.json` | #### Version tracking and update safety Every installed AI doc file is tracked in `.claude/.ai-docs-info.yml` with: - The dependency version from `shard.lock` (e.g., `kemal: 1.3.0`) - A dual-checksum per file: the upstream checksum (as shipped by the shard) and the installed checksum (as it exists on disk) When you run `shards update` and a dependency version changes: - Unmodified files (checksums match) are silently updated to the new version - Locally modified files (checksums differ) are preserved — the new upstream version is saved as `<file>.upstream` so you can merge manually This means you can safely customize AI docs from your dependencies without losing changes on update. Use `shards-alpha ai-docs diff <shard>` to compare your modifications against upstream, or `shards-alpha ai-docs reset <shard>` to discard changes and restore the original. ### MCP Server Distribution & Lifecycle Shards that ship `.mcp.json` files have their MCP server configurations merged into a project-level `.mcp-shards.json` during install. Server names are namespaced as `<shard>/<server>` and paths are rewritten automatically. ``` shards-alpha mcp # Show server status shards-alpha mcp start # Start all MCP servers shards-alpha mcp stop # Stop all MCP servers shards-alpha mcp restart # Restart servers shards-alpha mcp logs # Tail server logs ``` ### Postinstall Script Tracking Postinstall scripts are tracked by content hash. Changed scripts emit a warning instead of running automatically, requiring explicit approval: ``` shards-alpha run-script # Run all pending postinstall scripts shards-alpha run-script # Run for a specific shard ``` ### SBOM Generation Generate a Software Bill of Materials for your project's dependency tree: ``` shards-alpha sbom # SPDX 2.3 JSON (default) shards-alpha sbom --format=cyclonedx # CycloneDX 1.6 JSON ``` ### Documentation Generation Generate Crystal API documentation with optional theming: ``` shards-alpha docs ``` ### For Shard Authors To distribute AI docs and MCP servers with your shard, add any of: - `CLAUDE.md` — General AI context for your library - `.claude/skills/<name>/SKILL.md` — Specific AI workflows - `.mcp.json` — MCP server configurations - `ai_docs` section in `shard.yml` — Fine-grained include/exclude control See [`examples/`](examples/) for a complete walkthrough with a working demo project. ### Claude Code Assistant Setup Set up Claude Code with compliance skills, agents, and settings for your project in one command: ``` shards-alpha assistant init # Install skills, agents, settings, and MCP config ``` This creates: | What | Files | |------|-------| | Skills (6) | `/audit`, `/licenses`, `/policy-check`, `/diff-deps`, `/compliance-report`, `/sbom` | | Agents (2) | `compliance-checker`, `security-reviewer` | | Settings | `.claude/settings.json` (pre-approved compliance commands) | | Context | `.claude/CLAUDE.md` (project overview for Claude) | | MCP server | `.mcp.json` entry for the compliance MCP server | A tracking file (`.claude/.assistant-config.yml`) records the installed version, enabled components, and per-file checksums so upgrades can detect and preserve your local modifications. #### Managing the assistant config ``` shards-alpha assistant status # Show version, components, modified files shards-alpha assistant update # Upgrade to latest (preserves local edits) shards-alpha assistant update --dry-run # Preview what would change shards-alpha assistant remove # Remove all tracked files ``` #### Selective installation Skip components you don't need: ``` shards-alpha assistant init --no-agents # Skip agent definitions shards-alpha assistant init --no-mcp # Skip .mcp.json configuration shards-alpha assistant init --no-skills # Skip skill files shards-alpha assistant init --no-settings # Skip settings.json and CLAUDE.md ``` #### Automatic setup via shard.yml Projects can opt in to automatic assistant configuration during `shards-alpha install` by adding an `ai_assistant` section to `shard.yml`: ``` ai_assistant: auto_install: true ``` When enabled, `shards-alpha install` will: - Run `assistant init` if no assistant config exists - Run `assistant update` if the installed version is older than the binary Skip auto-configuration with `--skip-ai-assistant`. #### Upgrading from mcp-server init If you previously used `shards-alpha mcp-server init` to set up skills and agents, running `assistant init` will detect the existing files, adopt them into the tracking system, and create any missing files. Your local modifications are preserved. ## Supply Chain Compliance Ashard includes a suite of supply chain security tools, currently distributed through `shards-alpha`, designed for SOC2 and ISO 27001 compliance. These commands can be used individually or combined into a unified compliance report. For detailed usage, examples, and CI/CD integration patterns, see the [Compliance Guide](docs/compliance-guide.md). ### Vulnerability Audit Scan locked dependencies against the [OSV](https://osv.dev/) vulnerability database: ``` shards-alpha audit # Colored terminal output shards-alpha audit --format=json # Machine-readable JSON shards-alpha audit --format=sarif # SARIF 2.1.0 for GitHub Code Scanning shards-alpha audit --severity=high # Only show high/critical shards-alpha audit --fail-above=critical # Exit 1 only for critical vulns shards-alpha audit --ignore=GHSA-xxxx # Suppress specific advisories shards-alpha audit --offline # Use cached data only ``` Suppressions can be managed in `.shards-audit-ignore`: ``` - id: GHSA-xxxx-yyyy-zzzz reason: "Not applicable: we don't use the affected code path" expires: 2026-06-01 ``` ### Integrity Verification Every `shards-alpha install` and `shards-alpha update` records SHA-256 checksums in `shard.lock`. Subsequent installs verify that installed files match. ``` shards-alpha install # Checksums computed and verified automatically shards-alpha install --skip-verify # Bypass verification (logs a warning) ``` Tampered dependencies produce a clear error: ``` E: Checksum mismatch for web: expected sha256:abc123... got sha256:def456... ``` ### License Compliance List licenses for all locked dependencies with optional policy enforcement: ``` shards-alpha licenses # Colored table shards-alpha licenses --format=json # Machine-readable JSON shards-alpha licenses --format=csv # CSV export shards-alpha licenses --format=markdown # Markdown table shards-alpha licenses --detect # Heuristic detection from LICENSE files shards-alpha licenses --check # Exit 1 on policy violations shards-alpha licenses --policy=path.yml # Use custom license policy ``` ### Dependency Policy Define and enforce rules about what dependencies are allowed in your project. Create a `.shards-policy.yml` file: ``` shards-alpha policy init # Create a starter policy file shards-alpha policy check # Check dependencies against policy shards-alpha policy show # Display current policy summary ``` Policy rules include source host restrictions, blocked dependencies, minimum version requirements, and postinstall script controls. Policies are automatically enforced during `shards-alpha install` and `shards-alpha update` when a `.shards-policy.yml` file is present. ### Change Audit Trail Compare dependency states between lockfile versions: ``` shards-alpha diff # Compare HEAD vs current shard.lock shards-alpha diff --from=HEAD --to=current # Same as above (explicit) shards-alpha diff --from=v1.0.0 # Compare against a git tag shards-alpha diff --from=old.lock # Compare against a saved lockfile shards-alpha diff --format=json # Machine-readable output shards-alpha diff --format=markdown # Markdown table for PR descriptions ``` An audit log is automatically maintained at `.shards/audit/changelog.json` with timestamped entries for every `install` and `update` that modifies the lock file. ### Compliance Report Generate a unified report combining all compliance data into a single document suitable for auditors: ``` shards-alpha compliance-report # JSON (default) shards-alpha compliance-report --format=html # Professional HTML report shards-alpha compliance-report --format=markdown # Markdown report shards-alpha compliance-report --output=report.json # Custom output path shards-alpha compliance-report --sections=sbom,integrity # Only specific sections shards-alpha compliance-report --reviewer=security@co.com # Add attestation ``` The report aggregates SBOM data, vulnerability findings, license inventory, policy compliance status, integrity verification, and change history into a single document with an executive summary and overall pass/fail status. Reports are automatically archived to `.shards/audit/reports/`. ## Developers ### Requirements These requirements are only necessary for compiling Ashard. - Crystal Please refer to [https://crystal-lang.org/install/](https://crystal-lang.org/install/) for instructions for your operating system. - libyaml On Debian/Ubuntu Linux you may install the `libyaml-dev` package. On Mac OS X you may install it using homebrew with `brew install libyaml` then make sure to have `/usr/local/lib` in your `LIBRARY_PATH` environment variable (eg: `export LIBRARY_PATH="/usr/local/lib:$LIBRARY_PATH"`). Please adjust the path per your Homebrew installation. - [asciidoctor](https://asciidoctor.org/) Needed for building manpages. ### Getting started It is strongly recommended to use `make` for building Ashard and developing it. The [`Makefile`](./Makefile) contains recipes for compiling and testing. Run `make bin/shards-alpha` to build the binary. - `release=1` for a release build (applies optimizations) - `static=1` for static linking (only works with musl-libc) - `debug=1` for full symbolic debug info Run `make install` to install the binary. Target path can be adjusted with `PREFIX` (default: `PREFIX=/usr/bin`). Run `make test` to run the test suites: - `make test_unit` runs unit tests (`./spec/unit`) - `make test_integration` runs integration tests (`./spec/integration`) on `bin/shards-alpha` Run `make docs` to build the manpages. ### Devenv This repository contains a configuration for [devenv.sh](https://devenv.sh) which makes it easy to setup a reproducible environment with all necessary tools for building and testing. - Checkout the repository - Run `devenv shell` to get a shell with development environment A hook for [automatic shell activation](https://devenv.sh/automatic-shell-activation/) is also included. If you have `direnv` installed, the devenv environment loads automatically upon entering the repo folder. ## License Licensed under the Apache License, Version 2.0. See [LICENSE](./LICENSE) for details. ## /toplevel.md # Top Level Namespace - Ashard # Top Level Namespace ## Defined in: ## Method Summary - [walk_files(dir : String) : Array(String)](#walk_files%28dir%3AString%29%3AArray%28String%29-class-method) Recursively collect all files (including those in dot-directories) ## Method Detail def walk_files(dir : String) : Array(String) [#](#walk_files%28dir%3AString%29%3AArray%28String%29-class-method) Recursively collect all files (including those in dot-directories) [[View source](https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/build_assistant_versions.cr#L5)]