{"repository_name":"Ashard","body":"# Ashard\n\n[![CI](https://github.com/crystal-lang/shards/workflows/CI/badge.svg)](https://github.com/crystal-lang/shards/actions?query=workflow%3ACI+event%3Apush+branch%3Amaster)\n\nAshard is the public name for this Shards-compatible fork of the\n[Crystal language](https://crystal-lang.org) dependency manager.\n\nThe name is meant to read naturally as \"a shard\": tooling that wraps around a\nshard, stays compatible with the `Shards` ecosystem, and adds the agent-first\nworkflows we want for Amber v2 and the broader amberverse. We may personify the\nname more in the future as the Amber v2 tool family takes shape, but the\ncurrent promise is simple: Ashard should still feel like home to anyone who\nalready knows Shards.\n\n## Usage\n\nCrystal applications and libraries are expected to have a `shard.yml` file\nat their root looking like this:\n\n```yaml\nname: amberverse_app\nversion: 0.1.0\n\ndependencies:\n  amber_support:\n    path: vendors/amber_support\n\ndevelopment_dependencies:\n  ashard_spec:\n    path: tools/ashard_spec\n\nlicense: MIT\n```\n\nWhen libraries are installed from Git repositories, the repository is expected\nto have version tags following a [semver](http://semver.org/)-like format,\nprefixed with a `v`. Examples: `v1.2.3`, `v2.0.0-rc1` or `v2017.04.1`.\n\nPlease see the [SPEC](docs/shard.yml.adoc) for more details about the\n`shard.yml` format.\n\n\n## Install\n\nUpstream Shards is usually distributed with Crystal itself. This fork is\ncurrently distributed as `shards-alpha` while the public product name remains\n**Ashard**.\n\nYou can download a source tarball from the same page (or clone the repository)\nthen run `make release=1`and copy `bin/shards-alpha` into your `PATH`. For\nexample `/usr/local/bin`.\n\nYou are now ready to create a `shard.yml` for your projects (see details in\n[SPEC](docs/shard.yml.adoc)). You can type `shards-alpha init` to have an example\n`shard.yml` file created for your project.\n\nRun `shards-alpha install` to install your dependencies, which will lock your\ndependencies into a `shard.lock` file. You should check both `shard.yml` and\n`shard.lock` into version control, so further `shards-alpha install` will always\ninstall locked versions, achieving reproducible installations across computers.\n\nRun `shards-alpha --help` to list other commands with their options.\n\nHappy Hacking!\n\n## Public Name\n\nThe public name for this additive fork is **Ashard**.\n\nFor the current release-candidate period, the shipped binary and package names\nremain `shards-alpha` so existing installs and automation keep working. The\nproduct story we should publish is:\n\n- **Ashard** is the public project name\n- **`shards-alpha`** is the current compatibility-preserving binary/package name\n\nMore specifically:\n\n- **Ashard** is intended to read as \"a shard\" in ordinary English\n- The name signals tooling that sits around a shard instead of replacing the\n  shard ecosystem with a separate one\n- The codebase still exposes the `Shards` namespace because compatibility is\n  the contract\n- Over time we may personify the name more, alongside the rest of the Amber v2\n  tooling family, for people building inside the amberverse\n\nFor the docs publishing story, see\n[docs/crystal-docs-gap-analysis.md](docs/crystal-docs-gap-analysis.md). It\nexplains what Crystal Docs already provides and what Ashard adds on top.\n\n## Compatibility Promise\n\nThis repository has two operating modes:\n\n- `master` mirrors upstream `crystal-lang/shards`\n- `alpha` carries additive tooling currently distributed as `shards-alpha`\n\nThe goal is not to replace core Shards behavior. The goal is to stay\ncompatible with normal `shards` dependency-management workflows while layering\nadditional tooling on top.\n\nWe now validate that promise against `amber_cli` before treating upstream syncs\nor release-facing changes as safe. See\n[docs/upstream-compatibility.md](docs/upstream-compatibility.md) for the local\nand CI workflow, including `make compatibility`.\n\n## Ashard Features\n\nAshard currently ships as the `shards-alpha` binary and extends the standard\nCrystal dependency manager with features\nfor AI-assisted development. It distributes AI documentation and MCP server\nconfigurations alongside library code, so consuming projects get everything\nthey need from `shards-alpha install`.\n\n### AI Documentation Distribution\n\nShard authors can ship AI context files (`CLAUDE.md`, skills, agents,\ncommands) that are automatically installed into the consumer's `.claude/`\ndirectory with shard-namespaced paths.\n\n```sh\nshards-alpha install          # AI docs are installed alongside dependencies\nshards-alpha ai-docs          # Check status of installed AI documentation\n```\n\nAuto-detected locations in each dependency:\n\n| Shard path | Installed as |\n|---|---|\n| `.claude/skills/<name>/` | `.claude/skills/<shard>--<name>/` |\n| `.claude/agents/<name>.md` | `.claude/agents/<shard>--<name>.md` |\n| `.claude/commands/<name>.md` | `.claude/commands/<shard>:<name>.md` |\n| `CLAUDE.md` | `.claude/skills/<shard>--docs/SKILL.md` |\n| `AGENTS.md` | `.claude/skills/<shard>--docs/reference/AGENTS.md` |\n| `.mcp.json` | Merged into `.mcp-shards.json` |\n\n#### Version tracking and update safety\n\nEvery installed AI doc file is tracked in `.claude/.ai-docs-info.yml` with:\n\n- The **dependency version** from `shard.lock` (e.g., `kemal: 1.3.0`)\n- A **dual-checksum** per file: the upstream checksum (as shipped by the shard) and the installed checksum (as it exists on disk)\n\nWhen you run `shards update` and a dependency version changes:\n\n- **Unmodified files** (checksums match) are silently updated to the new version\n- **Locally modified files** (checksums differ) are preserved — the new upstream version is saved as `<file>.upstream` so you can merge manually\n\nThis means you can safely customize AI docs from your dependencies without\nlosing changes on update. Use `shards-alpha ai-docs diff <shard>` to compare\nyour modifications against upstream, or `shards-alpha ai-docs reset <shard>` to\ndiscard changes and restore the original.\n\n### MCP Server Distribution & Lifecycle\n\nShards that ship `.mcp.json` files have their MCP server configurations\nmerged into a project-level `.mcp-shards.json` during install. Server\nnames are namespaced as `<shard>/<server>` and paths are rewritten\nautomatically.\n\n```sh\nshards-alpha mcp              # Show server status\nshards-alpha mcp start        # Start all MCP servers\nshards-alpha mcp stop         # Stop all MCP servers\nshards-alpha mcp restart      # Restart servers\nshards-alpha mcp logs <name>  # Tail server logs\n```\n\n### Postinstall Script Tracking\n\nPostinstall scripts are tracked by content hash. Changed scripts emit a\nwarning instead of running automatically, requiring explicit approval:\n\n```sh\nshards-alpha run-script              # Run all pending postinstall scripts\nshards-alpha run-script <shard>      # Run for a specific shard\n```\n\n### SBOM Generation\n\nGenerate a Software Bill of Materials for your project's dependency tree:\n\n```sh\nshards-alpha sbom                      # SPDX 2.3 JSON (default)\nshards-alpha sbom --format=cyclonedx   # CycloneDX 1.6 JSON\n```\n\n### Documentation Generation\n\nGenerate Crystal API documentation with optional theming:\n\n```sh\nshards-alpha docs\n```\n\n### For Shard Authors\n\nTo distribute AI docs and MCP servers with your shard, add any of:\n\n- `CLAUDE.md` — General AI context for your library\n- `.claude/skills/<name>/SKILL.md` — Specific AI workflows\n- `.mcp.json` — MCP server configurations\n- `ai_docs` section in `shard.yml` — Fine-grained include/exclude control\n\nSee [`examples/`](examples/) for a complete walkthrough with a working\ndemo project.\n\n### Claude Code Assistant Setup\n\nSet up Claude Code with compliance skills, agents, and settings for your\nproject in one command:\n\n```sh\nshards-alpha assistant init       # Install skills, agents, settings, and MCP config\n```\n\nThis creates:\n\n| What | Files |\n|------|-------|\n| **Skills** (6) | `/audit`, `/licenses`, `/policy-check`, `/diff-deps`, `/compliance-report`, `/sbom` |\n| **Agents** (2) | `compliance-checker`, `security-reviewer` |\n| **Settings** | `.claude/settings.json` (pre-approved compliance commands) |\n| **Context** | `.claude/CLAUDE.md` (project overview for Claude) |\n| **MCP server** | `.mcp.json` entry for the compliance MCP server |\n\nA tracking file (`.claude/.assistant-config.yml`) records the installed\nversion, enabled components, and per-file checksums so upgrades can\ndetect and preserve your local modifications.\n\n#### Managing the assistant config\n\n```sh\nshards-alpha assistant status     # Show version, components, modified files\nshards-alpha assistant update     # Upgrade to latest (preserves local edits)\nshards-alpha assistant update --dry-run  # Preview what would change\nshards-alpha assistant remove     # Remove all tracked files\n```\n\n#### Selective installation\n\nSkip components you don't need:\n\n```sh\nshards-alpha assistant init --no-agents    # Skip agent definitions\nshards-alpha assistant init --no-mcp       # Skip .mcp.json configuration\nshards-alpha assistant init --no-skills    # Skip skill files\nshards-alpha assistant init --no-settings  # Skip settings.json and CLAUDE.md\n```\n\n#### Automatic setup via shard.yml\n\nProjects can opt in to automatic assistant configuration during\n`shards-alpha install` by adding an `ai_assistant` section to `shard.yml`:\n\n```yaml\nai_assistant:\n  auto_install: true\n```\n\nWhen enabled, `shards-alpha install` will:\n- Run `assistant init` if no assistant config exists\n- Run `assistant update` if the installed version is older than the binary\n\nSkip auto-configuration with `--skip-ai-assistant`.\n\n#### Upgrading from `mcp-server init`\n\nIf you previously used `shards-alpha mcp-server init` to set up skills\nand agents, running `assistant init` will detect the existing files,\nadopt them into the tracking system, and create any missing files. Your\nlocal modifications are preserved.\n\n## Supply Chain Compliance\n\nAshard includes a suite of supply chain security tools, currently distributed\nthrough `shards-alpha`, designed for\nSOC2 and ISO 27001 compliance. These commands can be used individually or\ncombined into a unified compliance report.\n\nFor detailed usage, examples, and CI/CD integration patterns, see the\n[Compliance Guide](docs/compliance-guide.md).\n\n### Vulnerability Audit\n\nScan locked dependencies against the [OSV](https://osv.dev/) vulnerability\ndatabase:\n\n```sh\nshards-alpha audit                        # Colored terminal output\nshards-alpha audit --format=json          # Machine-readable JSON\nshards-alpha audit --format=sarif         # SARIF 2.1.0 for GitHub Code Scanning\nshards-alpha audit --severity=high        # Only show high/critical\nshards-alpha audit --fail-above=critical  # Exit 1 only for critical vulns\nshards-alpha audit --ignore=GHSA-xxxx     # Suppress specific advisories\nshards-alpha audit --offline              # Use cached data only\n```\n\nSuppressions can be managed in `.shards-audit-ignore`:\n\n```yaml\n- id: GHSA-xxxx-yyyy-zzzz\n  reason: \"Not applicable: we don't use the affected code path\"\n  expires: 2026-06-01\n```\n\n### Integrity Verification\n\nEvery `shards-alpha install` and `shards-alpha update` records SHA-256 checksums in\n`shard.lock`. Subsequent installs verify that installed files match.\n\n```sh\nshards-alpha install               # Checksums computed and verified automatically\nshards-alpha install --skip-verify # Bypass verification (logs a warning)\n```\n\nTampered dependencies produce a clear error:\n\n```\nE: Checksum mismatch for web: expected sha256:abc123... got sha256:def456...\n```\n\n### License Compliance\n\nList licenses for all locked dependencies with optional policy enforcement:\n\n```sh\nshards-alpha licenses                     # Colored table\nshards-alpha licenses --format=json       # Machine-readable JSON\nshards-alpha licenses --format=csv        # CSV export\nshards-alpha licenses --format=markdown   # Markdown table\nshards-alpha licenses --detect            # Heuristic detection from LICENSE files\nshards-alpha licenses --check             # Exit 1 on policy violations\nshards-alpha licenses --policy=path.yml   # Use custom license policy\n```\n\n### Dependency Policy\n\nDefine and enforce rules about what dependencies are allowed in your\nproject. Create a `.shards-policy.yml` file:\n\n```sh\nshards-alpha policy init    # Create a starter policy file\nshards-alpha policy check   # Check dependencies against policy\nshards-alpha policy show    # Display current policy summary\n```\n\nPolicy rules include source host restrictions, blocked dependencies,\nminimum version requirements, and postinstall script controls. Policies\nare automatically enforced during `shards-alpha install` and `shards-alpha update`\nwhen a `.shards-policy.yml` file is present.\n\n### Change Audit Trail\n\nCompare dependency states between lockfile versions:\n\n```sh\nshards-alpha diff                              # Compare HEAD vs current shard.lock\nshards-alpha diff --from=HEAD --to=current     # Same as above (explicit)\nshards-alpha diff --from=v1.0.0                # Compare against a git tag\nshards-alpha diff --from=old.lock              # Compare against a saved lockfile\nshards-alpha diff --format=json                # Machine-readable output\nshards-alpha diff --format=markdown            # Markdown table for PR descriptions\n```\n\nAn audit log is automatically maintained at `.shards/audit/changelog.json`\nwith timestamped entries for every `install` and `update` that modifies\nthe lock file.\n\n### Compliance Report\n\nGenerate a unified report combining all compliance data into a single\ndocument suitable for auditors:\n\n```sh\nshards-alpha compliance-report                           # JSON (default)\nshards-alpha compliance-report --format=html             # Professional HTML report\nshards-alpha compliance-report --format=markdown         # Markdown report\nshards-alpha compliance-report --output=report.json      # Custom output path\nshards-alpha compliance-report --sections=sbom,integrity # Only specific sections\nshards-alpha compliance-report --reviewer=security@co.com # Add attestation\n```\n\nThe report aggregates SBOM data, vulnerability findings, license inventory,\npolicy compliance status, integrity verification, and change history into a\nsingle document with an executive summary and overall pass/fail status.\nReports are automatically archived to `.shards/audit/reports/`.\n\n## Developers\n\n### Requirements\n\nThese requirements are only necessary for compiling Ashard.\n\n* Crystal\n\n  Please refer to <https://crystal-lang.org/install/> for\n  instructions for your operating system.\n\n* libyaml\n\n  On Debian/Ubuntu Linux you may install the `libyaml-dev` package.\n\n  On Mac OS X you may install it using homebrew with `brew install libyaml`\n  then make sure to have `/usr/local/lib` in your `LIBRARY_PATH` environment\n  variable (eg: `export LIBRARY_PATH=\"/usr/local/lib:$LIBRARY_PATH\"`).\n  Please adjust the path per your Homebrew installation.\n\n* [asciidoctor](https://asciidoctor.org/)\n\n  Needed for building manpages.\n\n### Getting started\n\nIt is strongly recommended to use `make` for building Ashard and developing it.\nThe [`Makefile`](./Makefile) contains recipes for compiling and testing.\n\nRun `make bin/shards-alpha` to build the binary.\n* `release=1` for a release build (applies optimizations)\n* `static=1` for static linking (only works with musl-libc)\n* `debug=1` for full symbolic debug info\n\nRun `make install` to install the binary. Target path can be adjusted with `PREFIX` (default: `PREFIX=/usr/bin`).\n\nRun `make test` to run the test suites:\n* `make test_unit` runs unit tests (`./spec/unit`)\n* `make test_integration` runs integration tests (`./spec/integration`) on `bin/shards-alpha`\n\nRun `make docs` to build the manpages.\n\n### Devenv\n\nThis repository contains a configuration for [devenv.sh](https://devenv.sh) which\nmakes it easy to setup a reproducible environment with all necessary tools for\nbuilding and testing.\n\n- Checkout the repository\n- Run `devenv shell` to get a shell with development environment\n\nA hook for [automatic shell activation](https://devenv.sh/automatic-shell-activation/)\nis also included. If you have `direnv` installed, the devenv environment loads\nautomatically upon entering the repo folder.\n\n## License\n\nLicensed under the Apache License, Version 2.0. See [LICENSE](./LICENSE) for\ndetails.\n","program":{"html_id":"Ashard/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"Ashard","program":true,"enum":false,"alias":false,"const":false,"class_methods":[{"html_id":"walk_files(dir:String):Array(String)-class-method","name":"walk_files","doc":"Recursively collect all files (including those in dot-directories)","summary":"<p>Recursively collect all files (including those in dot-directories)</p>","abstract":false,"args":[{"name":"dir","external_name":"dir","restriction":"String"}],"args_string":"(dir : String) : Array(String)","args_html":"(dir : String) : Array(String)","location":{"filename":"src/build_assistant_versions.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/build_assistant_versions.cr#L5"},"def":{"name":"walk_files","args":[{"name":"dir","external_name":"dir","restriction":"String"}],"return_type":"Array(String)","visibility":"Public","body":"result = [] of String\nDir.each_child(dir) do |entry|\n  full = File.join(dir, entry)\n  if File.directory?(full)\n    result.concat(walk_files(full))\n  elsif File.file?(full)\n    result << full\n  end\nend\nresult\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards","path":"Shards.html","kind":"module","full_name":"Shards","name":"Shards","abstract":false,"locations":[{"filename":"src/ai_docs.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L6"},{"filename":"src/ai_docs_info.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L4"},{"filename":"src/assistant_config.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L6"},{"filename":"src/assistant_config_info.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L4"},{"filename":"src/assistant_versions.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_versions.cr#L1"},{"filename":"src/change_logger.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/change_logger.cr#L5"},{"filename":"src/checksum.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/checksum.cr#L3"},{"filename":"src/cli.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/cli.cr#L5"},{"filename":"src/commands/ai_docs.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/ai_docs.cr#L5"},{"filename":"src/commands/assistant.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/assistant.cr#L3"},{"filename":"src/commands/audit.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/audit.cr#L7"},{"filename":"src/commands/build.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/build.cr#L3"},{"filename":"src/commands/check.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/check.cr#L4"},{"filename":"src/commands/command.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L8"},{"filename":"src/commands/compliance_report.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/compliance_report.cr#L6"},{"filename":"src/commands/diff.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/diff.cr#L5"},{"filename":"src/commands/docs.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/docs.cr#L6"},{"filename":"src/commands/init.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/init.cr#L4"},{"filename":"src/commands/install.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/install.cr#L8"},{"filename":"src/commands/licenses.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/licenses.cr#L8"},{"filename":"src/commands/list.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/list.cr#L3"},{"filename":"src/commands/lock.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/lock.cr#L4"},{"filename":"src/commands/mcp.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/mcp.cr#L4"},{"filename":"src/commands/outdated.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/outdated.cr#L3"},{"filename":"src/commands/policy.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/policy.cr#L6"},{"filename":"src/commands/prune.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/prune.cr#L6"},{"filename":"src/commands/run.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run.cr#L3"},{"filename":"src/commands/run_script.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run_script.cr#L3"},{"filename":"src/commands/sbom.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/sbom.cr#L5"},{"filename":"src/commands/update.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/update.cr#L7"},{"filename":"src/commands/version.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/version.cr#L3"},{"filename":"src/compliance/html_template.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/html_template.cr#L1"},{"filename":"src/compliance/report_builder.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L5"},{"filename":"src/compliance/report_formatter.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_formatter.cr#L5"},{"filename":"src/config.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L5"},{"filename":"src/dependency.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L5"},{"filename":"src/diff_report.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L4"},{"filename":"src/docs.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L1"},{"filename":"src/errors.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L1"},{"filename":"src/license_policy.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L5"},{"filename":"src/license_scanner.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L1"},{"filename":"src/lock.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L5"},{"filename":"src/lockfile_differ.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L4"},{"filename":"src/logger.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/logger.cr#L4"},{"filename":"src/logger.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/logger.cr#L13"},{"filename":"src/mcp/claude_config.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/claude_config.cr#L1"},{"filename":"src/mcp/compliance_server.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L6"},{"filename":"src/mcp_manager.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L3"},{"filename":"src/molinillo_solver.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L4"},{"filename":"src/override.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/override.cr#L8"},{"filename":"src/package.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L5"},{"filename":"src/policy.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L5"},{"filename":"src/policy_checker.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_checker.cr#L9"},{"filename":"src/policy_report.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L4"},{"filename":"src/postinstall_info.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L4"},{"filename":"src/purl.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/purl.cr#L3"},{"filename":"src/requirement.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L1"},{"filename":"src/resolvers/crystal.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/crystal.cr#L1"},{"filename":"src/resolvers/fossil.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L7"},{"filename":"src/resolvers/git.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L7"},{"filename":"src/resolvers/hg.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L7"},{"filename":"src/resolvers/path.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L3"},{"filename":"src/resolvers/resolver.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L7"},{"filename":"src/script.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/script.cr#L1"},{"filename":"src/spdx.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L1"},{"filename":"src/spec.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L8"},{"filename":"src/target.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L1"},{"filename":"src/version.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/version.cr#L1"},{"filename":"src/versions.cr","line_number":1,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L1"},{"filename":"src/vulnerability_report.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L5"},{"filename":"src/vulnerability_scanner.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"AI_DOCS_INFO_FILENAME","name":"AI_DOCS_INFO_FILENAME","value":"\".ai-docs-info.yml\""},{"id":"ASSISTANT_CONFIG_FILENAME","name":"ASSISTANT_CONFIG_FILENAME","value":"\".assistant-config.yml\""},{"id":"BUILD_DATE","name":"BUILD_DATE","value":"\"\""},{"id":"BUILD_SHA1","name":"BUILD_SHA1","value":"{{ (env(\"SHARDS_CONFIG_BUILD_COMMIT\")) || \"\" }}"},{"id":"BUILTIN_COMMANDS","name":"BUILTIN_COMMANDS","value":"[\"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"},{"id":"DEFAULT_COMMAND","name":"DEFAULT_COMMAND","value":"\"install\""},{"id":"DEFAULT_VERSION","name":"DEFAULT_VERSION","value":"\"0\""},{"id":"FORMATTER","name":"FORMATTER","value":"::Log::Formatter.new do |entry, io|\n  message = entry.message\n  package_name = entry.context[:package]?\n  if @@colors\n    if package_name && entry.severity <= ::Log::Severity::Debug\n      ((io << \"[\") << (package_name.colorize(:blue)).to_s) << \"] \"\n    end\n    io << (if color = LOGGER_COLORS[entry.severity]?\n      if idx = message.index(' ')\n        (message[0...idx].colorize(color)).to_s + message[idx..-1]\n      else\n        message.colorize(color)\n      end\n    else\n      message\n    end)\n  else\n    (io << entry.severity.label[0]) << \": \"\n    if package_name && entry.severity <= ::Log::Severity::Debug\n      ((io << \"[\") << package_name) << \"] \"\n    end\n    io << message\n  end\nend"},{"id":"INSTALL_DIR","name":"INSTALL_DIR","value":"\"lib\""},{"id":"LOCK_FILENAME","name":"LOCK_FILENAME","value":"\"shard.lock\""},{"id":"Log","name":"Log","value":"::Log.for(self)"},{"id":"LOGGER_COLORS","name":"LOGGER_COLORS","value":"{::Log::Severity::Error => :red, ::Log::Severity::Warn => :yellow, ::Log::Severity::Info => :green, ::Log::Severity::Debug => :light_gray}"},{"id":"OVERRIDE_FILENAME","name":"OVERRIDE_FILENAME","value":"\"shard.override.yml\""},{"id":"POLICY_FILENAME","name":"POLICY_FILENAME","value":"\".shards-policy.yml\""},{"id":"POSTINSTALL_INFO_FILENAME","name":"POSTINSTALL_INFO_FILENAME","value":"\".shards.postinstall\""},{"id":"SPEC_FILENAME","name":"SPEC_FILENAME","value":"\"shard.yml\""},{"id":"VERSION","name":"VERSION","value":"{{ (read_file(\"/home/runner/work/shards/shards/src/../VERSION\")).chomp }}"},{"id":"VERSION_AT_FOSSIL_COMMIT","name":"VERSION_AT_FOSSIL_COMMIT","value":"/^(\\d+[-.][-.a-zA-Z\\d]+)\\+fossil\\.commit\\.([0-9a-f]+)$/"},{"id":"VERSION_AT_GIT_COMMIT","name":"VERSION_AT_GIT_COMMIT","value":"/^(\\d+[-.][-.a-zA-Z\\d]+)\\+git\\.commit\\.([0-9a-f]+)$/"},{"id":"VERSION_AT_HG_COMMIT","name":"VERSION_AT_HG_COMMIT","value":"/^(\\d+[-.][-.a-zA-Z\\d]+)\\+hg\\.commit\\.([0-9a-f]+)$/"},{"id":"VERSION_REFERENCE","name":"VERSION_REFERENCE","value":"/^v?\\d+[-.][-.a-zA-Z\\d]+$/"},{"id":"VERSION_TAG","name":"VERSION_TAG","value":"/^v(\\d+[-.][-.a-zA-Z\\d]+)$/"}],"class_methods":[{"html_id":"ai_docs_info-class-method","name":"ai_docs_info","abstract":false,"location":{"filename":"src/config.cr","line_number":131,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L131"},"def":{"name":"ai_docs_info","visibility":"Public","body":"@@ai_docs_info || (\n  @@ai_docs_info = AIDocsInfo.new(File.join(Dir.current, \".claude\", AI_DOCS_INFO_FILENAME))\n)"},"external_var":false},{"html_id":"bin_path-class-method","name":"bin_path","abstract":false,"location":{"filename":"src/config.cr","line_number":77,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L77"},"def":{"name":"bin_path","visibility":"Public","body":"@@bin_path || (@@bin_path = ENV.fetch(\"SHARDS_BIN_PATH\") do File.join(Dir.current, \"bin\") end)"},"external_var":false},{"html_id":"bin_path=(bin_path:String)-class-method","name":"bin_path=","abstract":false,"args":[{"name":"bin_path","external_name":"bin_path","restriction":"String"}],"args_string":"(bin_path : String)","args_html":"(bin_path : String)","location":{"filename":"src/config.cr","line_number":81,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L81"},"def":{"name":"bin_path=","args":[{"name":"bin_path","external_name":"bin_path","restriction":"String"}],"visibility":"Public","body":"@@bin_path = bin_path"},"external_var":false},{"html_id":"cache_path-class-method","name":"cache_path","abstract":false,"location":{"filename":"src/config.cr","line_number":24,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L24"},"def":{"name":"cache_path","visibility":"Public","body":"@@cache_path || (@@cache_path = find_or_create_cache_path)"},"external_var":false},{"html_id":"cache_path=(cache_path:String)-class-method","name":"cache_path=","abstract":false,"args":[{"name":"cache_path","external_name":"cache_path","restriction":"String"}],"args_string":"(cache_path : String)","args_html":"(cache_path : String)","location":{"filename":"src/config.cr","line_number":61,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L61"},"def":{"name":"cache_path=","args":[{"name":"cache_path","external_name":"cache_path","restriction":"String"}],"visibility":"Public","body":"@@cache_path = cache_path"},"external_var":false},{"html_id":"check_and_install_dependencies(path)-class-method","name":"check_and_install_dependencies","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""}],"args_string":"(path)","args_html":"(path)","location":{"filename":"src/cli.cr","line_number":288,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/cli.cr#L288"},"def":{"name":"check_and_install_dependencies","args":[{"name":"path","external_name":"path","restriction":""}],"visibility":"Public","body":"begin\n  Commands::Check.run(path)\nrescue\n  Commands::Install.run(path)\nend"},"external_var":false},{"html_id":"cli_options-class-method","name":"cli_options","abstract":false,"location":{"filename":"src/cli.cr","line_number":256,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/cli.cr#L256"},"def":{"name":"cli_options","visibility":"Public","body":"shards_opts : Array(String)\n{% if (compare_versions(Crystal::VERSION, \"1.0.0-0\")) > 0 %}\n      shards_opts = Process.parse_arguments(ENV.fetch(\"SHARDS_OPTS\", \"\"))\n    {% else %}\n      shards_opts = ENV.fetch(\"SHARDS_OPTS\", \"\").split\n    {% end %}\nARGV.dup.concat(shards_opts)\n"},"external_var":false},{"html_id":"colors=(colors:Bool)-class-method","name":"colors=","abstract":false,"args":[{"name":"colors","external_name":"colors","restriction":"Bool"}],"args_string":"(colors : Bool)","args_html":"(colors : Bool)","location":{"filename":"src/logger.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/logger.cr#L5"},"def":{"name":"colors=","args":[{"name":"colors","external_name":"colors","restriction":"Bool"}],"visibility":"Public","body":"@@colors = colors"},"external_var":false},{"html_id":"colors?:Bool-class-method","name":"colors?","abstract":false,"location":{"filename":"src/logger.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/logger.cr#L5"},"def":{"name":"colors?","return_type":"Bool","visibility":"Public","body":"@@colors"},"external_var":false},{"html_id":"crystal_bin-class-method","name":"crystal_bin","abstract":false,"location":{"filename":"src/config.cr","line_number":84,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L84"},"def":{"name":"crystal_bin","visibility":"Public","body":"@@crystal_bin || (@@crystal_bin = ENV.fetch(\"CRYSTAL\", \"crystal\"))"},"external_var":false},{"html_id":"crystal_bin=(crystal_bin:String)-class-method","name":"crystal_bin=","abstract":false,"args":[{"name":"crystal_bin","external_name":"crystal_bin","restriction":"String"}],"args_string":"(crystal_bin : String)","args_html":"(crystal_bin : String)","location":{"filename":"src/config.cr","line_number":88,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L88"},"def":{"name":"crystal_bin=","args":[{"name":"crystal_bin","external_name":"crystal_bin","restriction":"String"}],"visibility":"Public","body":"@@crystal_bin = crystal_bin"},"external_var":false},{"html_id":"crystal_version-class-method","name":"crystal_version","abstract":false,"location":{"filename":"src/config.cr","line_number":95,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L95"},"def":{"name":"crystal_version","visibility":"Public","body":"@@crystal_version || (\n  @@crystal_version = without_prerelease(ENV[\"CRYSTAL_VERSION\"]? || (\n    begin\n      output = IO::Memory.new\n      error = IO::Memory.new\n      status = begin\n        Process.run(crystal_bin, {\"env\", \"CRYSTAL_VERSION\"}, output: output, error: error)\n      rescue e\n        raise(Error.new(\"Could not execute '#{crystal_bin}': #{e.message}\"))\n      end\n      if status.success?\n      else\n        raise(Error.new(\"Error executing crystal:\\n#{error}\"))\n      end\n      output.to_s.strip\n    end\n  ))\n)"},"external_var":false},{"html_id":"crystal_version=(crystal_version:String)-class-method","name":"crystal_version=","abstract":false,"args":[{"name":"crystal_version","external_name":"crystal_version","restriction":"String"}],"args_string":"(crystal_version : String)","args_html":"(crystal_version : String)","location":{"filename":"src/config.cr","line_number":109,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L109"},"def":{"name":"crystal_version=","args":[{"name":"crystal_version","external_name":"crystal_version","restriction":"String"}],"visibility":"Public","body":"@@crystal_version = crystal_version"},"external_var":false},{"html_id":"display_help_and_exit(opts)-class-method","name":"display_help_and_exit","abstract":false,"args":[{"name":"opts","external_name":"opts","restriction":""}],"args_string":"(opts)","args_html":"(opts)","location":{"filename":"src/cli.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/cli.cr#L32"},"def":{"name":"display_help_and_exit","args":[{"name":"opts","external_name":"opts","restriction":""}],"visibility":"Public","body":"puts(\"shards [<options>...] [<command>]\\n\\nCommands:\\n    build [<targets>] [<build_options>]  - Build the specified <targets> in `bin` path, all build_options are delegated to `crystal build`.\\n    check                                - Verify all dependencies are installed.\\n    diff [--from=REF] [--to=REF] [--format=FORMAT]    - Show dependency changes between lockfile states.\\n    init                                 - Initialize a `shard.yml` file.\\n    install                              - Install dependencies, creating or using the `shard.lock` file.\\n    list [--tree]                        - List installed dependencies.\\n    lock [--update] [<shards>...]        - Lock dependencies in `shard.lock` but doesn't install them.\\n    outdated [--pre]                     - List dependencies that are outdated.\\n    prune                                - Remove unused dependencies from `lib` folder.\\n    run [<target>] [<options>]           - Build and run specified target\\n    update [<shards>...]                 - Update dependencies and `shard.lock`.\\n    version [<path>]                     - Print the current version of the shard.\\n    run-script [<shards>...]             - Run pending postinstall scripts.\\n    ai-docs [status|diff|reset|update|merge-mcp]  - Manage AI documentation from dependencies.\\n    docs [<crystal_docs_options>]            - Generate themed docs with AI assistant buttons.\\n    sbom [--format=spdx|cyclonedx] [--output=FILE]  - Generate Software Bill of Materials.\\n    mcp [status|start|stop|restart|logs]           - Manage MCP server lifecycle.\\n    audit [options]                                 - Audit dependencies for known vulnerabilities.\\n    licenses [options]                               - List dependency licenses and check compliance.\\n    policy [check|init|show]                         - Manage dependency policies.\\n    compliance-report [<options>]                      - Generate supply chain compliance report.\\n    mcp-server [--interactive]                              - Start MCP compliance server for AI agents (audit, licenses, policy, etc.).\\n    assistant [init|update|status|remove] [options]        - Manage Claude Code assistant configuration (skills, agents, settings).\\n\\nGeneral options:\")\nputs(opts)\nexit\n"},"external_var":false},{"html_id":"frozen=(frozen)-class-method","name":"frozen=","abstract":false,"args":[{"name":"frozen","external_name":"frozen","restriction":""}],"args_string":"(frozen)","args_html":"(frozen)","location":{"filename":"src/config.cr","line_number":120,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L120"},"def":{"name":"frozen=","args":[{"name":"frozen","external_name":"frozen","restriction":""}],"visibility":"Public","body":"@@frozen = frozen"},"external_var":false},{"html_id":"frozen?-class-method","name":"frozen?","abstract":false,"location":{"filename":"src/config.cr","line_number":120,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L120"},"def":{"name":"frozen?","visibility":"Public","body":"@@frozen"},"external_var":false},{"html_id":"global_override_filename-class-method","name":"global_override_filename","abstract":false,"location":{"filename":"src/config.cr","line_number":91,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L91"},"def":{"name":"global_override_filename","visibility":"Public","body":"ENV[\"SHARDS_OVERRIDE\"]?.try do |p| File.expand_path(p) end"},"external_var":false},{"html_id":"info-class-method","name":"info","abstract":false,"location":{"filename":"src/config.cr","line_number":73,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L73"},"def":{"name":"info","visibility":"Public","body":"@@info || (@@info = Info.new)"},"external_var":false},{"html_id":"install_path-class-method","name":"install_path","abstract":false,"location":{"filename":"src/config.cr","line_number":64,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L64"},"def":{"name":"install_path","visibility":"Public","body":"@@install_path || (\n  @@install_path = (ENV.fetch(\"SHARDS_INSTALL_PATH\") do File.join(Dir.current, INSTALL_DIR) end)\n)"},"external_var":false},{"html_id":"install_path=(install_path:String)-class-method","name":"install_path=","abstract":false,"args":[{"name":"install_path","external_name":"install_path","restriction":"String"}],"args_string":"(install_path : String)","args_html":"(install_path : String)","location":{"filename":"src/config.cr","line_number":70,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L70"},"def":{"name":"install_path=","args":[{"name":"install_path","external_name":"install_path","restriction":"String"}],"visibility":"Public","body":"@@install_path = install_path"},"external_var":false},{"html_id":"jobs:Int32-class-method","name":"jobs","abstract":false,"location":{"filename":"src/config.cr","line_number":129,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L129"},"def":{"name":"jobs","return_type":"Int32","visibility":"Public","body":"@@jobs"},"external_var":false},{"html_id":"jobs=(jobs:Int32)-class-method","name":"jobs=","abstract":false,"args":[{"name":"jobs","external_name":"jobs","restriction":"Int32"}],"args_string":"(jobs : Int32)","args_html":"(jobs : Int32)","location":{"filename":"src/config.cr","line_number":129,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L129"},"def":{"name":"jobs=","args":[{"name":"jobs","external_name":"jobs","restriction":"Int32"}],"visibility":"Public","body":"@@jobs = jobs"},"external_var":false},{"html_id":"local=(local)-class-method","name":"local=","abstract":false,"args":[{"name":"local","external_name":"local","restriction":""}],"args_string":"(local)","args_html":"(local)","location":{"filename":"src/config.cr","line_number":122,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L122"},"def":{"name":"local=","args":[{"name":"local","external_name":"local","restriction":""}],"visibility":"Public","body":"@@local = local"},"external_var":false},{"html_id":"local?-class-method","name":"local?","abstract":false,"location":{"filename":"src/config.cr","line_number":122,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L122"},"def":{"name":"local?","visibility":"Public","body":"@@local"},"external_var":false},{"html_id":"parse_args(args)-class-method","name":"parse_args","abstract":false,"args":[{"name":"args","external_name":"args","restriction":""}],"args_string":"(args)","args_html":"(args)","location":{"filename":"src/cli.cr","line_number":273,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/cli.cr#L273"},"def":{"name":"parse_args","args":[{"name":"args","external_name":"args","restriction":""}],"visibility":"Public","body":"targets = [] of String\noptions = [] of String\n\nargs.each do |arg|\n  if arg.starts_with?('-')\n    options << arg\n  else\n    targets << arg\n  end\nend\n\n{targets, options}\n"},"external_var":false},{"html_id":"postinstall_info-class-method","name":"postinstall_info","abstract":false,"location":{"filename":"src/config.cr","line_number":137,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L137"},"def":{"name":"postinstall_info","visibility":"Public","body":"@@postinstall_info || (\n  @@postinstall_info = PostinstallInfo.new(File.join(install_path, POSTINSTALL_INFO_FILENAME))\n)"},"external_var":false},{"html_id":"run-class-method","name":"run","abstract":false,"location":{"filename":"src/cli.cr","line_number":67,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/cli.cr#L67"},"def":{"name":"run","visibility":"Public","body":"display_help = false\n\nOptionParser.parse(cli_options) do |opts|\n  path = Dir.current\n\n  opts.on(\"--no-color\", \"Disable colored output.\") do self.colors = false end\n  opts.on(\"--version\", \"Print the `shards` version.\") do   puts(self.version_string)\n  exit\n end\n  opts.on(\"--frozen\", \"Strictly installs locked versions from shard.lock.\") do\n    self.frozen = true\n  end\n  opts.on(\"--without-development\", \"Does not install development dependencies.\") do\n    self.with_development = false\n  end\n  opts.on(\"--production\", \"same as `--frozen --without-development`\") do\n    self.frozen = true\n    self.with_development = false\n  end\n  opts.on(\"--skip-postinstall\", \"Does not run postinstall of dependencies\") do\n    self.skip_postinstall = true\n  end\n  opts.on(\"--skip-executables\", \"Does not install executables\") do\n    self.skip_executables = true\n  end\n  opts.on(\"--skip-ai-docs\", \"Does not install AI documentation from dependencies\") do\n    self.skip_ai_docs = true\n  end\n  opts.on(\"--skip-ai-assistant\", \"Skip AI assistant auto-configuration\") do\n    self.skip_ai_assistant = true\n  end\n  opts.on(\"--skip-verify\", \"Skip checksum verification during install.\") do\n    self.skip_verify = true\n  end\n  opts.on(\"--local\", \"Don't update remote repositories, use the local cache only.\") do self.local = true end\n  opts.on(\"--jobs=N\", \"Number of repository downloads to perform in parallel (default: 8). Currently only for git.\") do |n| self.jobs = n.to_i end\n\n  opts.on(\"--ignore-crystal-version\", \"Has no effect. Kept for compatibility, to be removed in the future.\") do\n  end\n  opts.on(\"-v\", \"--verbose\", \"Increase the log verbosity, printing all debug statements.\") do self.set_debug_log_level end\n  opts.on(\"-q\", \"--quiet\", \"Decrease the log verbosity, printing only warnings and errors.\") do self.set_warning_log_level end\n  opts.on(\"-h\", \"--help\", \"Print usage synopsis.\") do display_help = true end\n\n  opts.unknown_args do |args, options|\n    command = args[0]? || DEFAULT_COMMAND\n\n    if BUILTIN_COMMANDS.includes?(command)\n      if display_help && !({\"mcp-server\", \"assistant\"}.includes?(command))\n        display_help_and_exit(opts)\n      end\n\n      case command\n      when \"build\"\n        targets, build_options = parse_args(args[1..-1])\n        check_and_install_dependencies(path)\n        Commands::Build.run(path, targets, build_options)\n      when \"run\"\n        targets, run_options = parse_args(args[1..-1])\n        check_and_install_dependencies(path)\n        Commands::Run.run(path, targets, run_options, options)\n      when \"check\"\n        Commands::Check.run(path)\n      when \"init\"\n        Commands::Init.run(path)\n      when \"install\"\n        Commands::Install.run(path)\n      when \"list\"\n        Commands::List.run(path, tree: args.includes?(\"--tree\"))\n      when \"lock\"\n        Commands::Lock.run(path, args[1..-1].reject(&.starts_with?(\"--\")), print: args.includes?(\"--print\"), update: args.includes?(\"--update\"))\n      when \"outdated\"\n        Commands::Outdated.run(path, prereleases: args.includes?(\"--pre\"))\n      when \"prune\"\n        Commands::Prune.run(path)\n      when \"update\"\n        Commands::Update.run(path, args[1..-1].reject(&.starts_with?(\"--\")))\n      when \"version\"\n        Commands::Version.run(args[1]? || path)\n      when \"run-script\"\n        Commands::RunScript.run(path, args[1..-1].reject(&.starts_with?(\"--\")))\n      when \"ai-docs\"\n        Commands::AIDocs.run(path, args[1..-1].reject(&.starts_with?(\"--\")))\n      when \"docs\"\n        Commands::Docs.run(path, args[1..-1])\n      when \"mcp\"\n        Commands::MCP.run(path, args[1..-1])\n      when \"sbom\"\n        sbom_format = \"spdx\"\n        sbom_output = nil : String | ::Nil\n        sbom_include_dev = false\n        args[1..-1].each do |arg|\n          case arg\n          when .starts_with?(\"--format=\")\n            sbom_format = (arg.split(\"=\", 2)).last\n          when .starts_with?(\"--output=\")\n            sbom_output = (arg.split(\"=\", 2)).last\n          when \"--include-dev\"\n            sbom_include_dev = true\n          end\n        end\n        Commands::SBOM.run(path, sbom_format, sbom_output, sbom_include_dev)\n      when \"audit\"\n        audit_format = \"terminal\"\n        audit_severity : String | ::Nil = nil\n        audit_ignore_ids = [] of String\n        audit_ignore_file : String | ::Nil = nil\n        audit_fail_above : String | ::Nil = nil\n        audit_offline = false\n        audit_update_db = false\n        args[1..-1].each do |arg|\n          case arg\n          when .starts_with?(\"--format=\")\n            audit_format = (arg.split(\"=\", 2)).last\n          when .starts_with?(\"--severity=\")\n            audit_severity = (arg.split(\"=\", 2)).last\n          when .starts_with?(\"--ignore=\")\n            audit_ignore_ids = (arg.split(\"=\", 2)).last.split(\",\")\n          when .starts_with?(\"--ignore-file=\")\n            audit_ignore_file = (arg.split(\"=\", 2)).last\n          when .starts_with?(\"--fail-above=\")\n            audit_fail_above = (arg.split(\"=\", 2)).last\n          when \"--offline\"\n            audit_offline = true\n          when \"--update-db\"\n            audit_update_db = true\n          end\n        end\n        Commands::Audit.run(path, audit_format, audit_severity, audit_ignore_ids, audit_ignore_file, audit_fail_above, audit_offline, audit_update_db)\n      when \"licenses\"\n        lic_format = \"terminal\"\n        lic_policy : String | ::Nil = nil\n        lic_check = false\n        lic_include_dev = false\n        lic_detect = false\n        args[1..-1].each do |arg|\n          case arg\n          when .starts_with?(\"--format=\")\n            lic_format = (arg.split(\"=\", 2)).last\n          when .starts_with?(\"--policy=\")\n            lic_policy = (arg.split(\"=\", 2)).last\n          when \"--check\"\n            lic_check = true\n          when \"--include-dev\"\n            lic_include_dev = true\n          when \"--detect\"\n            lic_detect = true\n          end\n        end\n        Commands::Licenses.run(path, lic_format, lic_policy, lic_check, lic_include_dev, lic_detect)\n      when \"policy\"\n        Commands::Policy.run(path, args[1..-1])\n      when \"compliance-report\"\n        Commands::ComplianceReport.run(path, args[1..-1])\n      when \"diff\"\n        Commands::Diff.run(path, args[1..-1])\n      when \"mcp-server\"\n        mcp_args = args[1..-1]\n        if display_help\n          mcp_args << \"--help\"\n        end\n        ComplianceMCPServer.run(path, mcp_args)\n      when \"assistant\"\n        assistant_args = args[1..-1]\n        if display_help\n          assistant_args << \"--help\"\n        end\n        Commands::Assistant.run(path, assistant_args)\n      else\n        raise(\"BUG: unknown command #{command}\")\n      end\n    else\n      program_name = \"shards-#{command}\"\n      if program_path = Process.find_executable(program_name)\n        run_shards_subcommand(program_path, cli_options)\n      else\n        display_help_and_exit(opts)\n      end\n    end\n\n    exit\n  end\nend\n"},"external_var":false},{"html_id":"run_shards_subcommand(process_name,args)-class-method","name":"run_shards_subcommand","abstract":false,"args":[{"name":"process_name","external_name":"process_name","restriction":""},{"name":"args","external_name":"args","restriction":""}],"args_string":"(process_name, args)","args_html":"(process_name, args)","location":{"filename":"src/cli.cr","line_number":266,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/cli.cr#L266"},"def":{"name":"run_shards_subcommand","args":[{"name":"process_name","external_name":"process_name","restriction":""},{"name":"args","external_name":"args","restriction":""}],"visibility":"Public","body":"Process.exec(command: process_name, args: args[1..])"},"external_var":false},{"html_id":"set_debug_log_level-class-method","name":"set_debug_log_level","abstract":false,"location":{"filename":"src/logger.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/logger.cr#L20"},"def":{"name":"set_debug_log_level","visibility":"Public","body":"Log.level = ::Log::Severity::Debug"},"external_var":false},{"html_id":"set_warning_log_level-class-method","name":"set_warning_log_level","abstract":false,"location":{"filename":"src/logger.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/logger.cr#L16"},"def":{"name":"set_warning_log_level","visibility":"Public","body":"Log.level = ::Log::Severity::Warn"},"external_var":false},{"html_id":"skip_ai_assistant=(skip_ai_assistant)-class-method","name":"skip_ai_assistant=","abstract":false,"args":[{"name":"skip_ai_assistant","external_name":"skip_ai_assistant","restriction":""}],"args_string":"(skip_ai_assistant)","args_html":"(skip_ai_assistant)","location":{"filename":"src/config.cr","line_number":126,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L126"},"def":{"name":"skip_ai_assistant=","args":[{"name":"skip_ai_assistant","external_name":"skip_ai_assistant","restriction":""}],"visibility":"Public","body":"@@skip_ai_assistant = skip_ai_assistant"},"external_var":false},{"html_id":"skip_ai_assistant?-class-method","name":"skip_ai_assistant?","abstract":false,"location":{"filename":"src/config.cr","line_number":126,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L126"},"def":{"name":"skip_ai_assistant?","visibility":"Public","body":"@@skip_ai_assistant"},"external_var":false},{"html_id":"skip_ai_docs=(skip_ai_docs)-class-method","name":"skip_ai_docs=","abstract":false,"args":[{"name":"skip_ai_docs","external_name":"skip_ai_docs","restriction":""}],"args_string":"(skip_ai_docs)","args_html":"(skip_ai_docs)","location":{"filename":"src/config.cr","line_number":125,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L125"},"def":{"name":"skip_ai_docs=","args":[{"name":"skip_ai_docs","external_name":"skip_ai_docs","restriction":""}],"visibility":"Public","body":"@@skip_ai_docs = skip_ai_docs"},"external_var":false},{"html_id":"skip_ai_docs?-class-method","name":"skip_ai_docs?","abstract":false,"location":{"filename":"src/config.cr","line_number":125,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L125"},"def":{"name":"skip_ai_docs?","visibility":"Public","body":"@@skip_ai_docs"},"external_var":false},{"html_id":"skip_executables=(skip_executables)-class-method","name":"skip_executables=","abstract":false,"args":[{"name":"skip_executables","external_name":"skip_executables","restriction":""}],"args_string":"(skip_executables)","args_html":"(skip_executables)","location":{"filename":"src/config.cr","line_number":124,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L124"},"def":{"name":"skip_executables=","args":[{"name":"skip_executables","external_name":"skip_executables","restriction":""}],"visibility":"Public","body":"@@skip_executables = skip_executables"},"external_var":false},{"html_id":"skip_executables?-class-method","name":"skip_executables?","abstract":false,"location":{"filename":"src/config.cr","line_number":124,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L124"},"def":{"name":"skip_executables?","visibility":"Public","body":"@@skip_executables"},"external_var":false},{"html_id":"skip_postinstall=(skip_postinstall)-class-method","name":"skip_postinstall=","abstract":false,"args":[{"name":"skip_postinstall","external_name":"skip_postinstall","restriction":""}],"args_string":"(skip_postinstall)","args_html":"(skip_postinstall)","location":{"filename":"src/config.cr","line_number":123,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L123"},"def":{"name":"skip_postinstall=","args":[{"name":"skip_postinstall","external_name":"skip_postinstall","restriction":""}],"visibility":"Public","body":"@@skip_postinstall = skip_postinstall"},"external_var":false},{"html_id":"skip_postinstall?-class-method","name":"skip_postinstall?","abstract":false,"location":{"filename":"src/config.cr","line_number":123,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L123"},"def":{"name":"skip_postinstall?","visibility":"Public","body":"@@skip_postinstall"},"external_var":false},{"html_id":"skip_verify=(skip_verify)-class-method","name":"skip_verify=","abstract":false,"args":[{"name":"skip_verify","external_name":"skip_verify","restriction":""}],"args_string":"(skip_verify)","args_html":"(skip_verify)","location":{"filename":"src/config.cr","line_number":127,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L127"},"def":{"name":"skip_verify=","args":[{"name":"skip_verify","external_name":"skip_verify","restriction":""}],"visibility":"Public","body":"@@skip_verify = skip_verify"},"external_var":false},{"html_id":"skip_verify?-class-method","name":"skip_verify?","abstract":false,"location":{"filename":"src/config.cr","line_number":127,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L127"},"def":{"name":"skip_verify?","visibility":"Public","body":"@@skip_verify"},"external_var":false},{"html_id":"version_string-class-method","name":"version_string","abstract":false,"location":{"filename":"src/version.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/version.cr#L10"},"def":{"name":"version_string","visibility":"Public","body":"if BUILD_SHA1.empty?\n  \"Shards Alpha #{VERSION} (#{BUILD_DATE})\"\nelse\n  \"Shards Alpha #{VERSION} [#{BUILD_SHA1}] (#{BUILD_DATE})\"\nend"},"external_var":false},{"html_id":"with_development=(with_development)-class-method","name":"with_development=","abstract":false,"args":[{"name":"with_development","external_name":"with_development","restriction":""}],"args_string":"(with_development)","args_html":"(with_development)","location":{"filename":"src/config.cr","line_number":121,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L121"},"def":{"name":"with_development=","args":[{"name":"with_development","external_name":"with_development","restriction":""}],"visibility":"Public","body":"@@with_development = with_development"},"external_var":false},{"html_id":"with_development?-class-method","name":"with_development?","abstract":false,"location":{"filename":"src/config.cr","line_number":121,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/config.cr#L121"},"def":{"name":"with_development?","visibility":"Public","body":"@@with_development"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/AIDocsInfo","path":"Shards/AIDocsInfo.html","kind":"class","full_name":"Shards::AIDocsInfo","name":"AIDocsInfo","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/ai_docs_info.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L16"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CURRENT_VERSION","name":"CURRENT_VERSION","value":"\"1.0\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Tracks installed AI documentation files and their checksums.\n\nPersisted at `.claude/.ai-docs-info.yml`, this tracker enables\nconflict detection during updates by storing two checksums per file:\n\n- `upstream_checksum`: the checksum of the file as shipped by the shard\n- `installed_checksum`: the checksum of the file as it exists on disk\n\nWhen both match, the file is unmodified and safe to auto-update.\nWhen they differ, the user has customized the file and it should\nnot be overwritten.","summary":"<p>Tracks installed AI documentation files and their checksums.</p>","class_methods":[{"html_id":"checksum(content:String):String-class-method","name":"checksum","doc":"Computes a SHA-256 checksum for the given string content.","summary":"<p>Computes a SHA-256 checksum for the given string content.</p>","abstract":false,"args":[{"name":"content","external_name":"content","restriction":"String"}],"args_string":"(content : String) : String","args_html":"(content : String) : String","location":{"filename":"src/ai_docs_info.cr","line_number":140,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L140"},"def":{"name":"checksum","args":[{"name":"content","external_name":"content","restriction":"String"}],"return_type":"String","visibility":"Public","body":"\"sha256:#{Digest::SHA256.hexdigest(content)}\""},"external_var":false},{"html_id":"checksum_file(path:String):String-class-method","name":"checksum_file","doc":"Computes a SHA-256 checksum for the file at the given path.","summary":"<p>Computes a SHA-256 checksum for the file at the given path.</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : String","args_html":"(path : String) : String","location":{"filename":"src/ai_docs_info.cr","line_number":145,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L145"},"def":{"name":"checksum_file","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"String","visibility":"Public","body":"checksum(File.read(path))"},"external_var":false}],"constructors":[{"html_id":"new(path:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"::String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/ai_docs_info.cr","line_number":49,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L49"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"load-instance-method","name":"load","doc":"Loads tracker state from the YAML file at `#path`.","summary":"<p>Loads tracker state from the YAML file at <code><a href=\"../Shards/AIDocsInfo.html#path%3AString-instance-method\">#path</a></code>.</p>","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":55,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L55"},"def":{"name":"load","visibility":"Public","body":"begin\n  content = File.read(@path)\n  pull = YAML::PullParser.new(content)\n  pull.read_stream do\n    pull.read_document do\n      pull.each_in_mapping do\n        case pull.read_scalar\n        when \"version\"\n          pull.read_scalar\n        when \"shards\"\n          pull.each_in_mapping do\n            shard_name = pull.read_scalar\n            version = \"\"\n            files = Hash(String, FileEntry).new\n\n            pull.each_in_mapping do\n              case pull.read_scalar\n              when \"version\"\n                version = pull.read_scalar\n              when \"files\"\n                pull.each_in_mapping do\n                  file_path = pull.read_scalar\n                  upstream = \"\"\n                  installed = \"\"\n                  pull.each_in_mapping do\n                    case pull.read_scalar\n                    when \"upstream_checksum\"\n                      upstream = pull.read_scalar\n                    when \"installed_checksum\"\n                      installed = pull.read_scalar\n                    else\n                      pull.skip\n                    end\n                  end\n                  files[file_path] = FileEntry.new(upstream, installed)\n                end\n              else\n                pull.skip\n              end\n            end\n\n            @shards[shard_name] = ShardEntry.new(version, files)\n          end\n        else\n          pull.skip\n        end\n      end\n    end\n  end\nensure\n  pull.try(&.close)\nend"},"external_var":false},{"html_id":"path:String-instance-method","name":"path","doc":"Absolute path to the `.ai-docs-info.yml` file.","summary":"<p>Absolute path to the <code>.ai-docs-info.yml</code> file.</p>","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":47,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L47"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"@path"},"external_var":false},{"html_id":"save-instance-method","name":"save","doc":"Persists the current tracker state to the YAML file at `#path`.","summary":"<p>Persists the current tracker state to the YAML file at <code><a href=\"../Shards/AIDocsInfo.html#path%3AString-instance-method\">#path</a></code>.</p>","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":102,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L102"},"def":{"name":"save","visibility":"Public","body":"Dir.mkdir_p(File.dirname(@path))\n\nFile.open(@path, \"w\") do |file|\n  YAML.build(file) do |yaml|\n    yaml.mapping do\n      yaml.scalar(\"version\")\n      yaml.scalar(CURRENT_VERSION)\n\n      yaml.scalar(\"shards\")\n      yaml.mapping do\n        @shards.each do |name, entry|\n          yaml.scalar(name)\n          yaml.mapping do\n            yaml.scalar(\"version\")\n            yaml.scalar(entry.version)\n\n            yaml.scalar(\"files\")\n            yaml.mapping do\n              entry.files.each do |path, file_entry|\n                yaml.scalar(path)\n                yaml.mapping do\n                  yaml.scalar(\"upstream_checksum\")\n                  yaml.scalar(file_entry.upstream_checksum)\n                  yaml.scalar(\"installed_checksum\")\n                  yaml.scalar(file_entry.installed_checksum)\n                end\n              end\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"},"external_var":false},{"html_id":"shards:Hash(String,ShardEntry)-instance-method","name":"shards","doc":"Map of shard name to its tracked entry.","summary":"<p>Map of shard name to its tracked entry.</p>","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L44"},"def":{"name":"shards","return_type":"Hash(String, ShardEntry)","visibility":"Public","body":"@shards"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/AIDocsInfo/FileEntry","path":"Shards/AIDocsInfo/FileEntry.html","kind":"class","full_name":"Shards::AIDocsInfo::FileEntry","name":"FileEntry","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/ai_docs_info.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L20"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/AIDocsInfo","kind":"class","full_name":"Shards::AIDocsInfo","name":"AIDocsInfo"},"doc":"Represents a single tracked file with dual checksums.","summary":"<p>Represents a single tracked file with dual checksums.</p>","constructors":[{"html_id":"new(upstream_checksum:String,installed_checksum:String)-class-method","name":"new","abstract":false,"args":[{"name":"upstream_checksum","external_name":"upstream_checksum","restriction":"::String"},{"name":"installed_checksum","external_name":"installed_checksum","restriction":"::String"}],"args_string":"(upstream_checksum : String, installed_checksum : String)","args_html":"(upstream_checksum : String, installed_checksum : String)","location":{"filename":"src/ai_docs_info.cr","line_number":24,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L24"},"def":{"name":"new","args":[{"name":"upstream_checksum","external_name":"upstream_checksum","restriction":"::String"},{"name":"installed_checksum","external_name":"installed_checksum","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(upstream_checksum, installed_checksum)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"installed_checksum:String-instance-method","name":"installed_checksum","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L22"},"def":{"name":"installed_checksum","return_type":"String","visibility":"Public","body":"@installed_checksum"},"external_var":false},{"html_id":"installed_checksum=(installed_checksum:String)-instance-method","name":"installed_checksum=","abstract":false,"args":[{"name":"installed_checksum","external_name":"installed_checksum","restriction":"String"}],"args_string":"(installed_checksum : String)","args_html":"(installed_checksum : String)","location":{"filename":"src/ai_docs_info.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L22"},"def":{"name":"installed_checksum=","args":[{"name":"installed_checksum","external_name":"installed_checksum","restriction":"String"}],"visibility":"Public","body":"@installed_checksum = installed_checksum"},"external_var":false},{"html_id":"upstream_checksum:String-instance-method","name":"upstream_checksum","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":21,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L21"},"def":{"name":"upstream_checksum","return_type":"String","visibility":"Public","body":"@upstream_checksum"},"external_var":false},{"html_id":"upstream_checksum=(upstream_checksum:String)-instance-method","name":"upstream_checksum=","abstract":false,"args":[{"name":"upstream_checksum","external_name":"upstream_checksum","restriction":"String"}],"args_string":"(upstream_checksum : String)","args_html":"(upstream_checksum : String)","location":{"filename":"src/ai_docs_info.cr","line_number":21,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L21"},"def":{"name":"upstream_checksum=","args":[{"name":"upstream_checksum","external_name":"upstream_checksum","restriction":"String"}],"visibility":"Public","body":"@upstream_checksum = upstream_checksum"},"external_var":false},{"html_id":"user_modified?-instance-method","name":"user_modified?","doc":"Returns `true` if the installed file differs from the upstream version,\nindicating the user has made local modifications.","summary":"<p>Returns <code>true</code> if the installed file differs from the upstream version, indicating the user has made local modifications.</p>","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L29"},"def":{"name":"user_modified?","visibility":"Public","body":"upstream_checksum != installed_checksum"},"external_var":false}]},{"html_id":"Ashard/Shards/AIDocsInfo/ShardEntry","path":"Shards/AIDocsInfo/ShardEntry.html","kind":"class","full_name":"Shards::AIDocsInfo::ShardEntry","name":"ShardEntry","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/ai_docs_info.cr","line_number":35,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L35"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/AIDocsInfo","kind":"class","full_name":"Shards::AIDocsInfo","name":"AIDocsInfo"},"doc":"Tracks all AI doc files installed from a single shard.","summary":"<p>Tracks all AI doc files installed from a single shard.</p>","constructors":[{"html_id":"new(version:String,files:Hash(String,Shards::AIDocsInfo::FileEntry)=Hash(String,FileEntry).new)-class-method","name":"new","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"::String"},{"name":"files","default_value":"Hash(String, FileEntry).new","external_name":"files","restriction":"::Hash(::String, ::Shards::AIDocsInfo::FileEntry)"}],"args_string":"(version : String, files : Hash(String, Shards::AIDocsInfo::FileEntry) = Hash(String, FileEntry).new)","args_html":"(version : String, files : Hash(String, <a href=\"../../Shards/AIDocsInfo/FileEntry.html\">Shards::AIDocsInfo::FileEntry</a>) = <span class=\"t\">Hash</span>(<span class=\"t\">String</span>, <span class=\"t\">FileEntry</span>).new)","location":{"filename":"src/ai_docs_info.cr","line_number":39,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L39"},"def":{"name":"new","args":[{"name":"version","external_name":"version","restriction":"::String"},{"name":"files","default_value":"Hash(String, FileEntry).new","external_name":"files","restriction":"::Hash(::String, ::Shards::AIDocsInfo::FileEntry)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(version, files)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"files:Hash(String,FileEntry)-instance-method","name":"files","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":37,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L37"},"def":{"name":"files","return_type":"Hash(String, FileEntry)","visibility":"Public","body":"@files"},"external_var":false},{"html_id":"files=(files:Hash(String,FileEntry))-instance-method","name":"files=","abstract":false,"args":[{"name":"files","external_name":"files","restriction":"Hash(String, FileEntry)"}],"args_string":"(files : Hash(String, FileEntry))","args_html":"(files : Hash(String, <a href=\"../../Shards/AIDocsInfo/FileEntry.html\">FileEntry</a>))","location":{"filename":"src/ai_docs_info.cr","line_number":37,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L37"},"def":{"name":"files=","args":[{"name":"files","external_name":"files","restriction":"Hash(String, FileEntry)"}],"visibility":"Public","body":"@files = files"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/ai_docs_info.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L36"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/ai_docs_info.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs_info.cr#L36"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"},"external_var":false}]}]},{"html_id":"Ashard/Shards/AIDocsInstaller","path":"Shards/AIDocsInstaller.html","kind":"class","full_name":"Shards::AIDocsInstaller","name":"AIDocsInstaller","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/ai_docs.cr","line_number":39,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L39"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"SECURITY_SKIP_FILES","name":"SECURITY_SKIP_FILES","value":"[\".claude/settings.json\", \".claude/settings.local.json\"]","doc":"Settings files that are never distributed for security reasons.","summary":"<p>Settings files that are never distributed for security reasons.</p>"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Detects, installs, and manages AI documentation from shard dependencies.\n\nWhen dependencies are installed or updated, `AIDocsInstaller` scans each\npackage for AI-relevant files (skills, agents, commands, CLAUDE.md, etc.)\nand copies them into the project's `.claude/` directory with shard-namespaced\npaths to avoid conflicts.\n\nIt also handles MCP server configuration merging from `.mcp.json` files\nshipped by dependencies into a project-level `.mcp-shards.json`.\n\n## Auto-detected locations\n\nThe following paths are scanned in each dependency:\n- `.claude/skills/` -- Claude Code skill directories\n- `.claude/agents/` -- agent definition files\n- `.claude/commands/` -- slash command files\n- `CLAUDE.md` -- general AI context (converted to passive skill)\n- `AGENTS.md` -- agent specifications\n- `.mcp.json` -- MCP server configurations\n\n## Namespacing\n\nFiles are namespaced by shard name to prevent conflicts:\n- Skills: `<shard>--<name>`\n- Agents: `<shard>--<name>.md`\n- Commands: `<shard>:<name>.md`\n- MCP servers: `<shard>/<server_name>`\n\n## Conflict detection\n\nUses `AIDocsInfo` to track dual checksums per file. User-modified files\nare preserved during updates, with an `.upstream` copy saved for comparison.","summary":"<p>Detects, installs, and manages AI documentation from shard dependencies.</p>","constructors":[{"html_id":"new(project_path:String)-class-method","name":"new","abstract":false,"args":[{"name":"project_path","external_name":"project_path","restriction":"::String"}],"args_string":"(project_path : String)","args_html":"(project_path : String)","location":{"filename":"src/ai_docs.cr","line_number":46,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L46"},"def":{"name":"new","args":[{"name":"project_path","external_name":"project_path","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(project_path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"has_ai_docs?(package:Package):Bool-instance-method","name":"has_ai_docs?","doc":"Returns `true` if the package contains any auto-detectable AI docs\nor has explicit `ai_docs.include` entries in its spec.","summary":"<p>Returns <code>true</code> if the package contains any auto-detectable AI docs or has explicit <code>ai_docs.include</code> entries in its spec.</p>","abstract":false,"args":[{"name":"package","external_name":"package","restriction":"Package"}],"args_string":"(package : Package) : Bool","args_html":"(package : <a href=\"../Shards/Package.html\">Package</a>) : Bool","location":{"filename":"src/ai_docs.cr","line_number":91,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L91"},"def":{"name":"has_ai_docs?","args":[{"name":"package","external_name":"package","restriction":"Package"}],"return_type":"Bool","visibility":"Public","body":"shard_path = package.install_path\nif Dir.exists?(shard_path)\nelse\n  return false\nend\n\nai_docs = package.spec.ai_docs\n\n\nif Dir.exists?(File.join(shard_path, \".claude\", \"skills\"))\n  return true\nend\nif Dir.exists?(File.join(shard_path, \".claude\", \"agents\"))\n  return true\nend\nif Dir.exists?(File.join(shard_path, \".claude\", \"commands\"))\n  return true\nend\nif File.exists?(File.join(shard_path, \"CLAUDE.md\"))\n  return true\nend\nif File.exists?(File.join(shard_path, \"AGENTS.md\"))\n  return true\nend\nif File.exists?(File.join(shard_path, \".mcp.json\"))\n  return true\nend\n\n\nif ai_docs\n  if ai_docs.include.empty?\n  else\n    return true\n  end\nend\n\nfalse\n"},"external_var":false},{"html_id":"install(packages:Array(Package))-instance-method","name":"install","doc":"Installs AI documentation from the given packages into the project's\n`.claude/` directory. Skips packages without AI docs and respects\nthe `--skip-ai-docs` flag.","summary":"<p>Installs AI documentation from the given packages into the project's <code>.claude/</code> directory.</p>","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"args_string":"(packages : Array(Package))","args_html":"(packages : Array(<a href=\"../Shards/Package.html\">Package</a>))","location":{"filename":"src/ai_docs.cr","line_number":52,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L52"},"def":{"name":"install","args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"visibility":"Public","body":"if Shards.skip_ai_docs?\n  return\nend\n\npackages_with_docs = packages.select do |pkg| has_ai_docs?(pkg) end\nif packages_with_docs.empty?\n  return\nend\n\ninfo = Shards.ai_docs_info\n\npackages_with_docs.each do |package|\n  install_package_ai_docs(package, info)\nend\n\ninfo.save\n"},"external_var":false},{"html_id":"install_mcp_config(package:Package,mcp_json_path:String)-instance-method","name":"install_mcp_config","doc":"Installs MCP server configuration from a shard's `.mcp.json` into the\nproject's `.mcp-shards.json`. Server names are namespaced as\n`<shard>/<server_name>` and relative command/args paths are rewritten\nto point into `lib/<shard>/`.","summary":"<p>Installs MCP server configuration from a shard's <code>.mcp.json</code> into the project's <code>.mcp-shards.json</code>.</p>","abstract":false,"args":[{"name":"package","external_name":"package","restriction":"Package"},{"name":"mcp_json_path","external_name":"mcp_json_path","restriction":"String"}],"args_string":"(package : Package, mcp_json_path : String)","args_html":"(package : <a href=\"../Shards/Package.html\">Package</a>, mcp_json_path : String)","location":{"filename":"src/ai_docs.cr","line_number":329,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L329"},"def":{"name":"install_mcp_config","args":[{"name":"package","external_name":"package","restriction":"Package"},{"name":"mcp_json_path","external_name":"mcp_json_path","restriction":"String"}],"visibility":"Public","body":"shard_name = package.name\nmcp_shards_path = File.join(@project_path, \".mcp-shards.json\")\n\nbegin\n  source_config = JSON.parse(File.read(mcp_json_path))\nrescue ex\n  Log.warn do \"Failed to parse .mcp.json from #{shard_name}: #{ex.message}\" end\n  return\nend\n\nservers = source_config[\"mcpServers\"]?\nif servers && servers.as_h?\nelse\n  return\nend\n\n\nexisting = if File.exists?(mcp_shards_path)\n  begin\n    JSON.parse(File.read(mcp_shards_path))\n  rescue\n    JSON.parse(\"{\\\"mcpServers\\\": {}}\")\n  end\nelse\n  JSON.parse(\"{\\\"mcpServers\\\": {}}\")\nend\n\nmerged = (JSON.parse(existing.to_json)).as_h\nmerged_servers = (merged[\"mcpServers\"]?.try(&.as_h?) || ({} of String => JSON::Any)).dup\n\nservers.as_h.each do |server_name, config|\n  namespaced_name = \"#{shard_name}/#{server_name}\"\n  config_hash = config.as_h.dup\n\n\n  if command = config_hash[\"command\"]?.try(&.as_s?)\n    if (command.starts_with?(\"./\")) || (command.starts_with?(\"../\"))\n      config_hash[\"command\"] = JSON::Any.new(Path[\"lib\", shard_name, command].normalize.to_s)\n    end\n  end\n\n\n  if args = config_hash[\"args\"]?.try(&.as_a?)\n    rewritten_args = args.map do |arg|\n      str = arg.as_s?\n      if str && ((str.starts_with?(\"./\")) || (str.starts_with?(\"../\")))\n        JSON::Any.new(Path[\"lib\", shard_name, str].normalize.to_s)\n      else\n        arg\n      end\n    end\n    config_hash[\"args\"] = JSON::Any.new(rewritten_args)\n  end\n\n  merged_servers[namespaced_name] = JSON::Any.new(config_hash)\nend\n\nmerged[\"mcpServers\"] = JSON::Any.new(merged_servers)\n\nFile.write(mcp_shards_path, merged.to_pretty_json + \"\\n\")\nLog.info do \"MCP servers from #{shard_name} available in .mcp-shards.json\" end\n"},"external_var":false},{"html_id":"project_path:String-instance-method","name":"project_path","doc":"Root path of the project receiving AI docs.","summary":"<p>Root path of the project receiving AI docs.</p>","abstract":false,"location":{"filename":"src/ai_docs.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L44"},"def":{"name":"project_path","return_type":"String","visibility":"Public","body":"@project_path"},"external_var":false},{"html_id":"prune(removed_shard_names:Array(String))-instance-method","name":"prune","doc":"Removes all AI documentation files for the given shard names.\nCleans up skills, agents, commands, .upstream files, and MCP server entries.","summary":"<p>Removes all AI documentation files for the given shard names.</p>","abstract":false,"args":[{"name":"removed_shard_names","external_name":"removed_shard_names","restriction":"Array(String)"}],"args_string":"(removed_shard_names : Array(String))","args_html":"(removed_shard_names : Array(String))","location":{"filename":"src/ai_docs.cr","line_number":69,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ai_docs.cr#L69"},"def":{"name":"prune","args":[{"name":"removed_shard_names","external_name":"removed_shard_names","restriction":"Array(String)"}],"visibility":"Public","body":"if removed_shard_names.empty?\n  return\nend\n\ninfo = Shards.ai_docs_info\nclaude_dir = File.join(@project_path, \".claude\")\n\nremoved_shard_names.each do |shard_name|\n  prune_shard(shard_name, claude_dir)\n  info.shards.delete(shard_name)\nend\n\ninfo.save\n\n\nmcp_shards_path = File.join(@project_path, \".mcp-shards.json\")\nif File.exists?(mcp_shards_path)\n  prune_mcp_servers(removed_shard_names, mcp_shards_path)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Any","path":"Shards/Any.html","kind":"module","full_name":"Shards::Any","name":"Any","abstract":false,"locations":[{"filename":"src/requirement.cr","line_number":52,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L52"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"Ashard/Shards/Any","kind":"module","full_name":"Shards::Any","name":"Any"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"instance_methods":[{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/requirement.cr","line_number":55,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L55"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"io << \"*\""},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/requirement.cr","line_number":59,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L59"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":""},"external_var":false}]},{"html_id":"Ashard/Shards/AssistantConfig","path":"Shards/AssistantConfig.html","kind":"module","full_name":"Shards::AssistantConfig","name":"AssistantConfig","abstract":false,"locations":[{"filename":"src/assistant_config.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L7"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"COMPONENT_NAMES","name":"COMPONENT_NAMES","value":"[\"mcp\", \"skills\", \"agents\", \"settings\"] of ::String"},{"id":"MCP_SERVER_NAME","name":"MCP_SERVER_NAME","value":"\"shards-compliance\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"auto_install(path:String)-class-method","name":"auto_install","doc":"Called from install pipeline — auto-install or update as needed","summary":"<p>Called from install pipeline — auto-install or update as needed</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/assistant_config.cr","line_number":301,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L301"},"def":{"name":"auto_install","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"tracking_path = File.join(path, \".claude\", ASSISTANT_CONFIG_FILENAME)\ninfo = AssistantConfigInfo.new(tracking_path)\n\nif info.installed?\n  latest = AssistantVersions.latest_version\n  if info.installed_version < latest\n    Log.info do \"Updating assistant config to #{latest}\" end\n    update(path)\n  end\nelse\n  Log.info do \"Auto-installing assistant config\" end\n  install(path)\nend\n"},"external_var":false},{"html_id":"component_for(path:String):String-class-method","name":"component_for","doc":"Classify a file path into its component group.\nPaths may have ./ prefix from the build script.","summary":"<p>Classify a file path into its component group.</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : String","args_html":"(path : String) : String","location":{"filename":"src/assistant_config.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L14"},"def":{"name":"component_for","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"String","visibility":"Public","body":"normalized = path.lchop(\"./\")\nif normalized.starts_with?(\".claude/skills/\")\n  \"skills\"\nelsif normalized.starts_with?(\".claude/agents/\")\n  \"agents\"\nelsif (normalized == \".claude/settings.json\") || (normalized == \".claude/CLAUDE.md\")\n  \"settings\"\nelse\n  \"settings\"\nend\n"},"external_var":false},{"html_id":"filter_by_components(files:Hash(String,String),components:Hash(String,Bool)):Hash(String,String)-class-method","name":"filter_by_components","doc":"Filter files by enabled components","summary":"<p>Filter files by enabled components</p>","abstract":false,"args":[{"name":"files","external_name":"files","restriction":"Hash(String, String)"},{"name":"components","external_name":"components","restriction":"Hash(String, Bool)"}],"args_string":"(files : Hash(String, String), components : Hash(String, Bool)) : Hash(String, String)","args_html":"(files : Hash(String, String), components : Hash(String, Bool)) : Hash(String, String)","location":{"filename":"src/assistant_config.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L28"},"def":{"name":"filter_by_components","args":[{"name":"files","external_name":"files","restriction":"Hash(String, String)"},{"name":"components","external_name":"components","restriction":"Hash(String, Bool)"}],"return_type":"Hash(String, String)","visibility":"Public","body":"files.select do |path, _|\n  component = component_for(path)\n  components.fetch(component, true)\nend"},"external_var":false},{"html_id":"install(path:String,skip_components:Array(String)=[]ofString,force:Bool=false)-class-method","name":"install","doc":"Install assistant configuration files","summary":"<p>Install assistant configuration files</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"skip_components","default_value":"[] of String","external_name":"skip_components","restriction":"Array(String)"},{"name":"force","default_value":"false","external_name":"force","restriction":"Bool"}],"args_string":"(path : String, skip_components : Array(String) = [] of String, force : Bool = false)","args_html":"(path : String, skip_components : Array(String) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">String</span>, force : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/assistant_config.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L36"},"def":{"name":"install","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"skip_components","default_value":"[] of String","external_name":"skip_components","restriction":"Array(String)"},{"name":"force","default_value":"false","external_name":"force","restriction":"Bool"}],"visibility":"Public","body":"tracking_path = File.join(path, \".claude\", ASSISTANT_CONFIG_FILENAME)\ninfo = AssistantConfigInfo.new(tracking_path)\n\nif info.installed? && (!force)\n  Log.info do \"Assistant config already installed (version #{info.installed_version}). Use 'assistant update' to upgrade.\" end\n  return\nend\n\n\nif !info.installed? && (legacy_install?(path))\n  adopt_legacy(path, info, skip_components)\n  return\nend\n\ncomponents = {} of String => Bool\nCOMPONENT_NAMES.each do |name|\n  components[name] = !(skip_components.includes?(name))\nend\n\nall_files = AssistantVersions.current_files\nfiles_to_write = filter_by_components(all_files, components)\n\ninstalled = [] of String\n\nfiles_to_write.each do |relative_path, content|\n  full_path = File.join(path, relative_path)\n  dir = File.dirname(full_path)\n  if Dir.exists?(dir)\n  else\n    Dir.mkdir_p(dir)\n  end\n\n  if (File.exists?(full_path)) && (!force)\n    next\n  end\n\n  File.write(full_path, content)\n  installed << relative_path\nend\n\n\nif components.fetch(\"mcp\", true)\n  install_mcp_config(path)\nend\n\n\nfile_checksums = {} of String => String\nfiles_to_write.each do |relative_path, content|\n  full_path = File.join(path, relative_path)\n  if File.exists?(full_path)\n    file_checksums[relative_path] = AIDocsInfo.checksum(content)\n  end\nend\n\n\ninfo.installed_version = AssistantVersions.latest_version\ninfo.installed_at = Time.utc.to_rfc3339\ninfo.components = components\ninfo.files = file_checksums\ninfo.save\n\nprint_install_summary(installed, components)\n"},"external_var":false},{"html_id":"install_mcp_config(path:String)-class-method","name":"install_mcp_config","doc":"Install/merge MCP server entry into .mcp.json","summary":"<p>Install/merge MCP server entry into .mcp.json</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/assistant_config.cr","line_number":374,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L374"},"def":{"name":"install_mcp_config","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"mcp_path = File.join(path, \".mcp.json\")\nexecutable = find_executable\n\nserver_entry = {\"command\" => executable, \"args\" => [\"mcp-server\"]}\n\nif File.exists?(mcp_path)\n  begin\n    existing = JSON.parse(File.read(mcp_path))\n    servers = existing[\"mcpServers\"]?.try(&.as_h?) || ({} of String => JSON::Any)\n\n    if servers.has_key?(MCP_SERVER_NAME)\n      return\n    end\n\n    servers[MCP_SERVER_NAME] = JSON.parse(server_entry.to_json)\n    config = existing.as_h.dup\n    config[\"mcpServers\"] = JSON.parse(servers.to_json)\n\n    File.write(mcp_path, config.to_pretty_json + \"\\n\")\n  rescue ex\n    write_new_mcp_config(mcp_path, server_entry)\n  end\nelse\n  write_new_mcp_config(mcp_path, server_entry)\nend\n"},"external_var":false},{"html_id":"legacy_install?(path:String):Bool-class-method","name":"legacy_install?","doc":"Detect legacy mcp-server init installs (files exist but no tracking YAML)","summary":"<p>Detect legacy mcp-server init installs (files exist but no tracking YAML)</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : Bool","args_html":"(path : String) : Bool","location":{"filename":"src/assistant_config.cr","line_number":318,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L318"},"def":{"name":"legacy_install?","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"Bool","visibility":"Public","body":"tracking_path = File.join(path, \".claude\", ASSISTANT_CONFIG_FILENAME)\nif File.exists?(tracking_path)\n  return false\nend\n\n\n(File.exists?(File.join(path, \".claude\", \"CLAUDE.md\"))) ||\n(File.exists?(File.join(path, \".claude\", \"settings.json\")))\n"},"external_var":false},{"html_id":"remove(path:String)-class-method","name":"remove","doc":"Remove all tracked assistant config files","summary":"<p>Remove all tracked assistant config files</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/assistant_config.cr","line_number":267,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L267"},"def":{"name":"remove","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"tracking_path = File.join(path, \".claude\", ASSISTANT_CONFIG_FILENAME)\ninfo = AssistantConfigInfo.new(tracking_path)\n\nif info.installed?\nelse\n  puts(\"No assistant config installed.\")\n  return\nend\n\nremoved = [] of String\ninfo.files.each_key do |relative_path|\n  full_path = File.join(path, relative_path)\n  if File.exists?(full_path)\n    File.delete(full_path)\n    removed << relative_path\n\n\n    upstream_path = \"#{full_path}.upstream\"\n    if File.exists?(upstream_path)\n      File.delete(upstream_path)\n    end\n  end\nend\n\n\ncleanup_empty_dirs(File.join(path, \".claude\", \"skills\"))\ncleanup_empty_dirs(File.join(path, \".claude\", \"agents\"))\n\n\nif File.exists?(tracking_path)\n  File.delete(tracking_path)\nend\n\nputs(\"Removed #{removed.size} assistant config file(s).\")\nputs(\"Note: .mcp.json was not modified. Remove the '#{MCP_SERVER_NAME}' entry manually if desired.\")\n"},"external_var":false},{"html_id":"status(path:String)-class-method","name":"status","doc":"Show status of installed assistant config","summary":"<p>Show status of installed assistant config</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/assistant_config.cr","line_number":219,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L219"},"def":{"name":"status","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"tracking_path = File.join(path, \".claude\", ASSISTANT_CONFIG_FILENAME)\ninfo = AssistantConfigInfo.new(tracking_path)\n\nif info.installed?\nelse\n  puts(\"No assistant config installed.\")\n  puts(\"Run 'shards assistant init' to set up Claude Code skills, agents, and settings.\")\n  return\nend\n\nlatest = AssistantVersions.latest_version\nputs(\"Assistant: #{info.assistant}\")\nputs(\"Installed version: #{info.installed_version}\")\nputs(\"Latest version:    #{latest}\")\nputs(\"Installed at:      #{info.installed_at}\")\n\nif info.installed_version != latest\n  puts(\"Status:            Update available\")\nelse\n  puts(\"Status:            Up to date\")\nend\n\nputs(\"\")\nputs(\"Components:\")\ninfo.components.each do |name, enabled|\n  puts(\"  #{name}: #{enabled ? \"enabled\" : \"disabled\"}\")\nend\n\n\nmodified = [] of String\ninfo.files.each do |relative_path, tracked_checksum|\n  full_path = File.join(path, relative_path)\n  if File.exists?(full_path)\n    disk_checksum = AIDocsInfo.checksum_file(full_path)\n    if disk_checksum != tracked_checksum\n      modified << relative_path\n    end\n  end\nend\n\nif modified.empty?\nelse\n  puts(\"\")\n  puts(\"Modified locally (#{modified.size}):\")\n  modified.each do |f| puts(\"  #{f}\") end\nend\n"},"external_var":false},{"html_id":"update(path:String,force:Bool=false,dry_run:Bool=false)-class-method","name":"update","doc":"Update assistant configuration files","summary":"<p>Update assistant configuration files</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"force","default_value":"false","external_name":"force","restriction":"Bool"},{"name":"dry_run","default_value":"false","external_name":"dry_run","restriction":"Bool"}],"args_string":"(path : String, force : Bool = false, dry_run : Bool = false)","args_html":"(path : String, force : Bool = <span class=\"n\">false</span>, dry_run : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/assistant_config.cr","line_number":99,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config.cr#L99"},"def":{"name":"update","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"force","default_value":"false","external_name":"force","restriction":"Bool"},{"name":"dry_run","default_value":"false","external_name":"dry_run","restriction":"Bool"}],"visibility":"Public","body":"tracking_path = File.join(path, \".claude\", ASSISTANT_CONFIG_FILENAME)\ninfo = AssistantConfigInfo.new(tracking_path)\n\nif info.installed?\nelse\n  Log.error do \"No assistant config installed. Run 'shards assistant init' first.\" end\n  return\nend\n\nlatest = AssistantVersions.latest_version\nif (info.installed_version == latest) && (!force)\n  puts(\"Assistant config is up to date (version #{latest}).\")\n  return\nend\n\nchanged_files = if force\n  AssistantVersions.current_files\nelse\n  AssistantVersions.files_changed_since(info.installed_version)\nend\n\nfiles_to_write = filter_by_components(changed_files, info.components)\n\nif files_to_write.empty?\n  puts(\"No files to update.\")\n  return\nend\n\nupdated = [] of String\nskipped = [] of String\nupstream_saved = [] of String\n\nfiles_to_write.each do |relative_path, content|\n  full_path = File.join(path, relative_path)\n\n  if dry_run\n    if File.exists?(full_path)\n      tracked_checksum = info.files[relative_path]?\n      disk_checksum = AIDocsInfo.checksum_file(full_path)\n      if (tracked_checksum && (tracked_checksum != disk_checksum)) && (!force)\n        puts(\"  skip (modified): #{relative_path}\")\n        skipped << relative_path\n      else\n        puts(\"  update: #{relative_path}\")\n        updated << relative_path\n      end\n    else\n      puts(\"  create: #{relative_path}\")\n      updated << relative_path\n    end\n    next\n  end\n\n  dir = File.dirname(full_path)\n  if Dir.exists?(dir)\n  else\n    Dir.mkdir_p(dir)\n  end\n\n  if File.exists?(full_path)\n    tracked_checksum = info.files[relative_path]?\n    disk_checksum = AIDocsInfo.checksum_file(full_path)\n\n    if (tracked_checksum && (tracked_checksum != disk_checksum)) && (!force)\n      upstream_path = \"#{full_path}.upstream\"\n      File.write(upstream_path, content)\n      skipped << relative_path\n      upstream_saved << relative_path\n      next\n    end\n  end\n\n  File.write(full_path, content)\n  updated << relative_path\nend\n\nif dry_run\nelse\n  if info.components.fetch(\"mcp\", true)\n    install_mcp_config(path)\n  end\n\n\n  all_files = AssistantVersions.current_files\n  file_checksums = {} of String => String\n  (filter_by_components(all_files, info.components)).each do |relative_path, content|\n    full_path = File.join(path, relative_path)\n    if File.exists?(full_path)\n      if updated.includes?(relative_path)\n        file_checksums[relative_path] = AIDocsInfo.checksum(content)\n      elsif info.files.has_key?(relative_path)\n        file_checksums[relative_path] = info.files[relative_path]\n      else\n        file_checksums[relative_path] = AIDocsInfo.checksum_file(full_path)\n      end\n    end\n  end\n\n  info.installed_version = latest\n  info.installed_at = Time.utc.to_rfc3339\n  info.files = file_checksums\n  info.save\nend\n\nif dry_run\n  puts(\"\")\n  puts(\"Dry run: #{updated.size} file(s) would be updated, #{skipped.size} skipped (modified locally).\")\nelse\n  puts(\"Updated #{updated.size} file(s) to version #{latest}.\")\n  if skipped.empty?\n  else\n    puts(\"Skipped #{skipped.size} locally modified file(s):\")\n    skipped.each do |f| puts(\"  #{f}\") end\n    if upstream_saved.empty?\n    else\n      puts(\"Upstream versions saved as .upstream files.\")\n    end\n  end\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/AssistantConfigInfo","path":"Shards/AssistantConfigInfo.html","kind":"class","full_name":"Shards::AssistantConfigInfo","name":"AssistantConfigInfo","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/assistant_config_info.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L10"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CURRENT_VERSION","name":"CURRENT_VERSION","value":"\"1.0\""},{"id":"FILENAME","name":"FILENAME","value":"\".assistant-config.yml\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Tracks the installed assistant configuration state.\n\nPersisted at `.claude/.assistant-config.yml`, this tracker stores\nwhich version is installed, which components are enabled, and\nper-file checksums for detecting user modifications during upgrades.","summary":"<p>Tracks the installed assistant configuration state.</p>","constructors":[{"html_id":"new(path:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/assistant_config_info.cr","line_number":21,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L21"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"assistant:String-instance-method","name":"assistant","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L16"},"def":{"name":"assistant","return_type":"String","visibility":"Public","body":"@assistant"},"external_var":false},{"html_id":"assistant=(assistant:String)-instance-method","name":"assistant=","abstract":false,"args":[{"name":"assistant","external_name":"assistant","restriction":"String"}],"args_string":"(assistant : String)","args_html":"(assistant : String)","location":{"filename":"src/assistant_config_info.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L16"},"def":{"name":"assistant=","args":[{"name":"assistant","external_name":"assistant","restriction":"String"}],"visibility":"Public","body":"@assistant = assistant"},"external_var":false},{"html_id":"components:Hash(String,Bool)-instance-method","name":"components","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L18"},"def":{"name":"components","return_type":"Hash(String, Bool)","visibility":"Public","body":"@components"},"external_var":false},{"html_id":"components=(components:Hash(String,Bool))-instance-method","name":"components=","abstract":false,"args":[{"name":"components","external_name":"components","restriction":"Hash(String, Bool)"}],"args_string":"(components : Hash(String, Bool))","args_html":"(components : Hash(String, Bool))","location":{"filename":"src/assistant_config_info.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L18"},"def":{"name":"components=","args":[{"name":"components","external_name":"components","restriction":"Hash(String, Bool)"}],"visibility":"Public","body":"@components = components"},"external_var":false},{"html_id":"files:Hash(String,String)-instance-method","name":"files","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L19"},"def":{"name":"files","return_type":"Hash(String, String)","visibility":"Public","body":"@files"},"external_var":false},{"html_id":"files=(files:Hash(String,String))-instance-method","name":"files=","abstract":false,"args":[{"name":"files","external_name":"files","restriction":"Hash(String, String)"}],"args_string":"(files : Hash(String, String))","args_html":"(files : Hash(String, String))","location":{"filename":"src/assistant_config_info.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L19"},"def":{"name":"files=","args":[{"name":"files","external_name":"files","restriction":"Hash(String, String)"}],"visibility":"Public","body":"@files = files"},"external_var":false},{"html_id":"installed?:Bool-instance-method","name":"installed?","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":108,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L108"},"def":{"name":"installed?","return_type":"Bool","visibility":"Public","body":"!@installed_version.empty?"},"external_var":false},{"html_id":"installed_at:String-instance-method","name":"installed_at","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L17"},"def":{"name":"installed_at","return_type":"String","visibility":"Public","body":"@installed_at"},"external_var":false},{"html_id":"installed_at=(installed_at:String)-instance-method","name":"installed_at=","abstract":false,"args":[{"name":"installed_at","external_name":"installed_at","restriction":"String"}],"args_string":"(installed_at : String)","args_html":"(installed_at : String)","location":{"filename":"src/assistant_config_info.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L17"},"def":{"name":"installed_at=","args":[{"name":"installed_at","external_name":"installed_at","restriction":"String"}],"visibility":"Public","body":"@installed_at = installed_at"},"external_var":false},{"html_id":"installed_version:String-instance-method","name":"installed_version","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L15"},"def":{"name":"installed_version","return_type":"String","visibility":"Public","body":"@installed_version"},"external_var":false},{"html_id":"installed_version=(installed_version:String)-instance-method","name":"installed_version=","abstract":false,"args":[{"name":"installed_version","external_name":"installed_version","restriction":"String"}],"args_string":"(installed_version : String)","args_html":"(installed_version : String)","location":{"filename":"src/assistant_config_info.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L15"},"def":{"name":"installed_version=","args":[{"name":"installed_version","external_name":"installed_version","restriction":"String"}],"visibility":"Public","body":"@installed_version = installed_version"},"external_var":false},{"html_id":"load-instance-method","name":"load","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L30"},"def":{"name":"load","visibility":"Public","body":"begin\n  content = File.read(@path)\n  pull = YAML::PullParser.new(content)\n  pull.read_stream do\n    pull.read_document do\n      pull.each_in_mapping do\n        case pull.read_scalar\n        when \"version\"\n          pull.read_scalar\n        when \"installed_version\"\n          @installed_version = pull.read_scalar\n        when \"assistant\"\n          @assistant = pull.read_scalar\n        when \"installed_at\"\n          @installed_at = pull.read_scalar\n        when \"components\"\n          pull.each_in_mapping do\n            name = pull.read_scalar\n            @components[name] = pull.read_scalar == \"true\"\n          end\n        when \"files\"\n          pull.each_in_mapping do\n            file_path = pull.read_scalar\n            checksum = \"\"\n            pull.each_in_mapping do\n              case pull.read_scalar\n              when \"checksum\"\n                checksum = pull.read_scalar\n              else\n                pull.skip\n              end\n            end\n            @files[file_path] = checksum\n          end\n        else\n          pull.skip\n        end\n      end\n    end\n  end\nensure\n  pull.try(&.close)\nend"},"external_var":false},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L14"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"@path"},"external_var":false},{"html_id":"save-instance-method","name":"save","abstract":false,"location":{"filename":"src/assistant_config_info.cr","line_number":67,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_config_info.cr#L67"},"def":{"name":"save","visibility":"Public","body":"Dir.mkdir_p(File.dirname(@path))\n\nFile.open(@path, \"w\") do |file|\n  YAML.build(file) do |yaml|\n    yaml.mapping do\n      yaml.scalar(\"version\")\n      yaml.scalar(CURRENT_VERSION)\n\n      yaml.scalar(\"installed_version\")\n      yaml.scalar(@installed_version)\n\n      yaml.scalar(\"assistant\")\n      yaml.scalar(@assistant)\n\n      yaml.scalar(\"installed_at\")\n      yaml.scalar(@installed_at)\n\n      yaml.scalar(\"components\")\n      yaml.mapping do\n        @components.each do |name, enabled|\n          yaml.scalar(name)\n          yaml.scalar(enabled.to_s)\n        end\n      end\n\n      yaml.scalar(\"files\")\n      yaml.mapping do\n        @files.each do |path, checksum|\n          yaml.scalar(path)\n          yaml.mapping do\n            yaml.scalar(\"checksum\")\n            yaml.scalar(checksum)\n          end\n        end\n      end\n    end\n  end\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/AssistantVersions","path":"Shards/AssistantVersions.html","kind":"module","full_name":"Shards::AssistantVersions","name":"AssistantVersions","abstract":false,"locations":[{"filename":"src/assistant_versions.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_versions.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VERSIONS","name":"VERSIONS","value":"{{ run(\"./build_assistant_versions\") }}","doc":"Embedded at compile time by walking src/assistant_versions/","summary":"<p>Embedded at compile time by walking src/assistant_versions/</p>"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"all_versions:Array(String)-class-method","name":"all_versions","abstract":false,"location":{"filename":"src/assistant_versions.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_versions.cr#L29"},"def":{"name":"all_versions","return_type":"Array(String)","visibility":"Public","body":"VERSIONS.keys.sort"},"external_var":false},{"html_id":"current_files:Hash(String,String)-class-method","name":"current_files","doc":"Build current file state by overlaying all versions oldest-to-newest","summary":"<p>Build current file state by overlaying all versions oldest-to-newest</p>","abstract":false,"location":{"filename":"src/assistant_versions.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_versions.cr#L7"},"def":{"name":"current_files","return_type":"Hash(String, String)","visibility":"Public","body":"result = {} of String => String\nVERSIONS.keys.sort.each do |version|\n  VERSIONS[version].each do |path, content| result[path] = content end\nend\nresult\n"},"external_var":false},{"html_id":"files_changed_since(since_version:String):Hash(String,String)-class-method","name":"files_changed_since","doc":"Get only files that changed since a given version","summary":"<p>Get only files that changed since a given version</p>","abstract":false,"args":[{"name":"since_version","external_name":"since_version","restriction":"String"}],"args_string":"(since_version : String) : Hash(String, String)","args_html":"(since_version : String) : Hash(String, String)","location":{"filename":"src/assistant_versions.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_versions.cr#L16"},"def":{"name":"files_changed_since","args":[{"name":"since_version","external_name":"since_version","restriction":"String"}],"return_type":"Hash(String, String)","visibility":"Public","body":"result = {} of String => String\nVERSIONS.keys.sort.each do |version|\n  if version <= since_version\n    next\n  end\n  VERSIONS[version].each do |path, content| result[path] = content end\nend\nresult\n"},"external_var":false},{"html_id":"latest_version:String-class-method","name":"latest_version","abstract":false,"location":{"filename":"src/assistant_versions.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/assistant_versions.cr#L25"},"def":{"name":"latest_version","return_type":"String","visibility":"Public","body":"VERSIONS.keys.sort.last"},"external_var":false}]},{"html_id":"Ashard/Shards/ChangeLogger","path":"Shards/ChangeLogger.html","kind":"class","full_name":"Shards::ChangeLogger","name":"ChangeLogger","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/change_logger.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/change_logger.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"AUDIT_DIR","name":"AUDIT_DIR","value":"\".shards/audit\""},{"id":"LOG_FILE","name":"LOG_FILE","value":"\"changelog.json\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"load(project_path:String):Array(JSON::Any)-class-method","name":"load","abstract":false,"args":[{"name":"project_path","external_name":"project_path","restriction":"String"}],"args_string":"(project_path : String) : Array(JSON::Any)","args_html":"(project_path : String) : Array(JSON::Any)","location":{"filename":"src/change_logger.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/change_logger.cr#L30"},"def":{"name":"load","args":[{"name":"project_path","external_name":"project_path","restriction":"String"}],"return_type":"Array(JSON::Any)","visibility":"Public","body":"begin\n  log_path = File.join(project_path, AUDIT_DIR, LOG_FILE)\n  if File.exists?(log_path)\n  else\n    return [] of JSON::Any\n  end\n\n  parsed = JSON.parse(File.read(log_path))\n  if entries = parsed[\"entries\"]?\n    entries.as_a\n  else\n    [] of JSON::Any\n  end\nrescue\n  [] of JSON::Any\nend"},"external_var":false},{"html_id":"record(project_path:String,action:String,old_packages:Array(Package),new_packages:Array(Package),lockfile_path:String):Nil-class-method","name":"record","abstract":false,"args":[{"name":"project_path","external_name":"project_path","restriction":"String"},{"name":"action","external_name":"action","restriction":"String"},{"name":"old_packages","external_name":"old_packages","restriction":"Array(Package)"},{"name":"new_packages","external_name":"new_packages","restriction":"Array(Package)"},{"name":"lockfile_path","external_name":"lockfile_path","restriction":"String"}],"args_string":"(project_path : String, action : String, old_packages : Array(Package), new_packages : Array(Package), lockfile_path : String) : Nil","args_html":"(project_path : String, action : String, old_packages : Array(<a href=\"../Shards/Package.html\">Package</a>), new_packages : Array(<a href=\"../Shards/Package.html\">Package</a>), lockfile_path : String) : Nil","location":{"filename":"src/change_logger.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/change_logger.cr#L10"},"def":{"name":"record","args":[{"name":"project_path","external_name":"project_path","restriction":"String"},{"name":"action","external_name":"action","restriction":"String"},{"name":"old_packages","external_name":"old_packages","restriction":"Array(Package)"},{"name":"new_packages","external_name":"new_packages","restriction":"Array(Package)"},{"name":"lockfile_path","external_name":"lockfile_path","restriction":"String"}],"return_type":"Nil","visibility":"Public","body":"begin\n  changes = LockfileDiffer.diff(old_packages, new_packages)\n\n  actual = changes.reject do |c| c.status == LockfileDiffer::Status::Unchanged end\n  if actual.empty?\n    return\n  end\n\n  entry = build_entry(action, actual, lockfile_path)\n  entries = load(project_path)\n  entries << entry\n  write_log(project_path, entries)\nrescue ex\n  Log.warn do \"Could not write audit log: #{ex.message}\" end\nend"},"external_var":false}]},{"html_id":"Ashard/Shards/Checksum","path":"Shards/Checksum.html","kind":"module","full_name":"Shards::Checksum","name":"Checksum","abstract":false,"locations":[{"filename":"src/checksum.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/checksum.cr#L4"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"ALGORITHM_PREFIX","name":"ALGORITHM_PREFIX","value":"\"sha256\""},{"id":"EXCLUDED_DIRS","name":"EXCLUDED_DIRS","value":"{\".git\", \".hg\", \".fossil\", \".fslckout\", \"_FOSSIL_\"}"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"compute(path:String):String-class-method","name":"compute","doc":"Compute a deterministic SHA-256 checksum for a directory of source files.\nReturns a string like \"sha256:abcdef1234...\"","summary":"<p>Compute a deterministic SHA-256 checksum for a directory of source files.</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : String","args_html":"(path : String) : String","location":{"filename":"src/checksum.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/checksum.cr#L10"},"def":{"name":"compute","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"String","visibility":"Public","body":"digest = Digest::SHA256.new\nfiles = collect_files(path)\nfiles.sort!\n\nfiles.each do |relative_path|\n  full_path = File.join(path, relative_path)\n  content = File.read(full_path)\n\n  digest.update(relative_path)\n  digest.update(\"\\u0000\")\n  digest.update(content.bytesize.to_s)\n  digest.update(\"\\u0000\")\n  digest.update(content)\nend\n\n\"#{ALGORITHM_PREFIX}:#{digest.final.hexstring}\"\n"},"external_var":false},{"html_id":"verify(path:String,expected:String):Bool-class-method","name":"verify","doc":"Verify a checksum against a directory.\nReturns true if match, false if mismatch.","summary":"<p>Verify a checksum against a directory.</p>","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"expected","external_name":"expected","restriction":"String"}],"args_string":"(path : String, expected : String) : Bool","args_html":"(path : String, expected : String) : Bool","location":{"filename":"src/checksum.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/checksum.cr#L31"},"def":{"name":"verify","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"expected","external_name":"expected","restriction":"String"}],"return_type":"Bool","visibility":"Public","body":"(compute(path)) == expected"},"external_var":false}]},{"html_id":"Ashard/Shards/ChecksumMismatch","path":"Shards/ChecksumMismatch.html","kind":"class","full_name":"Shards::ChecksumMismatch","name":"ChecksumMismatch","abstract":false,"superclass":{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},"ancestors":[{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/errors.cr","line_number":71,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L71"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(package_name:String,expected:String,actual:String)-class-method","name":"new","abstract":false,"args":[{"name":"package_name","external_name":"package_name","restriction":"String"},{"name":"expected","external_name":"expected","restriction":"String"},{"name":"actual","external_name":"actual","restriction":"String"}],"args_string":"(package_name : String, expected : String, actual : String)","args_html":"(package_name : String, expected : String, actual : String)","location":{"filename":"src/errors.cr","line_number":72,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L72"},"def":{"name":"new","args":[{"name":"package_name","external_name":"package_name","restriction":"String"},{"name":"expected","external_name":"expected","restriction":"String"},{"name":"actual","external_name":"actual","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(package_name, expected, actual)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}]},{"html_id":"Ashard/Shards/ClaudeConfig","path":"Shards/ClaudeConfig.html","kind":"module","full_name":"Shards::ClaudeConfig","name":"ClaudeConfig","abstract":false,"locations":[{"filename":"src/mcp/claude_config.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/claude_config.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"AGENT_COMPLIANCE_CHECKER","name":"AGENT_COMPLIANCE_CHECKER","value":"\"---\\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.\""},{"id":"AGENT_SECURITY_REVIEWER","name":"AGENT_SECURITY_REVIEWER","value":"\"---\\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.\""},{"id":"CLAUDE_MD","name":"CLAUDE_MD","value":"\"# 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.\""},{"id":"FILES","name":"FILES","value":"{\".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}"},{"id":"REF_AI_DOCS","name":"REF_AI_DOCS","value":"\"# 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/<name>/` | Claude Code skills |\\n| `.claude/agents/<name>.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/<name>/` | `.claude/skills/<shard>--<name>/` |\\n| `.claude/agents/<name>.md` | `.claude/agents/<shard>--<name>.md` |\\n| `CLAUDE.md` | `.claude/skills/<shard>--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 <shard>`\\n- **Reset to upstream**: `shards ai-docs reset <shard>`\""},{"id":"REF_COMMANDS","name":"REF_COMMANDS","value":"\"# 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```\""},{"id":"REF_SHARD_YML","name":"REF_SHARD_YML","value":"\"# 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 <email@example.com>\\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: <url>` | Any git repository URL |\\n| `path: <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```\""},{"id":"SETTINGS_JSON","name":"SETTINGS_JSON","value":"\"{\\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}\""},{"id":"SKILL_AUDIT","name":"SKILL_AUDIT","value":"\"---\\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```\""},{"id":"SKILL_COMPLIANCE_REPORT","name":"SKILL_COMPLIANCE_REPORT","value":"\"---\\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```\""},{"id":"SKILL_DIFF_DEPS","name":"SKILL_DIFF_DEPS","value":"\"---\\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```\""},{"id":"SKILL_LICENSES","name":"SKILL_LICENSES","value":"\"---\\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```\""},{"id":"SKILL_POLICY_CHECK","name":"SKILL_POLICY_CHECK","value":"\"---\\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```\""},{"id":"SKILL_SBOM","name":"SKILL_SBOM","value":"\"---\\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```\""},{"id":"SKILL_SHARDS_CLI","name":"SKILL_SHARDS_CLI","value":"\"---\\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)\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"install(path:String):Array(String)-class-method","name":"install","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : Array(String)","args_html":"(path : String) : Array(String)","location":{"filename":"src/mcp/claude_config.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/claude_config.cr#L25"},"def":{"name":"install","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"Array(String)","visibility":"Public","body":"installed = [] of String\n\nFILES.each do |relative_path, content|\n  full_path = File.join(path, relative_path)\n  dir = File.dirname(full_path)\n  if Dir.exists?(dir)\n  else\n    Dir.mkdir_p(dir)\n  end\n\n  if File.exists?(full_path)\n    next\n  end\n\n  File.write(full_path, content)\n  installed << relative_path\nend\n\ninstalled\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Command","path":"Shards/Command.html","kind":"class","full_name":"Shards::Command","name":"Command","abstract":true,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/command.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L9"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/Commands/AIDocs","kind":"class","full_name":"Shards::Commands::AIDocs","name":"AIDocs"},{"html_id":"Ashard/Shards/Commands/Audit","kind":"class","full_name":"Shards::Commands::Audit","name":"Audit"},{"html_id":"Ashard/Shards/Commands/Build","kind":"class","full_name":"Shards::Commands::Build","name":"Build"},{"html_id":"Ashard/Shards/Commands/Check","kind":"class","full_name":"Shards::Commands::Check","name":"Check"},{"html_id":"Ashard/Shards/Commands/ComplianceReport","kind":"class","full_name":"Shards::Commands::ComplianceReport","name":"ComplianceReport"},{"html_id":"Ashard/Shards/Commands/Diff","kind":"class","full_name":"Shards::Commands::Diff","name":"Diff"},{"html_id":"Ashard/Shards/Commands/Docs","kind":"class","full_name":"Shards::Commands::Docs","name":"Docs"},{"html_id":"Ashard/Shards/Commands/Init","kind":"class","full_name":"Shards::Commands::Init","name":"Init"},{"html_id":"Ashard/Shards/Commands/Install","kind":"class","full_name":"Shards::Commands::Install","name":"Install"},{"html_id":"Ashard/Shards/Commands/Licenses","kind":"class","full_name":"Shards::Commands::Licenses","name":"Licenses"},{"html_id":"Ashard/Shards/Commands/List","kind":"class","full_name":"Shards::Commands::List","name":"List"},{"html_id":"Ashard/Shards/Commands/Lock","kind":"class","full_name":"Shards::Commands::Lock","name":"Lock"},{"html_id":"Ashard/Shards/Commands/MCP","kind":"class","full_name":"Shards::Commands::MCP","name":"MCP"},{"html_id":"Ashard/Shards/Commands/Outdated","kind":"class","full_name":"Shards::Commands::Outdated","name":"Outdated"},{"html_id":"Ashard/Shards/Commands/Policy","kind":"class","full_name":"Shards::Commands::Policy","name":"Policy"},{"html_id":"Ashard/Shards/Commands/Prune","kind":"class","full_name":"Shards::Commands::Prune","name":"Prune"},{"html_id":"Ashard/Shards/Commands/Run","kind":"class","full_name":"Shards::Commands::Run","name":"Run"},{"html_id":"Ashard/Shards/Commands/RunScript","kind":"class","full_name":"Shards::Commands::RunScript","name":"RunScript"},{"html_id":"Ashard/Shards/Commands/SBOM","kind":"class","full_name":"Shards::Commands::SBOM","name":"SBOM"},{"html_id":"Ashard/Shards/Commands/Update","kind":"class","full_name":"Shards::Commands::Update","name":"Update"},{"html_id":"Ashard/Shards/Commands/Version","kind":"class","full_name":"Shards::Commands::Version","name":"Version"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"run(path,*args,**kwargs)-class-method","name":"run","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""},{"name":"args","external_name":"args","restriction":""}],"args_string":"(path, *args, **kwargs)","args_html":"(path, *args, **kwargs)","location":{"filename":"src/commands/command.cr","line_number":38,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L38"},"def":{"name":"run","args":[{"name":"path","external_name":"path","restriction":""},{"name":"args","external_name":"args","restriction":""}],"double_splat":{"name":"kwargs","external_name":"kwargs","restriction":""},"splat_index":1,"visibility":"Public","body":"(new(path)).run(*args, **kwargs)"},"external_var":false}],"constructors":[{"html_id":"new(path)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""}],"args_string":"(path)","args_html":"(path)","location":{"filename":"src/commands/command.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L19"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"check_crystal_version(packages)-instance-method","name":"check_crystal_version","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":""}],"args_string":"(packages)","args_html":"(packages)","location":{"filename":"src/commands/command.cr","line_number":86,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L86"},"def":{"name":"check_crystal_version","args":[{"name":"packages","external_name":"packages","restriction":""}],"visibility":"Public","body":"crystal_version = Shards::Version.new(Shards.crystal_version)\n\npackages.each do |package|\n  crystal_req = MolinilloSolver.crystal_version_req(package.spec)\n\n  if !(Shards::Versions.matches?(crystal_version, crystal_req))\n    Log.warn do \"Shard \\\"#{package.name}\\\" may be incompatible with Crystal #{Shards.crystal_version}\" end\n  end\nend\n"},"external_var":false},{"html_id":"check_symlink_privilege-instance-method","name":"check_symlink_privilege","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":98,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L98"},"def":{"name":"check_symlink_privilege","visibility":"Public","body":"{% if flag?(:win32) %}\n        return if Shards::Helpers.developer_mode?\n        return if Shards::Helpers.privilege_enabled?(\"SeCreateSymbolicLinkPrivilege\")\n\n        raise Shards::Error.new(<<-EOS)\n        Shards needs symlinks to work. Please enable Developer Mode, or run Shards with elevated rights:\n            https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development\n        EOS\n      {% end %}"},"external_var":false},{"html_id":"handle_resolver_errors(&)-instance-method","name":"handle_resolver_errors","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":79,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L79"},"def":{"name":"handle_resolver_errors","yields":0,"block_arity":0,"visibility":"Public","body":"begin\n  yield\nrescue e : Molinillo::ResolverError\n  Log.error do e.message end\n  raise(Shards::Error.new(\"Failed to resolve dependencies\"))\nend"},"external_var":false},{"html_id":"lockfile?-instance-method","name":"lockfile?","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":62,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L62"},"def":{"name":"lockfile?","visibility":"Public","body":"File.exists?(lockfile_path)"},"external_var":false},{"html_id":"lockfile_path:String-instance-method","name":"lockfile_path","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L12"},"def":{"name":"lockfile_path","return_type":"String","visibility":"Public","body":"@lockfile_path"},"external_var":false},{"html_id":"locks-instance-method","name":"locks","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":54,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L54"},"def":{"name":"locks","visibility":"Public","body":"@locks || (\n  @locks = if lockfile?\n    Shards::Lock.from_file(lockfile_path)\n  else\n    raise(Error.new(\"Missing #{LOCK_FILENAME}. Please run 'shards install'\"))\n  end\n)"},"external_var":false},{"html_id":"override-instance-method","name":"override","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":66,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L66"},"def":{"name":"override","visibility":"Public","body":"@override || (@override = override_path.try do |p| Shards::Override.from_file(p) end)"},"external_var":false},{"html_id":"override_path:String|Nil-instance-method","name":"override_path","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L13"},"def":{"name":"override_path","return_type":"String | ::Nil","visibility":"Public","body":"@override_path"},"external_var":false},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L10"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"@path"},"external_var":false},{"html_id":"spec-instance-method","name":"spec","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":42,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L42"},"def":{"name":"spec","visibility":"Public","body":"@spec || (\n  @spec = if File.exists?(spec_path)\n    Spec.from_file(spec_path)\n  else\n    raise(Error.new(\"Missing #{spec_filename}. Please run 'shards init'\"))\n  end\n)"},"external_var":false},{"html_id":"spec_filename-instance-method","name":"spec_filename","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":50,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L50"},"def":{"name":"spec_filename","visibility":"Public","body":"File.basename(spec_path)"},"external_var":false},{"html_id":"spec_path:String-instance-method","name":"spec_path","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L11"},"def":{"name":"spec_path","return_type":"String","visibility":"Public","body":"@spec_path"},"external_var":false},{"html_id":"touch_install_path-instance-method","name":"touch_install_path","abstract":false,"location":{"filename":"src/commands/command.cr","line_number":110,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L110"},"def":{"name":"touch_install_path","visibility":"Public","body":"Dir.mkdir_p(Shards.install_path)\nFile.touch(Shards.install_path)\n"},"external_var":false},{"html_id":"write_lockfile(packages)-instance-method","name":"write_lockfile","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":""}],"args_string":"(packages)","args_html":"(packages)","location":{"filename":"src/commands/command.cr","line_number":70,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/command.cr#L70"},"def":{"name":"write_lockfile","args":[{"name":"packages","external_name":"packages","restriction":""}],"visibility":"Public","body":"Log.info do \"Writing #{LOCK_FILENAME}\" end\n\noverride_path = @override_path\nif override_path && ((File.dirname(override_path)) == @path)\n  override_path = File.basename(override_path)\nend\n\nShards::Lock.write(packages, override_path, LOCK_FILENAME)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands","path":"Shards/Commands.html","kind":"module","full_name":"Shards::Commands","name":"Commands","abstract":false,"locations":[{"filename":"src/commands/ai_docs.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/ai_docs.cr#L6"},{"filename":"src/commands/assistant.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/assistant.cr#L4"},{"filename":"src/commands/audit.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/audit.cr#L8"},{"filename":"src/commands/build.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/build.cr#L4"},{"filename":"src/commands/check.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/check.cr#L5"},{"filename":"src/commands/compliance_report.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/compliance_report.cr#L7"},{"filename":"src/commands/diff.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/diff.cr#L6"},{"filename":"src/commands/docs.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/docs.cr#L7"},{"filename":"src/commands/init.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/init.cr#L5"},{"filename":"src/commands/install.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/install.cr#L9"},{"filename":"src/commands/licenses.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/licenses.cr#L9"},{"filename":"src/commands/list.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/list.cr#L4"},{"filename":"src/commands/lock.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/lock.cr#L5"},{"filename":"src/commands/mcp.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/mcp.cr#L5"},{"filename":"src/commands/outdated.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/outdated.cr#L4"},{"filename":"src/commands/policy.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/policy.cr#L7"},{"filename":"src/commands/prune.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/prune.cr#L7"},{"filename":"src/commands/run.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run.cr#L4"},{"filename":"src/commands/run_script.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run_script.cr#L4"},{"filename":"src/commands/sbom.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/sbom.cr#L6"},{"filename":"src/commands/update.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/update.cr#L8"},{"filename":"src/commands/version.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/version.cr#L4"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"types":[{"html_id":"Ashard/Shards/Commands/AIDocs","path":"Shards/Commands/AIDocs.html","kind":"class","full_name":"Shards::Commands::AIDocs","name":"AIDocs","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/ai_docs.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/ai_docs.cr#L15"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"doc":"Manages AI documentation installed from shard dependencies.\n\nSubcommands:\n- `status` (default): show installed AI docs and their state\n- `diff <shard>`: compare local modifications against upstream\n- `reset <shard> [file]`: discard local changes, restore upstream\n- `update [shard]`: force re-install, overwriting local changes\n- `merge-mcp`: merge `.mcp-shards.json` entries into `.mcp.json`","summary":"<p>Manages AI documentation installed from shard dependencies.</p>","instance_methods":[{"html_id":"run(args:Array(String))-instance-method","name":"run","doc":"Dispatches to the appropriate subcommand based on *args*.","summary":"<p>Dispatches to the appropriate subcommand based on <em>args</em>.</p>","abstract":false,"args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(args : Array(String))","args_html":"(args : Array(String))","location":{"filename":"src/commands/ai_docs.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/ai_docs.cr#L17"},"def":{"name":"run","args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"subcommand = args[0]? || \"status\"\nremaining = args.size > 1 ? args[1..] : [] of String\n\ncase subcommand\nwhen \"status\"\n  status\nwhen \"diff\"\n  if remaining.empty?\n    raise(Error.new(\"Usage: shards ai-docs diff <shard>\"))\n  end\n  diff(remaining[0])\nwhen \"reset\"\n  if remaining.empty?\n    raise(Error.new(\"Usage: shards ai-docs reset <shard> [file]\"))\n  end\n  reset(remaining[0], remaining[1]?)\nwhen \"update\"\n  update(remaining[0]?)\nwhen \"merge-mcp\"\n  merge_mcp\nelse\n  raise(Error.new(\"Unknown ai-docs subcommand: #{subcommand}. Use: status, diff, reset, update, merge-mcp\"))\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Assistant","path":"Shards/Commands/Assistant.html","kind":"class","full_name":"Shards::Commands::Assistant","name":"Assistant","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/assistant.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/assistant.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"HELP_TEXT","name":"HELP_TEXT","value":"\"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)\""}],"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"class_methods":[{"html_id":"run(path:String,args:Array(String))-class-method","name":"run","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(path : String, args : Array(String))","args_html":"(path : String, args : Array(String))","location":{"filename":"src/commands/assistant.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/assistant.cr#L27"},"def":{"name":"run","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"subcommand = \"status\"\nskip_components = [] of String\nforce = false\ndry_run = false\n\nargs.each do |arg|\n  case arg\n  when \"init\", \"update\", \"status\", \"remove\"\n    subcommand = arg\n  when \"--no-mcp\"\n    skip_components << \"mcp\"\n  when \"--no-skills\"\n    skip_components << \"skills\"\n  when \"--no-agents\"\n    skip_components << \"agents\"\n  when \"--no-settings\"\n    skip_components << \"settings\"\n  when \"--force\"\n    force = true\n  when \"--dry-run\"\n    dry_run = true\n  when \"--help\", \"-h\"\n    puts(HELP_TEXT)\n    return\n  end\nend\n\ncase subcommand\nwhen \"init\"\n  AssistantConfig.install(path, skip_components, force)\nwhen \"update\"\n  AssistantConfig.update(path, force, dry_run)\nwhen \"status\"\n  AssistantConfig.status(path)\nwhen \"remove\"\n  AssistantConfig.remove(path)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Audit","path":"Shards/Commands/Audit.html","kind":"class","full_name":"Shards::Commands::Audit","name":"Audit","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/audit.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/audit.cr#L9"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"IGNORE_FILENAME","name":"IGNORE_FILENAME","value":"\".shards-audit-ignore\""}],"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(format:String=\"terminal\",severity:String|Nil=nil,ignore_ids:Array(String)=[]ofString,ignore_file:String|Nil=nil,fail_above:String|Nil=nil,offline:Bool=false,update_db:Bool=false)-instance-method","name":"run","abstract":false,"args":[{"name":"format","default_value":"\"terminal\"","external_name":"format","restriction":"String"},{"name":"severity","default_value":"nil","external_name":"severity","restriction":"String | ::Nil"},{"name":"ignore_ids","default_value":"[] of String","external_name":"ignore_ids","restriction":"Array(String)"},{"name":"ignore_file","default_value":"nil","external_name":"ignore_file","restriction":"String | ::Nil"},{"name":"fail_above","default_value":"nil","external_name":"fail_above","restriction":"String | ::Nil"},{"name":"offline","default_value":"false","external_name":"offline","restriction":"Bool"},{"name":"update_db","default_value":"false","external_name":"update_db","restriction":"Bool"}],"args_string":"(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)","args_html":"(format : String = <span class=\"s\">&quot;terminal&quot;</span>, severity : String | Nil = <span class=\"n\">nil</span>, ignore_ids : Array(String) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">String</span>, ignore_file : String | Nil = <span class=\"n\">nil</span>, fail_above : String | Nil = <span class=\"n\">nil</span>, offline : Bool = <span class=\"n\">false</span>, update_db : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/commands/audit.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/audit.cr#L12"},"def":{"name":"run","args":[{"name":"format","default_value":"\"terminal\"","external_name":"format","restriction":"String"},{"name":"severity","default_value":"nil","external_name":"severity","restriction":"String | ::Nil"},{"name":"ignore_ids","default_value":"[] of String","external_name":"ignore_ids","restriction":"Array(String)"},{"name":"ignore_file","default_value":"nil","external_name":"ignore_file","restriction":"String | ::Nil"},{"name":"fail_above","default_value":"nil","external_name":"fail_above","restriction":"String | ::Nil"},{"name":"offline","default_value":"false","external_name":"offline","restriction":"Bool"},{"name":"update_db","default_value":"false","external_name":"update_db","restriction":"Bool"}],"visibility":"Public","body":"if format.in?(\"terminal\", \"json\", \"sarif\")\nelse\n  raise(Error.new(\"Unknown audit format: #{format}. Use 'terminal', 'json', or 'sarif'.\"))\nend\n\n\nmin_severity = if sev = severity\n  Severity.parse(sev)\nelse\n  Severity::Unknown\nend\n\n\nfail_threshold = if fa = fail_above\n  Severity.parse(fa)\nelse\n  Severity::Low\nend\n\n\npackages = locks.shards\n\nif packages.empty?\n  Log.info do \"No dependencies to audit.\" end\n  return\nend\n\nLog.info do \"Auditing #{packages.size} package(s) for vulnerabilities...\" end\n\n\nscanner = VulnerabilityScanner.new(path, offline: offline)\n\n\nif update_db\n  scanner.update_cache(packages)\nelse\n  scanner.scan(packages)\nend\n\nresults = scanner.results\n\n\nignore_rules = load_ignore_rules(ignore_ids, ignore_file)\n\n\nreport = VulnerabilityReport.new(results, ignore_rules: ignore_rules, min_severity: min_severity, fail_above: fail_threshold)\n\n\ncase format\nwhen \"terminal\"\n  report.to_terminal\nwhen \"json\"\n  report.to_json(STDOUT)\n  puts\nwhen \"sarif\"\n  report.to_sarif(STDOUT)\n  puts\nend\n\n\ncode = report.exit_code\nif code != 0\n  exit(code)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Build","path":"Shards/Commands/Build.html","kind":"class","full_name":"Shards::Commands::Build","name":"Build","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/build.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/build.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(targets,options)-instance-method","name":"run","abstract":false,"args":[{"name":"targets","external_name":"targets","restriction":""},{"name":"options","external_name":"options","restriction":""}],"args_string":"(targets, options)","args_html":"(targets, options)","location":{"filename":"src/commands/build.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/build.cr#L6"},"def":{"name":"run","args":[{"name":"targets","external_name":"targets","restriction":""},{"name":"options","external_name":"options","restriction":""}],"visibility":"Public","body":"if spec.targets.empty?\n  raise(Error.new(\"Targets not defined in #{SPEC_FILENAME}\"))\nend\n\nif Dir.exists?(Shards.bin_path)\nelse\n  Log.debug do \"mkdir #{Shards.bin_path}\" end\n  Dir.mkdir(Shards.bin_path)\nend\n\nif targets.empty?\n  targets = spec.targets.map(&.name)\nend\n\ntargets.each do |name|\n  if target = spec.targets.find do |t| t.name == name end\n    build(target, options)\n  else\n    raise(Error.new(\"Error target #{name} was not found in #{SPEC_FILENAME}.\"))\n  end\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Check","path":"Shards/Commands/Check.html","kind":"class","full_name":"Shards::Commands::Check","name":"Check","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/check.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/check.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"apply_overrides(deps:Array(Dependency))-instance-method","name":"apply_overrides","doc":"FIXME: duplicates MolinilloSolver#apply_overrides","summary":"<p><span class=\"flag yellow\">FIXME</span>  duplicates MolinilloSolver#apply_overrides</p>","abstract":false,"args":[{"name":"deps","external_name":"deps","restriction":"Array(Dependency)"}],"args_string":"(deps : Array(Dependency))","args_html":"(deps : Array(<a href=\"../../Shards/Dependency.html\">Dependency</a>))","location":{"filename":"src/commands/check.cr","line_number":56,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/check.cr#L56"},"def":{"name":"apply_overrides","args":[{"name":"deps","external_name":"deps","restriction":"Array(Dependency)"}],"visibility":"Public","body":"deps.map do |dep| (on_override(dep)) || dep end"},"external_var":false},{"html_id":"on_override(dependency:Dependency):Dependency|Nil-instance-method","name":"on_override","doc":"FIXME: duplicates MolinilloSolver#on_override","summary":"<p><span class=\"flag yellow\">FIXME</span>  duplicates MolinilloSolver#on_override</p>","abstract":false,"args":[{"name":"dependency","external_name":"dependency","restriction":"Dependency"}],"args_string":"(dependency : Dependency) : Dependency | Nil","args_html":"(dependency : <a href=\"../../Shards/Dependency.html\">Dependency</a>) : <a href=\"../../Shards/Dependency.html\">Dependency</a> | Nil","location":{"filename":"src/commands/check.cr","line_number":51,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/check.cr#L51"},"def":{"name":"on_override","args":[{"name":"dependency","external_name":"dependency","restriction":"Dependency"}],"return_type":"Dependency | ::Nil","visibility":"Public","body":"override.try() do |__arg0| __arg0.dependencies.find do |o| o.name == dependency.name end end"},"external_var":false},{"html_id":"run-instance-method","name":"run","abstract":false,"location":{"filename":"src/commands/check.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/check.cr#L7"},"def":{"name":"run","visibility":"Public","body":"if has_dependencies?\n  locks\n  verify(spec.dependencies)\n  if Shards.with_development?\n    verify(spec.development_dependencies)\n  end\nend\n\nLog.info do \"Dependencies are satisfied\" end\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/ComplianceReport","path":"Shards/Commands/ComplianceReport.html","kind":"class","full_name":"Shards::Commands::ComplianceReport","name":"ComplianceReport","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/compliance_report.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/compliance_report.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(args:Array(String))-instance-method","name":"run","abstract":false,"args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(args : Array(String))","args_html":"(args : Array(String))","location":{"filename":"src/commands/compliance_report.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/compliance_report.cr#L9"},"def":{"name":"run","args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"format = \"json\"\noutput : String | ::Nil = nil\nsections = [\"all\"]\nreviewer : String | ::Nil = nil\nsince : String | ::Nil = nil\nsign = false\n\nargs.each do |arg|\n  case arg\n  when .starts_with?(\"--format=\")\n    format = (arg.split(\"=\", 2)).last\n  when .starts_with?(\"--output=\")\n    output = (arg.split(\"=\", 2)).last\n  when .starts_with?(\"--sections=\")\n    sections = (arg.split(\"=\", 2)).last.split(\",\")\n  when .starts_with?(\"--reviewer=\")\n    reviewer = (arg.split(\"=\", 2)).last\n  when .starts_with?(\"--since=\")\n    since = (arg.split(\"=\", 2)).last\n  when \"--sign\"\n    sign = true\n  end\nend\n\next = case format\nwhen \"html\"\n  \".html\"\nwhen \"markdown\", \"md\"\n  \".md\"\nelse\n  \".json\"\nend\noutput_path = output || \"#{spec.name}-compliance-report#{ext}\"\n\nbuilder = Compliance::ReportBuilder.new(path: path, spec: spec, locks: locks, sections: sections, since: since, reviewer: reviewer)\n\nreport_data = builder.build\n\nformatter = Compliance::ReportFormatter.new(format: format)\nformatter.write(report_data, output_path)\n\nif sign\n  sign_report(output_path)\nend\n\narchive_report(output_path)\n\nLog.info do \"Compliance report generated: #{output_path}\" end\nprint_summary(report_data)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Diff","path":"Shards/Commands/Diff.html","kind":"class","full_name":"Shards::Commands::Diff","name":"Diff","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/diff.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/diff.cr#L7"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(args:Array(String))-instance-method","name":"run","abstract":false,"args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(args : Array(String))","args_html":"(args : Array(String))","location":{"filename":"src/commands/diff.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/diff.cr#L12"},"def":{"name":"run","args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"parse_args(args)\n\nfrom_packages = resolve_ref(@from_ref)\nto_packages = resolve_ref(@to_ref)\n\nchanges = LockfileDiffer.diff(from_packages, to_packages)\n\nreport = DiffReport.new(changes, from_label: @from_ref, to_label: @to_ref)\n\nif report.any_changes?\n  case @format\n  when \"terminal\"\n    report.to_terminal\n  when \"json\"\n    report.to_json\n  when \"markdown\"\n    report.to_markdown\n  else\n    raise(Error.new(\"Unknown format: #{@format}. Use: terminal, json, markdown\"))\n  end\nelse\n  Log.info do \"No dependency changes between #{@from_ref} and #{@to_ref}.\" end\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Docs","path":"Shards/Commands/Docs.html","kind":"class","full_name":"Shards::Commands::Docs","name":"Docs","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/docs.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/docs.cr#L15"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"AI_BUTTONS_CSS","name":"AI_BUTTONS_CSS","value":"\".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}\""},{"id":"AI_BUTTONS_JS","name":"AI_BUTTONS_JS","value":"\"<script>\\n(function() {\\n  function getPageMarkdown() {\\n    var title = document.querySelector('h1.type-name');\\n    var content = document.querySelector('.main-content');\\n    if (!content) return '';\\n\\n    var text = '';\\n    if (title) text += '# ' + title.textContent.trim() + '\\\\n\\\\n';\\n\\n    var sections = content.querySelectorAll('h2, p, pre, dl, .entry-detail');\\n    sections.forEach(function(el) {\\n      if (el.tagName === 'H2') text += '## ' + el.textContent.trim() + '\\\\n\\\\n';\\n      else if (el.tagName === 'P') text += el.textContent.trim() + '\\\\n\\\\n';\\n      else if (el.tagName === 'PRE') text += '```\\\\n' + el.textContent.trim() + '\\\\n```\\\\n\\\\n';\\n      else if (el.tagName === 'DL') {\\n        el.querySelectorAll('dt').forEach(function(dt) {\\n          text += '- `' + dt.textContent.trim() + '`\\\\n';\\n        });\\n        text += '\\\\n';\\n      }\\n    });\\n    return text;\\n  }\\n\\n  function buildPrompt(typeName, projectName) {\\n    return 'I\\\\'m working with the ' + projectName + ' Crystal library. ' +\\n           'Help me understand and use `' + typeName + '`. ' +\\n           'Here is the API documentation:\\\\n\\\\n';\\n  }\\n\\n  function getTypeName() {\\n    var el = document.querySelector('h1.type-name');\\n    return el ? el.textContent.trim() : document.title;\\n  }\\n\\n  function getProjectName() {\\n    var el = document.querySelector('.project-name');\\n    return el ? el.textContent.trim() : 'this project';\\n  }\\n\\n  function openInClaude() {\\n    var prompt = buildPrompt(getTypeName(), getProjectName()) + getPageMarkdown();\\n    var url = 'https://claude.ai/new?q=' + encodeURIComponent(prompt);\\n    window.open(url, '_blank');\\n  }\\n\\n  function openInChatGPT() {\\n    var prompt = buildPrompt(getTypeName(), getProjectName()) + getPageMarkdown();\\n    var url = 'https://chatgpt.com/?q=' + encodeURIComponent(prompt);\\n    window.open(url, '_blank');\\n  }\\n\\n  function openInGemini() {\\n    var prompt = buildPrompt(getTypeName(), getProjectName()) + getPageMarkdown();\\n    var url = 'https://gemini.google.com/app?q=' + encodeURIComponent(prompt);\\n    window.open(url, '_blank');\\n  }\\n\\n  function viewMarkdown() {\\n    var mdPath = window.location.pathname.replace(/\\\\.html$/, '.md');\\n    if (mdPath === window.location.pathname) mdPath += '.md';\\n    window.open(mdPath, '_blank');\\n  }\\n\\n  document.addEventListener('DOMContentLoaded', function() {\\n    var h1 = document.querySelector('h1.type-name');\\n    var mainContent = document.querySelector('.main-content');\\n    if (!mainContent) return;\\n\\n    var bar = document.createElement('div');\\n    bar.className = 'ai-assistant-bar';\\n    bar.innerHTML =\\n      '<span class=\\\"ai-label\\\">Discuss with AI:</span>' +\\n      '<button class=\\\"ai-btn claude-btn\\\" onclick=\\\"window.__openInClaude()\\\" title=\\\"Open in Claude\\\">' +\\n        '<svg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\"><path d=\\\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15h-2v-2h2v2zm2.07-7.75l-.9.92C11.45 10.9 11 11.5 11 13H9v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H6c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z\\\" fill=\\\"currentColor\\\"/></svg>' +\\n        'Claude' +\\n      '</button>' +\\n      '<button class=\\\"ai-btn chatgpt-btn\\\" onclick=\\\"window.__openInChatGPT()\\\" title=\\\"Open in ChatGPT\\\">' +\\n        '<svg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\"><path d=\\\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z\\\" fill=\\\"currentColor\\\"/></svg>' +\\n        'ChatGPT' +\\n      '</button>' +\\n      '<button class=\\\"ai-btn gemini-btn\\\" onclick=\\\"window.__openInGemini()\\\" title=\\\"Open in Gemini\\\">' +\\n        '<svg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\"><path d=\\\"M12 2L2 7v10l10 5 10-5V7L12 2zm0 2.18L19.18 8 12 11.82 4.82 8 12 4.18zM4 9.12l7 3.5V19.5l-7-3.5V9.12zm9 10.38v-6.88l7-3.5v6.88l-7 3.5z\\\" fill=\\\"currentColor\\\"/></svg>' +\\n        'Gemini' +\\n      '</button>' +\\n      '<button class=\\\"ai-btn md-btn\\\" onclick=\\\"window.__viewMarkdown()\\\" title=\\\"View as Markdown\\\">' +\\n        '<svg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\"><path d=\\\"M20.56 18H3.44C2.65 18 2 17.37 2 16.59V7.41C2 6.63 2.65 6 3.44 6h17.12c.79 0 1.44.63 1.44 1.41v9.18c0 .78-.65 1.41-1.44 1.41zM6.81 15.19v-3.68l1.83 2.29 1.83-2.29v3.68h1.83V8.81h-1.83l-1.83 2.29-1.83-2.29H5v6.38h1.81zm10.99-3.19h-1.83V8.81h-1.83V12h-1.84l2.75 3.19L17.8 12z\\\" fill=\\\"currentColor\\\"/></svg>' +\\n        'Markdown' +\\n      '</button>';\\n\\n    if (h1 && h1.nextSibling) {\\n      mainContent.insertBefore(bar, h1.nextSibling);\\n    } else {\\n      mainContent.insertBefore(bar, mainContent.firstChild);\\n    }\\n  });\\n\\n  window.__openInClaude = openInClaude;\\n  window.__openInChatGPT = openInChatGPT;\\n  window.__openInGemini = openInGemini;\\n  window.__viewMarkdown = viewMarkdown;\\n})();\\n</script>\""},{"id":"CSS_VARIABLES","name":"CSS_VARIABLES","value":"\":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}\""}],"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"doc":"Generates project documentation with theming and AI assistant integration.\n\nWraps `crystal docs` and post-processes the output to:\n- Inject CSS custom properties for theming\n- Apply project-local theme overrides from `docs-theme/`\n- Add \"Open in AI\" buttons (Claude, ChatGPT, Gemini) to each page\n- Generate parallel Markdown files for AI consumption","summary":"<p>Generates project documentation with theming and AI assistant integration.</p>","instance_methods":[{"html_id":"run(args:Array(String))-instance-method","name":"run","abstract":false,"args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(args : Array(String))","args_html":"(args : Array(String))","location":{"filename":"src/commands/docs.cr","line_number":339,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/docs.cr#L339"},"def":{"name":"run","args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"output_dir = \"docs\"\nskip_ai_buttons = false\nskip_agent_files = false\nskip_llms = false\ncrystal_args = [] of String\n\nargs.each do |arg|\n  case arg\n  when \"--output\", \"-o\"\n    crystal_args << arg\n  when .starts_with?(\"--output=\")\n    output_dir = arg.lchop(\"--output=\")\n    crystal_args << arg\n  when .starts_with?(\"-o\")\n    output_dir = arg.lchop(\"-o\")\n    crystal_args << arg\n  when \"--skip-ai-buttons\"\n    skip_ai_buttons = true\n  when \"--skip-agent-files\"\n    skip_agent_files = true\n  when \"--skip-llms\"\n    skip_llms = true\n  else\n    if (crystal_args.last? == \"--output\") || (crystal_args.last? == \"-o\")\n      output_dir = arg\n    end\n    crystal_args << arg\n  end\nend\n\n\nLog.info do \"Generating documentation...\" end\ncrystal_args_str = crystal_args.empty? ? \"\" : \" \" + (crystal_args.join(\" \"))\nstatus = Process.run(\"#{Shards.crystal_bin} docs#{crystal_args_str}\", shell: true, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit)\n\nif status.success?\nelse\n  raise(Error.new(\"crystal docs failed\"))\nend\n\n\ninject_theme(output_dir)\n\n\nif skip_ai_buttons\nelse\n  inject_ai_buttons(output_dir)\nend\n\n\ngenerate_markdown_files(output_dir)\ninject_resource_links(output_dir)\ninject_brand_story(output_dir)\n\nagent_files = [] of AgentFileEntry\nif skip_agent_files\nelse\n  agent_files = copy_agent_files(output_dir)\nend\nif skip_llms\nelse\n  generate_llms_exports(output_dir, agent_files)\nend\n\nLog.info do \"Documentation generated in #{output_dir}/\" end\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/Commands/Docs/AgentFileEntry","path":"Shards/Commands/Docs/AgentFileEntry.html","kind":"alias","full_name":"Shards::Commands::Docs::AgentFileEntry","name":"AgentFileEntry","abstract":false,"locations":[{"filename":"src/commands/docs.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/docs.cr#L16"}],"repository_name":"Ashard","program":false,"enum":false,"alias":true,"aliased":"NamedTuple(source: String, output: String, category: String, title: String)","aliased_html":"{source: String, output: String, category: String, title: String}","const":false,"namespace":{"html_id":"Ashard/Shards/Commands/Docs","kind":"class","full_name":"Shards::Commands::Docs","name":"Docs"}}]},{"html_id":"Ashard/Shards/Commands/Init","path":"Shards/Commands/Init.html","kind":"class","full_name":"Shards::Commands::Init","name":"Init","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/init.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/init.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run-instance-method","name":"run","abstract":false,"location":{"filename":"src/commands/init.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/init.cr#L7"},"def":{"name":"run","visibility":"Public","body":"if File.exists?(shard_path)\n  raise(Error.new(\"#{SPEC_FILENAME} already exists\"))\nend\n\nFile.write(shard_path, String.build do |__str__|\n  ECR.embed(\"/home/runner/work/shards/shards/src/commands/../templates/shard.yml.ecr\", \"__str__\")\nend)\n\nLog.info do \"Created #{SPEC_FILENAME}\" end\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Install","path":"Shards/Commands/Install.html","kind":"class","full_name":"Shards::Commands::Install","name":"Install","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/install.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/install.cr#L10"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run-instance-method","name":"run","abstract":false,"location":{"filename":"src/commands/install.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/install.cr#L11"},"def":{"name":"run","visibility":"Public","body":"if Shards.frozen? && (!lockfile?)\n  raise(Error.new(\"Missing shard.lock\"))\nend\ncheck_symlink_privilege\n\nLog.info do \"Resolving dependencies\" end\n\nsolver = MolinilloSolver.new(spec, override)\n\nif lockfile?\n  solver.locks = locks.shards\nend\n\nsolver.prepare(development: Shards.with_development?)\n\npackages = handle_resolver_errors do solver.solve end\n\n\nif lockfile?\n  lock_checksums = locks.shards.to_h do |p| {p.name, p.checksum} end\n  packages.each do |pkg|\n    pkg.checksum = lock_checksums[pkg.name]?\n  end\nend\n\ncheck_policy(packages)\n\nif Shards.frozen?\n  validate(packages)\nend\n\ninstall(packages)\n\n\nif Shards.skip_verify?\n  Log.warn do \"Checksum verification skipped (--skip-verify)\" end\nelse\n  verify_or_compute_checksums(packages)\nend\n\n(AIDocsInstaller.new(path)).install(packages)\n\n\nif Shards.skip_ai_assistant?\nelsif spec.ai_assistant.try(&.auto_install)\n  AssistantConfig.auto_install(path)\nend\n\nif generate_lockfile?(packages)\n  old_packages = if lockfile?\n    (Shards::Lock.from_file(lockfile_path)).shards\n  else\n    [] of Package\n  end\n  write_lockfile(packages)\n  ChangeLogger.record(path, \"install\", old_packages, packages, lockfile_path)\nelsif !Shards.frozen?\n  File.touch(lockfile_path)\nend\n\n\ntouch_install_path\n\ncheck_crystal_version(packages)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Licenses","path":"Shards/Commands/Licenses.html","kind":"class","full_name":"Shards::Commands::Licenses","name":"Licenses","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/licenses.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/licenses.cr#L10"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(format:String=\"terminal\",policy_path:String|Nil=nil,check:Bool=false,include_dev:Bool=false,detect:Bool=false)-instance-method","name":"run","abstract":false,"args":[{"name":"format","default_value":"\"terminal\"","external_name":"format","restriction":"String"},{"name":"policy_path","default_value":"nil","external_name":"policy_path","restriction":"String | ::Nil"},{"name":"check","default_value":"false","external_name":"check","restriction":"Bool"},{"name":"include_dev","default_value":"false","external_name":"include_dev","restriction":"Bool"},{"name":"detect","default_value":"false","external_name":"detect","restriction":"Bool"}],"args_string":"(format : String = \"terminal\", policy_path : String | Nil = nil, check : Bool = false, include_dev : Bool = false, detect : Bool = false)","args_html":"(format : String = <span class=\"s\">&quot;terminal&quot;</span>, policy_path : String | Nil = <span class=\"n\">nil</span>, check : Bool = <span class=\"n\">false</span>, include_dev : Bool = <span class=\"n\">false</span>, detect : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/commands/licenses.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/licenses.cr#L11"},"def":{"name":"run","args":[{"name":"format","default_value":"\"terminal\"","external_name":"format","restriction":"String"},{"name":"policy_path","default_value":"nil","external_name":"policy_path","restriction":"String | ::Nil"},{"name":"check","default_value":"false","external_name":"check","restriction":"Bool"},{"name":"include_dev","default_value":"false","external_name":"include_dev","restriction":"Bool"},{"name":"detect","default_value":"false","external_name":"detect","restriction":"Bool"}],"visibility":"Public","body":"packages = locks.shards\nroot_spec = spec\npolicy = LicensePolicy.load_policy(policy_path)\nreport = LicensePolicy.evaluate(packages, root_spec, policy, detect)\n\ncase format\nwhen \"terminal\"\n  render_terminal(report)\nwhen \"json\"\n  render_json(report)\nwhen \"csv\"\n  render_csv(report)\nwhen \"markdown\"\n  render_markdown(report)\nelse\n  raise(Error.new(\"Unknown format: #{format}. Use: terminal, json, csv, markdown\"))\nend\n\nif check && (report.summary.denied > 0 || report.summary.unlicensed > 0)\n  denied_count = report.summary.denied\n  unlicensed_count = report.summary.unlicensed\n  msgs = [] of String\n  if denied_count > 0\n    msgs << \"#{denied_count} denied\"\n  end\n  if unlicensed_count > 0\n    msgs << \"#{unlicensed_count} unlicensed\"\n  end\n  raise(Error.new(\"License policy violations: #{msgs.join(\", \")}\"))\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/List","path":"Shards/Commands/List.html","kind":"class","full_name":"Shards::Commands::List","name":"List","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/list.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/list.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(tree:Bool=false)-instance-method","name":"run","abstract":false,"args":[{"name":"tree","default_value":"false","external_name":"tree","restriction":"::Bool"}],"args_string":"(tree : Bool = false)","args_html":"(tree : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/commands/list.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/list.cr#L8"},"def":{"name":"run","args":[{"name":"tree","default_value":"false","external_name":"tree","restriction":"::Bool"}],"visibility":"Public","body":"@tree = tree\nif has_dependencies?\nelse\n  return\nend\nputs(\"Shards installed:\")\nlist(spec.dependencies)\nif Shards.with_development?\n  list(spec.development_dependencies)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Lock","path":"Shards/Commands/Lock.html","kind":"class","full_name":"Shards::Commands::Lock","name":"Lock","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/lock.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/lock.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(shards:Array(String),print=false,update=false)-instance-method","name":"run","abstract":false,"args":[{"name":"shards","external_name":"shards","restriction":"Array(String)"},{"name":"print","default_value":"false","external_name":"print","restriction":""},{"name":"update","default_value":"false","external_name":"update","restriction":""}],"args_string":"(shards : Array(String), print = false, update = false)","args_html":"(shards : Array(String), print = <span class=\"n\">false</span>, update = <span class=\"n\">false</span>)","location":{"filename":"src/commands/lock.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/lock.cr#L7"},"def":{"name":"run","args":[{"name":"shards","external_name":"shards","restriction":"Array(String)"},{"name":"print","default_value":"false","external_name":"print","restriction":""},{"name":"update","default_value":"false","external_name":"update","restriction":""}],"visibility":"Public","body":"check_symlink_privilege\n\nLog.info do \"Resolving dependencies\" end\n\nsolver = MolinilloSolver.new(spec, override)\n\nif lockfile?\n  if update\n    if shards.empty?\n    else\n      solver.locks = locks.shards.reject do |d| shards.includes?(d.name) end\n    end\n  else\n    solver.locks = locks.shards\n  end\nend\n\nsolver.prepare(development: Shards.with_development?)\n\npackages = handle_resolver_errors do solver.solve end\nif packages.empty?\n  return\nend\n\nif print\n  Shards::Lock.write(packages, @override_path, STDOUT)\nelse\n  write_lockfile(packages)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/MCP","path":"Shards/Commands/MCP.html","kind":"class","full_name":"Shards::Commands::MCP","name":"MCP","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/mcp.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/mcp.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(args:Array(String))-instance-method","name":"run","abstract":false,"args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(args : Array(String))","args_html":"(args : Array(String))","location":{"filename":"src/commands/mcp.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/mcp.cr#L7"},"def":{"name":"run","args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"subcommand = args[0]? || \"status\"\nremaining = args.size > 1 ? args[1..] : [] of String\n\ncase subcommand\nwhen \"status\"\n  show_status\nwhen \"start\"\n  manager.start(remaining[0]?)\nwhen \"stop\"\n  manager.stop(remaining[0]?)\nwhen \"restart\"\n  manager.restart(remaining[0]?)\nwhen \"logs\"\n  if remaining.empty?\n    raise(Error.new(\"Usage: shards mcp logs <server_name> [--no-follow] [--lines=N]\"))\n  end\n  server_name = remaining.reject(&.starts_with?(\"--\")).first? ||\n  (raise(Error.new(\"Usage: shards mcp logs <server_name>\")))\n  follow = !(remaining.includes?(\"--no-follow\"))\n  lines = 20\n  remaining.each do |arg|\n    if arg.starts_with?(\"--lines=\")\n      lines = (arg.split(\"=\", 2)).last.to_i\n    end\n  end\n  manager.logs(server_name, follow, lines)\nelse\n  raise(Error.new(\"Unknown mcp subcommand: #{subcommand}. Use: status, start, stop, restart, logs\"))\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Outdated","path":"Shards/Commands/Outdated.html","kind":"class","full_name":"Shards::Commands::Outdated","name":"Outdated","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/outdated.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/outdated.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(prereleases:Bool=false)-instance-method","name":"run","abstract":false,"args":[{"name":"prereleases","default_value":"false","external_name":"prereleases","restriction":"::Bool"}],"args_string":"(prereleases : Bool = false)","args_html":"(prereleases : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/commands/outdated.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/outdated.cr#L11"},"def":{"name":"run","args":[{"name":"prereleases","default_value":"false","external_name":"prereleases","restriction":"::Bool"}],"visibility":"Public","body":"@prereleases = prereleases\ncheck_symlink_privilege\n\nif has_dependencies?\nelse\n  return\nend\n\nLog.info do \"Resolving dependencies\" end\n\nsolver = MolinilloSolver.new(spec, override, prereleases: @prereleases)\nsolver.prepare(development: Shards.with_development?)\n\npackages = handle_resolver_errors do solver.solve end\npackages.each do |package| analyze(package) end\n\nif @up_to_date\n  Log.info do \"Dependencies are up to date!\" end\nelse\n  @output.rewind\n  Log.warn do \"Outdated dependencies:\" end\n  puts(@output.to_s)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Policy","path":"Shards/Commands/Policy.html","kind":"class","full_name":"Shards::Commands::Policy","name":"Policy","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/policy.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/policy.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"DEFAULT_POLICY_TEMPLATE","name":"DEFAULT_POLICY_TEMPLATE","value":"\"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\""}],"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(args:Array(String))-instance-method","name":"run","abstract":false,"args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(args : Array(String))","args_html":"(args : Array(String))","location":{"filename":"src/commands/policy.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/policy.cr#L13"},"def":{"name":"run","args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"remaining = [] of String\nargs.each do |arg|\n  case arg\n  when .starts_with?(\"--policy=\")\n    @policy_path = (arg.split(\"=\", 2)).last\n  when \"--strict\"\n    @strict = true\n  when .starts_with?(\"--format=\")\n    @format = (arg.split(\"=\", 2)).last\n  else\n    if arg.starts_with?(\"--\")\n    else\n      remaining << arg\n    end\n  end\nend\n\nsubcommand = remaining[0]? || \"check\"\n\ncase subcommand\nwhen \"check\"\n  run_check\nwhen \"init\"\n  run_init\nwhen \"show\"\n  run_show\nelse\n  raise(Error.new(\"Unknown policy subcommand: #{subcommand}. Use: check, init, show\"))\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Prune","path":"Shards/Commands/Prune.html","kind":"class","full_name":"Shards::Commands::Prune","name":"Prune","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/prune.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/prune.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run-instance-method","name":"run","abstract":false,"location":{"filename":"src/commands/prune.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/prune.cr#L9"},"def":{"name":"run","visibility":"Public","body":"if lockfile? && (Dir.exists?(Shards.install_path))\nelse\n  return\nend\n\npruned_names = [] of String\n\nDir.each_child(Shards.install_path) do |name|\n  path = File.join(Shards.install_path, name)\n  if File.directory?(path)\n  else\n    next\n  end\n\n  if locks.shards.none? do |d| d.name == name end\n    Log.with_context do\n      Log.context.set(package: name)\n      Log.debug do \"rm -rf '#{Process.quote(path)}'\" end\n      Shards::Helpers.rm_rf(path)\n\n      Shards.info.installed.delete(name)\n      Log.info do \"Pruned #{File.join(File.basename(Shards.install_path), name)}\" end\n    end\n    pruned_names << name\n  end\nend\n\nShards.info.save\n\n\nif pruned_names.empty?\nelse\n  (AIDocsInstaller.new(self.path)).prune(pruned_names)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Run","path":"Shards/Commands/Run.html","kind":"class","full_name":"Shards::Commands::Run","name":"Run","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/run.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(targets,options,run_options)-instance-method","name":"run","abstract":false,"args":[{"name":"targets","external_name":"targets","restriction":""},{"name":"options","external_name":"options","restriction":""},{"name":"run_options","external_name":"run_options","restriction":""}],"args_string":"(targets, options, run_options)","args_html":"(targets, options, run_options)","location":{"filename":"src/commands/run.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run.cr#L6"},"def":{"name":"run","args":[{"name":"targets","external_name":"targets","restriction":""},{"name":"options","external_name":"options","restriction":""},{"name":"run_options","external_name":"run_options","restriction":""}],"visibility":"Public","body":"if spec.targets.empty?\n  raise(Error.new(\"Targets not defined in #{SPEC_FILENAME}\"))\nend\n\n\nif targets.size > 1\n  raise(Error.new(\"Error please specify only one target. If you meant to pass arguments you may use 'shards run target -- args'\"))\nend\n\n\nif targets.empty?\n  if spec.targets.size > 1\n    raise(Error.new(\"Error please specify the target with 'shards run target'\"))\n  else\n    name = spec.targets.first.name\n  end\nelse\n  name = targets.first\nend\n\ntarget = spec.targets.find do |t| t.name == name end\n\nif target\nelse\n  raise(Error.new(\"Error target #{name} was not found in #{SPEC_FILENAME}\"))\nend\n\nCommands::Build.run(path, [target.name], options)\n\nLog.info do \"Executing: #{target.name} #{run_options.join(' ')}\" end\n\n{% if flag?(:win32) %}\n          # FIXME: Process.exec doesn't work as expected on Windows, we need to run\n          # as a child process and report the exit code afterwards. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933\n          status = Process.run(File.join(Shards.bin_path, target.name), args: run_options, input: Process::Redirect::Inherit, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit)\n          {% if (compare_versions(Crystal::VERSION, \"1.19.0\")) >= 0 %}\n            exit status\n          {% else %}\n            exit status.system_exit_status.to_i32!\n          {% end %}\n        {% else %}\n          # FIXME: The explicit close is necessary to flush the last log message\n          # before `exec`. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933\n          ::Log.builder.close\n\n          Process.exec(File.join(Shards.bin_path, target.name), args: run_options)\n        {% end %}\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/RunScript","path":"Shards/Commands/RunScript.html","kind":"class","full_name":"Shards::Commands::RunScript","name":"RunScript","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/run_script.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run_script.cr#L13"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"doc":"Runs postinstall scripts that are pending or have changed since last execution.\n\nWhen called without arguments, runs all pending scripts. When given shard\nnames, runs only those specific scripts.\n\nThis command exists because postinstall scripts only auto-run on first\ninstall. If a script changes during `shards update`, the user must\nexplicitly run it with this command.","summary":"<p>Runs postinstall scripts that are pending or have changed since last execution.</p>","instance_methods":[{"html_id":"run(shard_names:Array(String))-instance-method","name":"run","doc":"Runs postinstall scripts for the specified shards, or all pending if none given.","summary":"<p>Runs postinstall scripts for the specified shards, or all pending if none given.</p>","abstract":false,"args":[{"name":"shard_names","external_name":"shard_names","restriction":"Array(String)"}],"args_string":"(shard_names : Array(String))","args_html":"(shard_names : Array(String))","location":{"filename":"src/commands/run_script.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/run_script.cr#L15"},"def":{"name":"run","args":[{"name":"shard_names","external_name":"shard_names","restriction":"Array(String)"}],"visibility":"Public","body":"if shard_names.empty?\n  run_all_pending\nelse\n  shard_names.each do |name| run_for(name) end\nend"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/SBOM","path":"Shards/Commands/SBOM.html","kind":"class","full_name":"Shards::Commands::SBOM","name":"SBOM","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/sbom.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/sbom.cr#L7"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(format:String,output:String|Nil,include_dev:Bool)-instance-method","name":"run","abstract":false,"args":[{"name":"format","external_name":"format","restriction":"String"},{"name":"output","external_name":"output","restriction":"String | ::Nil"},{"name":"include_dev","external_name":"include_dev","restriction":"Bool"}],"args_string":"(format : String, output : String | Nil, include_dev : Bool)","args_html":"(format : String, output : String | Nil, include_dev : Bool)","location":{"filename":"src/commands/sbom.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/sbom.cr#L8"},"def":{"name":"run","args":[{"name":"format","external_name":"format","restriction":"String"},{"name":"output","external_name":"output","restriction":"String | ::Nil"},{"name":"include_dev","external_name":"include_dev","restriction":"Bool"}],"visibility":"Public","body":"packages = locks.shards\n\nroot_spec = spec\n\n\ndep_graph = build_dependency_graph(packages)\n\ncase format\nwhen \"spdx\"\n  output_path = output || \"#{root_spec.name}.spdx.json\"\n  generate_spdx(root_spec, packages, dep_graph, output_path)\nwhen \"cyclonedx\"\n  output_path = output || \"#{root_spec.name}.cdx.json\"\n  generate_cyclonedx(root_spec, packages, dep_graph, output_path)\nelse\n  raise(Error.new(\"Unknown SBOM format: #{format}. Use 'spdx' or 'cyclonedx'.\"))\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Update","path":"Shards/Commands/Update.html","kind":"class","full_name":"Shards::Commands::Update","name":"Update","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/update.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/update.cr#L9"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"instance_methods":[{"html_id":"run(shards:Array(String))-instance-method","name":"run","abstract":false,"args":[{"name":"shards","external_name":"shards","restriction":"Array(String)"}],"args_string":"(shards : Array(String))","args_html":"(shards : Array(String))","location":{"filename":"src/commands/update.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/update.cr#L10"},"def":{"name":"run","args":[{"name":"shards","external_name":"shards","restriction":"Array(String)"}],"visibility":"Public","body":"check_symlink_privilege\n\nLog.info do \"Resolving dependencies\" end\n\nsolver = MolinilloSolver.new(spec, override)\n\nif lockfile? && !shards.empty?\n  solver.locks = locks.shards.reject do |d| shards.includes?(d.name) end\nend\n\nsolver.prepare(development: Shards.with_development?)\n\npackages = handle_resolver_errors do solver.solve end\ncheck_policy(packages)\ninstall(packages)\n\n\ncompute_checksums(packages)\n\n(AIDocsInstaller.new(path)).install(packages)\n\nif generate_lockfile?(packages)\n  old_packages = if lockfile?\n    (Shards::Lock.from_file(lockfile_path)).shards\n  else\n    [] of Package\n  end\n  write_lockfile(packages)\n  ChangeLogger.record(path, \"update\", old_packages, packages, lockfile_path)\nelse\n  File.touch(lockfile_path)\nend\n\n\ntouch_install_path\n\ncheck_crystal_version(packages)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Commands/Version","path":"Shards/Commands/Version.html","kind":"class","full_name":"Shards::Commands::Version","name":"Version","abstract":false,"superclass":{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},"ancestors":[{"html_id":"Ashard/Shards/Command","kind":"class","full_name":"Shards::Command","name":"Command"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/commands/version.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/version.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Commands","kind":"module","full_name":"Shards::Commands","name":"Commands"},"class_methods":[{"html_id":"run(path)-class-method","name":"run","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""}],"args_string":"(path)","args_html":"(path)","location":{"filename":"src/commands/version.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/version.cr#L6"},"def":{"name":"run","args":[{"name":"path","external_name":"path","restriction":""}],"visibility":"Public","body":"path = lookup_path(path)\n(new(path)).run\n"},"external_var":false}],"instance_methods":[{"html_id":"run-instance-method","name":"run","abstract":false,"location":{"filename":"src/commands/version.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/commands/version.cr#L11"},"def":{"name":"run","visibility":"Public","body":"puts(spec.version)"},"external_var":false}]}]},{"html_id":"Ashard/Shards/Compliance","path":"Shards/Compliance.html","kind":"module","full_name":"Shards::Compliance","name":"Compliance","abstract":false,"locations":[{"filename":"src/compliance/html_template.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/html_template.cr#L2"},{"filename":"src/compliance/report_builder.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L6"},{"filename":"src/compliance/report_formatter.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_formatter.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"types":[{"html_id":"Ashard/Shards/Compliance/Attestation","path":"Shards/Compliance/Attestation.html","kind":"struct","full_name":"Shards::Compliance::Attestation","name":"Attestation","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_builder.cr","line_number":60,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L60"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"new(reviewer:String,reviewed_at:Time,notes:Nil|String=nil)-class-method","name":"new","abstract":false,"args":[{"name":"reviewer","external_name":"reviewer","restriction":"::String"},{"name":"reviewed_at","external_name":"reviewed_at","restriction":"::Time"},{"name":"notes","default_value":"nil","external_name":"notes","restriction":"::Nil | ::String"}],"args_string":"(reviewer : String, reviewed_at : Time, notes : Nil | String = nil)","args_html":"(reviewer : String, reviewed_at : Time, notes : Nil | String = <span class=\"n\">nil</span>)","location":{"filename":"src/compliance/report_builder.cr","line_number":65,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L65"},"def":{"name":"new","args":[{"name":"reviewer","external_name":"reviewer","restriction":"::String"},{"name":"reviewed_at","external_name":"reviewed_at","restriction":"::Time"},{"name":"notes","default_value":"nil","external_name":"notes","restriction":"::Nil | ::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(reviewer, reviewed_at, notes)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"notes:String|Nil-instance-method","name":"notes","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":63,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L63"},"def":{"name":"notes","return_type":"String | ::Nil","visibility":"Public","body":"@notes"},"external_var":false},{"html_id":"reviewed_at:Time-instance-method","name":"reviewed_at","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":62,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L62"},"def":{"name":"reviewed_at","return_type":"Time","visibility":"Public","body":"@reviewed_at"},"external_var":false},{"html_id":"reviewer:String-instance-method","name":"reviewer","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":61,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L61"},"def":{"name":"reviewer","return_type":"String","visibility":"Public","body":"@reviewer"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/HtmlTemplate","path":"Shards/Compliance/HtmlTemplate.html","kind":"module","full_name":"Shards::Compliance::HtmlTemplate","name":"HtmlTemplate","abstract":false,"locations":[{"filename":"src/compliance/html_template.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/html_template.cr#L3"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CSS","name":"CSS","value":"\"  * { 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; } }\""},{"id":"JS","name":"JS","value":"\"  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  });\""}],"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"class_methods":[{"html_id":"render(data:ReportData):String-class-method","name":"render","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"ReportData"}],"args_string":"(data : ReportData) : String","args_html":"(data : <a href=\"../../Shards/Compliance/ReportData.html\">ReportData</a>) : String","location":{"filename":"src/compliance/html_template.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/html_template.cr#L4"},"def":{"name":"render","args":[{"name":"data","external_name":"data","restriction":"ReportData"}],"return_type":"String","visibility":"Public","body":"String.build do |html|\n  html << \"<!DOCTYPE html>\\n\"\n  html << \"<html lang=\\\"en\\\">\\n<head>\\n\"\n  html << \"<meta charset=\\\"UTF-8\\\">\\n\"\n  html << \"<meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\\n\"\n  html << \"<title>Compliance Report - #{escape_html(data.project.name)}</title>\\n\"\n  html << \"<style>\\n#{CSS}\\n</style>\\n\"\n  html << \"</head>\\n<body>\\n\"\n\n\n  html << \"<header>\\n\"\n  html << \"<h1>Supply Chain Compliance Report</h1>\\n\"\n  html << \"<div class=\\\"report-meta\\\">\\n\"\n  html << \"<span class=\\\"project\\\">#{escape_html(data.project.name)} v#{escape_html(data.project.version)}</span>\\n\"\n  html << \"<span class=\\\"date\\\">Generated: #{data.generated_at.to_rfc3339}</span>\\n\"\n  html << \"<span class=\\\"generator\\\">#{escape_html(data.generator)}</span>\\n\"\n  html << \"</div>\\n</header>\\n\"\n\n\n  html << \"<section class=\\\"summary\\\">\\n\"\n  html << \"<h2>Executive Summary</h2>\\n\"\n  html << \"<div class=\\\"status-badge #{data.summary.overall_status}\\\">#{data.summary.overall_status.upcase}</div>\\n\"\n  html << \"<table class=\\\"metrics\\\">\\n\"\n  html << \"<tr><td>Total Dependencies</td><td>#{data.summary.total_dependencies}</td></tr>\\n\"\n  html << \"<tr><td>Direct Dependencies</td><td>#{data.summary.direct_dependencies}</td></tr>\\n\"\n  html << \"<tr><td>Transitive Dependencies</td><td>#{data.summary.transitive_dependencies}</td></tr>\\n\"\n  html << \"<tr><td>License Compliance</td><td>#{data.summary.license_compliance}</td></tr>\\n\"\n  html << \"<tr><td>Policy Compliance</td><td>#{data.summary.policy_compliance}</td></tr>\\n\"\n  html << \"</table>\\n</section>\\n\"\n\n\n  if sbom = data.sections.sbom\n    html << (render_sbom_section(sbom))\n  end\n\n\n  if integrity = data.sections.integrity\n    html << (render_integrity_section(integrity))\n  end\n\n\n  if att = data.attestation\n    html << \"<section class=\\\"attestation\\\">\\n\"\n    html << \"<h2>Attestation</h2>\\n\"\n    html << \"<p><strong>Reviewer:</strong> #{escape_html(att.reviewer)}</p>\\n\"\n    html << \"<p><strong>Reviewed:</strong> #{att.reviewed_at.to_rfc3339}</p>\\n\"\n    html << \"</section>\\n\"\n  end\n\n  html << \"<footer><p>Generated by #{escape_html(data.generator)}</p></footer>\\n\"\n  html << \"<script>\\n#{JS}\\n</script>\\n\"\n  html << \"</body>\\n</html>\"\nend"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/ProjectInfo","path":"Shards/Compliance/ProjectInfo.html","kind":"struct","full_name":"Shards::Compliance::ProjectInfo","name":"ProjectInfo","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_builder.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L7"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"new(name:String,version:String,crystal_version:String)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"version","external_name":"version","restriction":"::String"},{"name":"crystal_version","external_name":"crystal_version","restriction":"::String"}],"args_string":"(name : String, version : String, crystal_version : String)","args_html":"(name : String, version : String, crystal_version : String)","location":{"filename":"src/compliance/report_builder.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L12"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"version","external_name":"version","restriction":"::String"},{"name":"crystal_version","external_name":"crystal_version","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, version, crystal_version)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"crystal_version:String-instance-method","name":"crystal_version","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L10"},"def":{"name":"crystal_version","return_type":"String","visibility":"Public","body":"@crystal_version"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L8"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L9"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/ReportBuilder","path":"Shards/Compliance/ReportBuilder.html","kind":"class","full_name":"Shards::Compliance::ReportBuilder","name":"ReportBuilder","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_builder.cr","line_number":87,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L87"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"new(path:String,spec:Shards::Spec,locks:Shards::Lock,sections:Array(String)=[\"all\"],since:Nil|String=nil,reviewer:Nil|String=nil)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"::String"},{"name":"spec","external_name":"spec","restriction":"::Shards::Spec"},{"name":"locks","external_name":"locks","restriction":"::Shards::Lock"},{"name":"sections","default_value":"[\"all\"]","external_name":"sections","restriction":"Array(String)"},{"name":"since","default_value":"nil","external_name":"since","restriction":"::Nil | ::String"},{"name":"reviewer","default_value":"nil","external_name":"reviewer","restriction":"::Nil | ::String"}],"args_string":"(path : String, spec : Shards::Spec, locks : Shards::Lock, sections : Array(String) = [\"all\"], since : Nil | String = nil, reviewer : Nil | String = nil)","args_html":"(path : String, spec : <a href=\"../../Shards/Spec.html\">Shards::Spec</a>, locks : <a href=\"../../Shards/Lock.html\">Shards::Lock</a>, sections : Array(String) = [<span class=\"s\">&quot;all&quot;</span>], since : Nil | String = <span class=\"n\">nil</span>, reviewer : Nil | String = <span class=\"n\">nil</span>)","location":{"filename":"src/compliance/report_builder.cr","line_number":95,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L95"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"::String"},{"name":"spec","external_name":"spec","restriction":"::Shards::Spec"},{"name":"locks","external_name":"locks","restriction":"::Shards::Lock"},{"name":"sections","default_value":"[\"all\"]","external_name":"sections","restriction":"Array(String)"},{"name":"since","default_value":"nil","external_name":"since","restriction":"::Nil | ::String"},{"name":"reviewer","default_value":"nil","external_name":"reviewer","restriction":"::Nil | ::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, spec, locks, sections, since, reviewer)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"build:ReportData-instance-method","name":"build","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":101,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L101"},"def":{"name":"build","return_type":"ReportData","visibility":"Public","body":"packages = locks.shards\nroot_spec = spec\n\nsections = SectionData.new\n\nif include_section?(\"sbom\")\n  sections.sbom = collect_sbom(root_spec, packages)\nend\n\nif include_section?(\"audit\")\n  sections.vulnerability_audit = collect_vulnerability_audit\nend\n\nif include_section?(\"licenses\")\n  sections.license_audit = collect_license_audit\nend\n\nif include_section?(\"policy\")\n  sections.policy_compliance = collect_policy_compliance\nend\n\nif include_section?(\"integrity\")\n  sections.integrity = collect_integrity_check(packages)\nend\n\nif include_section?(\"changelog\")\n  sections.change_history = collect_change_history\nend\n\nsummary = compute_summary(packages, root_spec, sections)\n\nattestation = if r = reviewer\n  Attestation.new(reviewer: r, reviewed_at: Time.utc)\nend\n\nReportData.new(project: ProjectInfo.new(name: root_spec.name, version: root_spec.version.to_s, crystal_version: Shards.crystal_version), summary: summary, sections: sections, reviewer: reviewer, attestation: attestation)\n"},"external_var":false},{"html_id":"locks:Shards::Lock-instance-method","name":"locks","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":90,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L90"},"def":{"name":"locks","return_type":"Shards::Lock","visibility":"Public","body":"@locks"},"external_var":false},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":88,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L88"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"@path"},"external_var":false},{"html_id":"requested_sections:Array(String)-instance-method","name":"requested_sections","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":91,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L91"},"def":{"name":"requested_sections","return_type":"Array(String)","visibility":"Public","body":"@requested_sections"},"external_var":false},{"html_id":"reviewer:String|Nil-instance-method","name":"reviewer","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":93,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L93"},"def":{"name":"reviewer","return_type":"String | ::Nil","visibility":"Public","body":"@reviewer"},"external_var":false},{"html_id":"since:String|Nil-instance-method","name":"since","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":92,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L92"},"def":{"name":"since","return_type":"String | ::Nil","visibility":"Public","body":"@since"},"external_var":false},{"html_id":"spec:Shards::Spec-instance-method","name":"spec","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":89,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L89"},"def":{"name":"spec","return_type":"Shards::Spec","visibility":"Public","body":"@spec"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/ReportData","path":"Shards/Compliance/ReportData.html","kind":"struct","full_name":"Shards::Compliance::ReportData","name":"ReportData","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_builder.cr","line_number":69,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L69"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"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}\")-class-method","name":"new","abstract":false,"args":[{"name":"project","external_name":"project","restriction":"::Shards::Compliance::ProjectInfo"},{"name":"summary","external_name":"summary","restriction":"::Shards::Compliance::Summary"},{"name":"sections","external_name":"sections","restriction":"::Shards::Compliance::SectionData"},{"name":"reviewer","default_value":"nil","external_name":"reviewer","restriction":"::Nil | ::String"},{"name":"attestation","default_value":"nil","external_name":"attestation","restriction":"::Shards::Compliance::Attestation | ::Nil"},{"name":"version","default_value":"\"1.0\"","external_name":"version","restriction":"::String"},{"name":"generated_at","default_value":"Time.utc","external_name":"generated_at","restriction":"::Time"},{"name":"generator","default_value":"\"shards-alpha #{VERSION}\"","external_name":"generator","restriction":"::String"}],"args_string":"(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}\")","args_html":"(project : <a href=\"../../Shards/Compliance/ProjectInfo.html\">Shards::Compliance::ProjectInfo</a>, summary : <a href=\"../../Shards/Compliance/Summary.html\">Shards::Compliance::Summary</a>, sections : <a href=\"../../Shards/Compliance/SectionData.html\">Shards::Compliance::SectionData</a>, reviewer : Nil | String = <span class=\"n\">nil</span>, attestation : <a href=\"../../Shards/Compliance/Attestation.html\">Shards::Compliance::Attestation</a> | Nil = <span class=\"n\">nil</span>, version : String = <span class=\"s\">&quot;1.0&quot;</span>, generated_at : Time = <span class=\"t\">Time</span>.utc, generator : String = <span class=\"s\">&quot;shards-alpha </span><span class=\"i\">#{</span><span class=\"t\">VERSION</span><span class=\"i\">}</span><span class=\"s\">&quot;</span>)","location":{"filename":"src/compliance/report_builder.cr","line_number":79,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L79"},"def":{"name":"new","args":[{"name":"project","external_name":"project","restriction":"::Shards::Compliance::ProjectInfo"},{"name":"summary","external_name":"summary","restriction":"::Shards::Compliance::Summary"},{"name":"sections","external_name":"sections","restriction":"::Shards::Compliance::SectionData"},{"name":"reviewer","default_value":"nil","external_name":"reviewer","restriction":"::Nil | ::String"},{"name":"attestation","default_value":"nil","external_name":"attestation","restriction":"::Shards::Compliance::Attestation | ::Nil"},{"name":"version","default_value":"\"1.0\"","external_name":"version","restriction":"::String"},{"name":"generated_at","default_value":"Time.utc","external_name":"generated_at","restriction":"::Time"},{"name":"generator","default_value":"\"shards-alpha #{VERSION}\"","external_name":"generator","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(project, summary, sections, reviewer, attestation, version, generated_at, generator)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"attestation:Attestation|Nil-instance-method","name":"attestation","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":77,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L77"},"def":{"name":"attestation","return_type":"Attestation | ::Nil","visibility":"Public","body":"@attestation"},"external_var":false},{"html_id":"generated_at:Time-instance-method","name":"generated_at","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":71,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L71"},"def":{"name":"generated_at","return_type":"Time","visibility":"Public","body":"@generated_at"},"external_var":false},{"html_id":"generator:String-instance-method","name":"generator","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":72,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L72"},"def":{"name":"generator","return_type":"String","visibility":"Public","body":"@generator"},"external_var":false},{"html_id":"project:ProjectInfo-instance-method","name":"project","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":73,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L73"},"def":{"name":"project","return_type":"ProjectInfo","visibility":"Public","body":"@project"},"external_var":false},{"html_id":"reviewer:String|Nil-instance-method","name":"reviewer","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":74,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L74"},"def":{"name":"reviewer","return_type":"String | ::Nil","visibility":"Public","body":"@reviewer"},"external_var":false},{"html_id":"sections:SectionData-instance-method","name":"sections","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":76,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L76"},"def":{"name":"sections","return_type":"SectionData","visibility":"Public","body":"@sections"},"external_var":false},{"html_id":"summary:Summary-instance-method","name":"summary","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":75,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L75"},"def":{"name":"summary","return_type":"Summary","visibility":"Public","body":"@summary"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":70,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L70"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/ReportFormatter","path":"Shards/Compliance/ReportFormatter.html","kind":"class","full_name":"Shards::Compliance::ReportFormatter","name":"ReportFormatter","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_formatter.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_formatter.cr#L7"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"new(format:String,template_path:Nil|String=nil)-class-method","name":"new","abstract":false,"args":[{"name":"format","external_name":"format","restriction":"::String"},{"name":"template_path","default_value":"nil","external_name":"template_path","restriction":"::Nil | ::String"}],"args_string":"(format : String, template_path : Nil | String = nil)","args_html":"(format : String, template_path : Nil | String = <span class=\"n\">nil</span>)","location":{"filename":"src/compliance/report_formatter.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_formatter.cr#L11"},"def":{"name":"new","args":[{"name":"format","external_name":"format","restriction":"::String"},{"name":"template_path","default_value":"nil","external_name":"template_path","restriction":"::Nil | ::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(format, template_path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"format:String-instance-method","name":"format","abstract":false,"location":{"filename":"src/compliance/report_formatter.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_formatter.cr#L8"},"def":{"name":"format","return_type":"String","visibility":"Public","body":"@format"},"external_var":false},{"html_id":"template_path:String|Nil-instance-method","name":"template_path","abstract":false,"location":{"filename":"src/compliance/report_formatter.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_formatter.cr#L9"},"def":{"name":"template_path","return_type":"String | ::Nil","visibility":"Public","body":"@template_path"},"external_var":false},{"html_id":"write(data:ReportData,output_path:String):Nil-instance-method","name":"write","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"ReportData"},{"name":"output_path","external_name":"output_path","restriction":"String"}],"args_string":"(data : ReportData, output_path : String) : Nil","args_html":"(data : <a href=\"../../Shards/Compliance/ReportData.html\">ReportData</a>, output_path : String) : Nil","location":{"filename":"src/compliance/report_formatter.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_formatter.cr#L14"},"def":{"name":"write","args":[{"name":"data","external_name":"data","restriction":"ReportData"},{"name":"output_path","external_name":"output_path","restriction":"String"}],"return_type":"Nil","visibility":"Public","body":"dir = File.dirname(output_path)\nif dir == \".\"\nelse\n  Dir.mkdir_p(dir)\nend\n\ncase format\nwhen \"json\"\n  write_json(data, output_path)\nwhen \"html\"\n  write_html(data, output_path)\nwhen \"markdown\", \"md\"\n  write_markdown(data, output_path)\nelse\n  raise(Error.new(\"Unknown report format: #{format}. Use 'json', 'html', or 'markdown'.\"))\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/SectionData","path":"Shards/Compliance/SectionData.html","kind":"struct","full_name":"Shards::Compliance::SectionData","name":"SectionData","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_builder.cr","line_number":42,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L42"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":50,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L50"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"change_history:JSON::Any|Nil-instance-method","name":"change_history","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L48"},"def":{"name":"change_history","return_type":"JSON::Any | ::Nil","visibility":"Public","body":"@change_history"},"external_var":false},{"html_id":"change_history=(change_history:JSON::Any|Nil)-instance-method","name":"change_history=","abstract":false,"args":[{"name":"change_history","external_name":"change_history","restriction":"JSON::Any | ::Nil"}],"args_string":"(change_history : JSON::Any | Nil)","args_html":"(change_history : JSON::Any | Nil)","location":{"filename":"src/compliance/report_builder.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L48"},"def":{"name":"change_history=","args":[{"name":"change_history","external_name":"change_history","restriction":"JSON::Any | ::Nil"}],"visibility":"Public","body":"@change_history = change_history"},"external_var":false},{"html_id":"integrity:JSON::Any|Nil-instance-method","name":"integrity","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":47,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L47"},"def":{"name":"integrity","return_type":"JSON::Any | ::Nil","visibility":"Public","body":"@integrity"},"external_var":false},{"html_id":"integrity=(integrity:JSON::Any|Nil)-instance-method","name":"integrity=","abstract":false,"args":[{"name":"integrity","external_name":"integrity","restriction":"JSON::Any | ::Nil"}],"args_string":"(integrity : JSON::Any | Nil)","args_html":"(integrity : JSON::Any | Nil)","location":{"filename":"src/compliance/report_builder.cr","line_number":47,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L47"},"def":{"name":"integrity=","args":[{"name":"integrity","external_name":"integrity","restriction":"JSON::Any | ::Nil"}],"visibility":"Public","body":"@integrity = integrity"},"external_var":false},{"html_id":"license_audit:JSON::Any|Nil-instance-method","name":"license_audit","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":45,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L45"},"def":{"name":"license_audit","return_type":"JSON::Any | ::Nil","visibility":"Public","body":"@license_audit"},"external_var":false},{"html_id":"license_audit=(license_audit:JSON::Any|Nil)-instance-method","name":"license_audit=","abstract":false,"args":[{"name":"license_audit","external_name":"license_audit","restriction":"JSON::Any | ::Nil"}],"args_string":"(license_audit : JSON::Any | Nil)","args_html":"(license_audit : JSON::Any | Nil)","location":{"filename":"src/compliance/report_builder.cr","line_number":45,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L45"},"def":{"name":"license_audit=","args":[{"name":"license_audit","external_name":"license_audit","restriction":"JSON::Any | ::Nil"}],"visibility":"Public","body":"@license_audit = license_audit"},"external_var":false},{"html_id":"policy_compliance:JSON::Any|Nil-instance-method","name":"policy_compliance","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":46,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L46"},"def":{"name":"policy_compliance","return_type":"JSON::Any | ::Nil","visibility":"Public","body":"@policy_compliance"},"external_var":false},{"html_id":"policy_compliance=(policy_compliance:JSON::Any|Nil)-instance-method","name":"policy_compliance=","abstract":false,"args":[{"name":"policy_compliance","external_name":"policy_compliance","restriction":"JSON::Any | ::Nil"}],"args_string":"(policy_compliance : JSON::Any | Nil)","args_html":"(policy_compliance : JSON::Any | Nil)","location":{"filename":"src/compliance/report_builder.cr","line_number":46,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L46"},"def":{"name":"policy_compliance=","args":[{"name":"policy_compliance","external_name":"policy_compliance","restriction":"JSON::Any | ::Nil"}],"visibility":"Public","body":"@policy_compliance = policy_compliance"},"external_var":false},{"html_id":"sbom:JSON::Any|Nil-instance-method","name":"sbom","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":43,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L43"},"def":{"name":"sbom","return_type":"JSON::Any | ::Nil","visibility":"Public","body":"@sbom"},"external_var":false},{"html_id":"sbom=(sbom:JSON::Any|Nil)-instance-method","name":"sbom=","abstract":false,"args":[{"name":"sbom","external_name":"sbom","restriction":"JSON::Any | ::Nil"}],"args_string":"(sbom : JSON::Any | Nil)","args_html":"(sbom : JSON::Any | Nil)","location":{"filename":"src/compliance/report_builder.cr","line_number":43,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L43"},"def":{"name":"sbom=","args":[{"name":"sbom","external_name":"sbom","restriction":"JSON::Any | ::Nil"}],"visibility":"Public","body":"@sbom = sbom"},"external_var":false},{"html_id":"vulnerability_audit:JSON::Any|Nil-instance-method","name":"vulnerability_audit","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L44"},"def":{"name":"vulnerability_audit","return_type":"JSON::Any | ::Nil","visibility":"Public","body":"@vulnerability_audit"},"external_var":false},{"html_id":"vulnerability_audit=(vulnerability_audit:JSON::Any|Nil)-instance-method","name":"vulnerability_audit=","abstract":false,"args":[{"name":"vulnerability_audit","external_name":"vulnerability_audit","restriction":"JSON::Any | ::Nil"}],"args_string":"(vulnerability_audit : JSON::Any | Nil)","args_html":"(vulnerability_audit : JSON::Any | Nil)","location":{"filename":"src/compliance/report_builder.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L44"},"def":{"name":"vulnerability_audit=","args":[{"name":"vulnerability_audit","external_name":"vulnerability_audit","restriction":"JSON::Any | ::Nil"}],"visibility":"Public","body":"@vulnerability_audit = vulnerability_audit"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/Summary","path":"Shards/Compliance/Summary.html","kind":"struct","full_name":"Shards::Compliance::Summary","name":"Summary","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_builder.cr","line_number":26,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L26"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"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)-class-method","name":"new","abstract":false,"args":[{"name":"total_dependencies","external_name":"total_dependencies","restriction":"::Int32"},{"name":"direct_dependencies","external_name":"direct_dependencies","restriction":"::Int32"},{"name":"transitive_dependencies","external_name":"transitive_dependencies","restriction":"::Int32"},{"name":"vulnerabilities","external_name":"vulnerabilities","restriction":"::Shards::Compliance::VulnerabilityCounts"},{"name":"license_compliance","external_name":"license_compliance","restriction":"::String"},{"name":"policy_compliance","external_name":"policy_compliance","restriction":"::String"},{"name":"integrity_verified","external_name":"integrity_verified","restriction":"::Bool | ::Nil"},{"name":"overall_status","external_name":"overall_status","restriction":"::String"}],"args_string":"(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)","args_html":"(total_dependencies : Int32, direct_dependencies : Int32, transitive_dependencies : Int32, vulnerabilities : <a href=\"../../Shards/Compliance/VulnerabilityCounts.html\">Shards::Compliance::VulnerabilityCounts</a>, license_compliance : String, policy_compliance : String, integrity_verified : Bool | Nil, overall_status : String)","location":{"filename":"src/compliance/report_builder.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L36"},"def":{"name":"new","args":[{"name":"total_dependencies","external_name":"total_dependencies","restriction":"::Int32"},{"name":"direct_dependencies","external_name":"direct_dependencies","restriction":"::Int32"},{"name":"transitive_dependencies","external_name":"transitive_dependencies","restriction":"::Int32"},{"name":"vulnerabilities","external_name":"vulnerabilities","restriction":"::Shards::Compliance::VulnerabilityCounts"},{"name":"license_compliance","external_name":"license_compliance","restriction":"::String"},{"name":"policy_compliance","external_name":"policy_compliance","restriction":"::String"},{"name":"integrity_verified","external_name":"integrity_verified","restriction":"::Bool | ::Nil"},{"name":"overall_status","external_name":"overall_status","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(total_dependencies, direct_dependencies, transitive_dependencies, vulnerabilities, license_compliance, policy_compliance, integrity_verified, overall_status)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"direct_dependencies:Int32-instance-method","name":"direct_dependencies","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L28"},"def":{"name":"direct_dependencies","return_type":"Int32","visibility":"Public","body":"@direct_dependencies"},"external_var":false},{"html_id":"integrity_verified:Bool|Nil-instance-method","name":"integrity_verified","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L33"},"def":{"name":"integrity_verified","return_type":"Bool | ::Nil","visibility":"Public","body":"@integrity_verified"},"external_var":false},{"html_id":"license_compliance:String-instance-method","name":"license_compliance","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L31"},"def":{"name":"license_compliance","return_type":"String","visibility":"Public","body":"@license_compliance"},"external_var":false},{"html_id":"overall_status:String-instance-method","name":"overall_status","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":34,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L34"},"def":{"name":"overall_status","return_type":"String","visibility":"Public","body":"@overall_status"},"external_var":false},{"html_id":"policy_compliance:String-instance-method","name":"policy_compliance","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L32"},"def":{"name":"policy_compliance","return_type":"String","visibility":"Public","body":"@policy_compliance"},"external_var":false},{"html_id":"total_dependencies:Int32-instance-method","name":"total_dependencies","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L27"},"def":{"name":"total_dependencies","return_type":"Int32","visibility":"Public","body":"@total_dependencies"},"external_var":false},{"html_id":"transitive_dependencies:Int32-instance-method","name":"transitive_dependencies","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L29"},"def":{"name":"transitive_dependencies","return_type":"Int32","visibility":"Public","body":"@transitive_dependencies"},"external_var":false},{"html_id":"vulnerabilities:VulnerabilityCounts-instance-method","name":"vulnerabilities","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L30"},"def":{"name":"vulnerabilities","return_type":"VulnerabilityCounts","visibility":"Public","body":"@vulnerabilities"},"external_var":false}]},{"html_id":"Ashard/Shards/Compliance/VulnerabilityCounts","path":"Shards/Compliance/VulnerabilityCounts.html","kind":"struct","full_name":"Shards::Compliance::VulnerabilityCounts","name":"VulnerabilityCounts","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/compliance/report_builder.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L16"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Compliance","kind":"module","full_name":"Shards::Compliance","name":"Compliance"},"constructors":[{"html_id":"new(critical:Int32=0,high:Int32=0,medium:Int32=0,low:Int32=0)-class-method","name":"new","abstract":false,"args":[{"name":"critical","default_value":"0","external_name":"critical","restriction":"::Int32"},{"name":"high","default_value":"0","external_name":"high","restriction":"::Int32"},{"name":"medium","default_value":"0","external_name":"medium","restriction":"::Int32"},{"name":"low","default_value":"0","external_name":"low","restriction":"::Int32"}],"args_string":"(critical : Int32 = 0, high : Int32 = 0, medium : Int32 = 0, low : Int32 = 0)","args_html":"(critical : Int32 = <span class=\"n\">0</span>, high : Int32 = <span class=\"n\">0</span>, medium : Int32 = <span class=\"n\">0</span>, low : Int32 = <span class=\"n\">0</span>)","location":{"filename":"src/compliance/report_builder.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L22"},"def":{"name":"new","args":[{"name":"critical","default_value":"0","external_name":"critical","restriction":"::Int32"},{"name":"high","default_value":"0","external_name":"high","restriction":"::Int32"},{"name":"medium","default_value":"0","external_name":"medium","restriction":"::Int32"},{"name":"low","default_value":"0","external_name":"low","restriction":"::Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(critical, high, medium, low)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"critical:Int32-instance-method","name":"critical","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L17"},"def":{"name":"critical","return_type":"Int32","visibility":"Public","body":"@critical"},"external_var":false},{"html_id":"critical=(critical:Int32)-instance-method","name":"critical=","abstract":false,"args":[{"name":"critical","external_name":"critical","restriction":"Int32"}],"args_string":"(critical : Int32)","args_html":"(critical : Int32)","location":{"filename":"src/compliance/report_builder.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L17"},"def":{"name":"critical=","args":[{"name":"critical","external_name":"critical","restriction":"Int32"}],"visibility":"Public","body":"@critical = critical"},"external_var":false},{"html_id":"high:Int32-instance-method","name":"high","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L18"},"def":{"name":"high","return_type":"Int32","visibility":"Public","body":"@high"},"external_var":false},{"html_id":"high=(high:Int32)-instance-method","name":"high=","abstract":false,"args":[{"name":"high","external_name":"high","restriction":"Int32"}],"args_string":"(high : Int32)","args_html":"(high : Int32)","location":{"filename":"src/compliance/report_builder.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L18"},"def":{"name":"high=","args":[{"name":"high","external_name":"high","restriction":"Int32"}],"visibility":"Public","body":"@high = high"},"external_var":false},{"html_id":"low:Int32-instance-method","name":"low","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L20"},"def":{"name":"low","return_type":"Int32","visibility":"Public","body":"@low"},"external_var":false},{"html_id":"low=(low:Int32)-instance-method","name":"low=","abstract":false,"args":[{"name":"low","external_name":"low","restriction":"Int32"}],"args_string":"(low : Int32)","args_html":"(low : Int32)","location":{"filename":"src/compliance/report_builder.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L20"},"def":{"name":"low=","args":[{"name":"low","external_name":"low","restriction":"Int32"}],"visibility":"Public","body":"@low = low"},"external_var":false},{"html_id":"medium:Int32-instance-method","name":"medium","abstract":false,"location":{"filename":"src/compliance/report_builder.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L19"},"def":{"name":"medium","return_type":"Int32","visibility":"Public","body":"@medium"},"external_var":false},{"html_id":"medium=(medium:Int32)-instance-method","name":"medium=","abstract":false,"args":[{"name":"medium","external_name":"medium","restriction":"Int32"}],"args_string":"(medium : Int32)","args_html":"(medium : Int32)","location":{"filename":"src/compliance/report_builder.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/compliance/report_builder.cr#L19"},"def":{"name":"medium=","args":[{"name":"medium","external_name":"medium","restriction":"Int32"}],"visibility":"Public","body":"@medium = medium"},"external_var":false}]}]},{"html_id":"Ashard/Shards/ComplianceMCPServer","path":"Shards/ComplianceMCPServer.html","kind":"class","full_name":"Shards::ComplianceMCPServer","name":"ComplianceMCPServer","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/mcp/compliance_server.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L7"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CAPABILITIES","name":"CAPABILITIES","value":"MCProtocol::ServerCapabilities.new(tools: MCProtocol::ServerCapabilitiesTools.new)"},{"id":"HELP_TEXT","name":"HELP_TEXT","value":"\"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\""},{"id":"LATEST_VERSION","name":"LATEST_VERSION","value":"SUPPORTED_VERSIONS.first"},{"id":"MCP_SERVER_NAME","name":"MCP_SERVER_NAME","value":"\"shards-compliance\""},{"id":"SERVER_INFO","name":"SERVER_INFO","value":"MCProtocol::Implementation.new(name: \"shards-compliance\", version: Shards::VERSION)"},{"id":"SUPPORTED_VERSIONS","name":"SUPPORTED_VERSIONS","value":"[\"2025-11-25\", \"2025-06-18\", \"2025-03-26\", \"2024-11-05\"]","doc":"Supported MCP protocol versions, newest first.\nThe server negotiates the highest version both client and server support.","summary":"<p>Supported MCP protocol versions, newest first.</p>"},{"id":"TOOLS","name":"TOOLS","value":"[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\")})})))]"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"init_claude_config(path:String)-class-method","name":"init_claude_config","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/mcp/compliance_server.cr","line_number":241,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L241"},"def":{"name":"init_claude_config","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"installed = ClaudeConfig.install(path)\n\nif installed.empty?\n  puts(\"Claude Code skills and agents already configured\")\nelse\n  puts(\"\")\n  puts(\"Installed #{installed.size} Claude Code files:\")\n  skills = installed.select(&.includes?(\"/skills/\"))\n  agents = installed.select(&.includes?(\"/agents/\"))\n  other = installed.reject do |f| (f.includes?(\"/skills/\")) || (f.includes?(\"/agents/\")) end\n\n  skills.each do |f| puts(\"  skill:    #{f}\") end\n  agents.each do |f| puts(\"  agent:    #{f}\") end\n  other.each do |f| puts(\"  config:   #{f}\") end\n\n  puts(\"\")\n  puts(\"Available skills: /audit, /licenses, /policy-check, /diff-deps, /compliance-report, /sbom\")\n  puts(\"Available agents: compliance-checker, security-reviewer\")\nend\n"},"external_var":false},{"html_id":"init_mcp_config(path:String)-class-method","name":"init_mcp_config","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/mcp/compliance_server.cr","line_number":191,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L191"},"def":{"name":"init_mcp_config","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"mcp_path = File.join(path, \".mcp.json\")\nexecutable = find_executable_for_config\n\nserver_entry = {\"command\" => executable, \"args\" => [\"mcp-server\"]}\n\nif File.exists?(mcp_path)\n  begin\n    existing = JSON.parse(File.read(mcp_path))\n    servers = existing[\"mcpServers\"]?.try(&.as_h?) || ({} of String => JSON::Any)\n\n    if servers.has_key?(MCP_SERVER_NAME)\n      puts(\"#{MCP_SERVER_NAME} is already configured in .mcp.json\")\n      return\n    end\n\n\n    servers[MCP_SERVER_NAME] = JSON.parse(server_entry.to_json)\n    config = existing.as_h.dup\n    config[\"mcpServers\"] = JSON.parse(servers.to_json)\n\n    File.write(mcp_path, config.to_pretty_json + \"\\n\")\n    puts(\"Added #{MCP_SERVER_NAME} to existing .mcp.json\")\n  rescue ex\n    STDERR.puts(\"Error reading existing .mcp.json: #{ex.message}\")\n    STDERR.puts(\"Creating a new .mcp.json instead.\")\n    write_new_mcp_config(mcp_path, server_entry)\n  end\nelse\n  write_new_mcp_config(mcp_path, server_entry)\nend\n\nputs(\"\")\nputs(\"MCP server configured.\")\nputs(\"Tools available: audit, licenses, policy_check, diff, compliance_report, sbom\")\n"},"external_var":false},{"html_id":"run(path:String,args:Array(String)=[]ofString)-class-method","name":"run","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"args","default_value":"[] of String","external_name":"args","restriction":"Array(String)"}],"args_string":"(path : String, args : Array(String) = [] of String)","args_html":"(path : String, args : Array(String) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">String</span>)","location":{"filename":"src/mcp/compliance_server.cr","line_number":174,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L174"},"def":{"name":"run","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"args","default_value":"[] of String","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"if (args.includes?(\"--help\")) || (args.includes?(\"-h\"))\n  puts(HELP_TEXT)\n  return\nend\n\nif args.includes?(\"init\")\n  init_mcp_config(path)\n  puts(\"\")\n  puts(\"MCP server configured. Run 'shards-alpha assistant init' for skills, agents, and Claude Code config.\")\n  return\nend\n\ninteractive = args.includes?(\"--interactive\")\n(new(path, interactive)).run\n"},"external_var":false}],"constructors":[{"html_id":"new(path:String,interactive:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"interactive","default_value":"false","external_name":"interactive","restriction":"Bool"}],"args_string":"(path : String, interactive : Bool = false)","args_html":"(path : String, interactive : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/mcp/compliance_server.cr","line_number":170,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L170"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"interactive","default_value":"false","external_name":"interactive","restriction":"Bool"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, interactive)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"build_cli_args(tool_name:String,arguments:JSON::Any|Nil):Array(String)-instance-method","name":"build_cli_args","doc":"Build CLI arguments from tool name and parameters","summary":"<p>Build CLI arguments from tool name and parameters</p>","abstract":false,"args":[{"name":"tool_name","external_name":"tool_name","restriction":"String"},{"name":"arguments","external_name":"arguments","restriction":"JSON::Any | ::Nil"}],"args_string":"(tool_name : String, arguments : JSON::Any | Nil) : Array(String)","args_html":"(tool_name : String, arguments : JSON::Any | Nil) : Array(String)","location":{"filename":"src/mcp/compliance_server.cr","line_number":502,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L502"},"def":{"name":"build_cli_args","args":[{"name":"tool_name","external_name":"tool_name","restriction":"String"},{"name":"arguments","external_name":"arguments","restriction":"JSON::Any | ::Nil"}],"return_type":"Array(String)","visibility":"Public","body":"args = [] of String\n\ncase tool_name\nwhen \"audit\"\n  (args << \"audit\") << \"--format=json\"\n  if arguments\n    if v = arguments[\"severity\"]?.try(&.as_s)\n      args << \"--severity=#{v}\"\n    end\n    if v = arguments[\"fail_above\"]?.try(&.as_s)\n      args << \"--fail-above=#{v}\"\n    end\n    if v = arguments[\"ignore\"]?.try(&.as_s)\n      args << \"--ignore=#{v}\"\n    end\n    if arguments[\"offline\"]?.try(&.as_bool)\n      args << \"--offline\"\n    end\n  end\nwhen \"licenses\"\n  (args << \"licenses\") << \"--format=json\"\n  if arguments\n    if arguments[\"check\"]?.try(&.as_bool)\n      args << \"--check\"\n    end\n    if arguments[\"detect\"]?.try(&.as_bool)\n      args << \"--detect\"\n    end\n    if arguments[\"include_dev\"]?.try(&.as_bool)\n      args << \"--include-dev\"\n    end\n  end\nwhen \"policy_check\"\n  ((args << \"policy\") << \"check\") << \"--format=json\"\n  if arguments\n    if arguments[\"strict\"]?.try(&.as_bool)\n      args << \"--strict\"\n    end\n  end\nwhen \"diff\"\n  (args << \"diff\") << \"--format=json\"\n  if arguments\n    if v = arguments[\"from\"]?.try(&.as_s)\n      args << \"--from=#{v}\"\n    end\n    if v = arguments[\"to\"]?.try(&.as_s)\n      args << \"--to=#{v}\"\n    end\n  end\nwhen \"compliance_report\"\n  (args << \"compliance-report\") << \"--format=json\"\n  if arguments\n    if v = arguments[\"sections\"]?.try(&.as_s)\n      args << \"--sections=#{v}\"\n    end\n    if v = arguments[\"reviewer\"]?.try(&.as_s)\n      args << \"--reviewer=#{v}\"\n    end\n  end\nwhen \"sbom\"\n  fmt = arguments.try() do |__arg21| __arg21[\"format\"]?.try(&.as_s) end || \"spdx\"\n  ((args << \"sbom\") << \"--format=#{fmt}\") << \"--output=/dev/stdout\"\n  if arguments\n    if arguments[\"include_dev\"]?.try(&.as_bool)\n      args << \"--include-dev\"\n    end\n  end\nend\n\nargs\n"},"external_var":false},{"html_id":"negotiate_version(client_version:String|Nil):String-instance-method","name":"negotiate_version","doc":"Negotiate the best protocol version.\nIf the client requests a version we support, use it.\nIf the client requests a version newer than our latest, use our latest.\nIf the client requests an older version we don't support, use our oldest.\nIf no version is provided, use the latest.","summary":"<p>Negotiate the best protocol version.</p>","abstract":false,"args":[{"name":"client_version","external_name":"client_version","restriction":"String | ::Nil"}],"args_string":"(client_version : String | Nil) : String","args_html":"(client_version : String | Nil) : String","location":{"filename":"src/mcp/compliance_server.cr","line_number":411,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L411"},"def":{"name":"negotiate_version","args":[{"name":"client_version","external_name":"client_version","restriction":"String | ::Nil"}],"return_type":"String","visibility":"Public","body":"if client_version\nelse\n  return LATEST_VERSION\nend\n\n\nif SUPPORTED_VERSIONS.includes?(client_version)\n  return client_version\nend\n\n\n\n\nSUPPORTED_VERSIONS.each do |v|\n  if v <= client_version\n    return v\n  end\nend\n\n\nSUPPORTED_VERSIONS.last\n"},"external_var":false},{"html_id":"run-instance-method","name":"run","abstract":false,"location":{"filename":"src/mcp/compliance_server.cr","line_number":277,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp/compliance_server.cr#L277"},"def":{"name":"run","visibility":"Public","body":"STDIN.sync = true\nSTDOUT.sync = true\nSTDERR.sync = true\n\nif @interactive\n  run_interactive\nelse\n  run_stdio\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Conflict","path":"Shards/Conflict.html","kind":"class","full_name":"Shards::Conflict","name":"Conflict","abstract":false,"superclass":{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},"ancestors":[{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/errors.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(package:Package)-class-method","name":"new","abstract":false,"args":[{"name":"package","external_name":"package","restriction":"Package"}],"args_string":"(package : Package)","args_html":"(package : <a href=\"../Shards/Package.html\">Package</a>)","location":{"filename":"src/errors.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L8"},"def":{"name":"new","args":[{"name":"package","external_name":"package","restriction":"Package"}],"visibility":"Public","body":"_ = allocate\n_.initialize(package)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"package:Shards::Package-instance-method","name":"package","abstract":false,"location":{"filename":"src/errors.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L6"},"def":{"name":"package","visibility":"Public","body":"@package"},"external_var":false}]},{"html_id":"Ashard/Shards/CrystalResolver","path":"Shards/CrystalResolver.html","kind":"class","full_name":"Shards::CrystalResolver","name":"CrystalResolver","abstract":false,"superclass":{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},"ancestors":[{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/crystal.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/crystal.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"INSTANCE","name":"INSTANCE","value":"new(\"crystal\", \"\")"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"key-class-method","name":"key","abstract":false,"location":{"filename":"src/resolvers/crystal.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/crystal.cr#L5"},"def":{"name":"key","visibility":"Public","body":"\"crystal\""},"external_var":false}],"instance_methods":[{"html_id":"available_releases:Array(Version)-instance-method","name":"available_releases","abstract":false,"location":{"filename":"src/resolvers/crystal.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/crystal.cr#L9"},"def":{"name":"available_releases","return_type":"Array(Version)","visibility":"Public","body":"[Version.new(Shards.crystal_version)]"},"external_var":false},{"html_id":"install_sources(version:Version,install_path:String)-instance-method","name":"install_sources","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"args_string":"(version : Version, install_path : String)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>, install_path : String)","location":{"filename":"src/resolvers/crystal.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/crystal.cr#L17"},"def":{"name":"install_sources","args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"visibility":"Public","body":"raise(NotImplementedError.new(\"CrystalResolver#install_sources\"))"},"external_var":false},{"html_id":"read_spec(version:Version):String|Nil-instance-method","name":"read_spec","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String | Nil","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String | Nil","location":{"filename":"src/resolvers/crystal.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/crystal.cr#L13"},"def":{"name":"read_spec","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String | ::Nil","visibility":"Public","body":"nil"},"external_var":false},{"html_id":"report_version(version:Version):String-instance-method","name":"report_version","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String","location":{"filename":"src/resolvers/crystal.cr","line_number":21,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/crystal.cr#L21"},"def":{"name":"report_version","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String","visibility":"Public","body":"version.value"},"external_var":false}]},{"html_id":"Ashard/Shards/Dependency","path":"Shards/Dependency.html","kind":"class","full_name":"Shards::Dependency","name":"Dependency","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/dependency.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"from_yaml(pull:YAML::PullParser)-class-method","name":"from_yaml","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"args_string":"(pull : YAML::PullParser)","args_html":"(pull : <a href=\"../YAML/PullParser.html\">YAML::PullParser</a>)","location":{"filename":"src/dependency.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L15"},"def":{"name":"from_yaml","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"visibility":"Public","body":"mapping_start = pull.location\nname = pull.read_scalar\npull.read_mapping do\n  resolver_data = nil\n  params = Hash(String, String).new\n  checksum : String | ::Nil = nil\n\n  while !pull.kind.mapping_end?\n    location = pull.location\n    key, value = pull.read_scalar, pull.read_scalar\n\n    if key == \"checksum\"\n      checksum = value\n    elsif type = Resolver.find_class(key)\n      if resolver_data\n        raise(YAML::ParseException.new(\"Duplicate resolver mapping for dependency #{name.inspect}\", *location))\n      else\n        resolver_data = {type: type, key: key, source: value}\n      end\n    else\n      params[key] = value\n    end\n  end\n\n  if resolver_data\n  else\n    raise(YAML::ParseException.new(\"Missing resolver for dependency #{name.inspect}\", *mapping_start))\n  end\n\n  resolver = resolver_data[:type].find_resolver(resolver_data[:key], name, resolver_data[:source])\n\n  requirement = resolver.parse_requirement(params)\n  dep = Dependency.new(name, resolver, requirement)\n  dep.checksum = checksum\n  dep\nend\n"},"external_var":false}],"constructors":[{"html_id":"new(name:String,resolver:Resolver,requirement:Requirement=Any)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"resolver","external_name":"resolver","restriction":"Resolver"},{"name":"requirement","default_value":"Any","external_name":"requirement","restriction":"Requirement"}],"args_string":"(name : String, resolver : Resolver, requirement : Requirement = Any)","args_html":"(name : String, resolver : <a href=\"../Shards/Resolver.html\">Resolver</a>, requirement : <a href=\"../Shards/Requirement.html\">Requirement</a> = <span class=\"t\">Any</span>)","location":{"filename":"src/dependency.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L12"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"resolver","external_name":"resolver","restriction":"Resolver"},{"name":"requirement","default_value":"Any","external_name":"requirement","restriction":"Requirement"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, resolver, requirement)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"==(other:self)-instance-method","name":"==","doc":"Returns `true` if this reference is the same as *other*. Invokes `same?`.","summary":"<p>Returns <code>true</code> if this reference is the same as <em>other</em>.</p>","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"self"}],"args_string":"(other : self)","args_html":"(other : <span class=\"k\">self</span>)","location":{"filename":"src/dependency.cr","line_number":81,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L81"},"def":{"name":"==","args":[{"name":"other","external_name":"other","restriction":"self"}],"visibility":"Public","body":"if same?(other)\n  return true\nend\n\n\nif @name == (other.@name)\nelse\n  return false\nend\n\nif @resolver == (other.@resolver)\nelse\n  return false\nend\n\nif @requirement == (other.@requirement)\nelse\n  return false\nend\n\ntrue\n"},"external_var":false},{"html_id":"as_package?-instance-method","name":"as_package?","abstract":false,"location":{"filename":"src/dependency.cr","line_number":62,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L62"},"def":{"name":"as_package?","visibility":"Public","body":"version = case req = @requirement\nwhen VersionReq\n  Version.new(req.to_s)\nelse\n  versions = @resolver.versions_for(req)\n  if versions.size == 1\n  else\n    return\n  end\n  versions.first\nend\n\npkg = Package.new(@name, @resolver, version)\npkg.checksum = @checksum\npkg\n"},"external_var":false},{"html_id":"checksum:String|Nil-instance-method","name":"checksum","abstract":false,"location":{"filename":"src/dependency.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L10"},"def":{"name":"checksum","return_type":"String | ::Nil","visibility":"Public","body":"@checksum"},"external_var":false},{"html_id":"checksum=(checksum:String|Nil)-instance-method","name":"checksum=","abstract":false,"args":[{"name":"checksum","external_name":"checksum","restriction":"String | ::Nil"}],"args_string":"(checksum : String | Nil)","args_html":"(checksum : String | Nil)","location":{"filename":"src/dependency.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L10"},"def":{"name":"checksum=","args":[{"name":"checksum","external_name":"checksum","restriction":"String | ::Nil"}],"visibility":"Public","body":"@checksum = checksum"},"external_var":false},{"html_id":"matches?(version:Version)-instance-method","name":"matches?","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/dependency.cr","line_number":107,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L107"},"def":{"name":"matches?","args":[{"name":"version","external_name":"version","restriction":"Version"}],"visibility":"Public","body":"case req = requirement\nwhen Ref\n  resolver.matches_ref?(req, version)\nwhen Version\n  req == version\nwhen VersionReq\n  Versions.matches?(version, req)\nwhen Any\n  true\nend"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/dependency.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/dependency.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L7"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"},"external_var":false},{"html_id":"prerelease?-instance-method","name":"prerelease?","abstract":false,"location":{"filename":"src/dependency.cr","line_number":83,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L83"},"def":{"name":"prerelease?","visibility":"Public","body":"case req = requirement\nwhen Version\n  req.prerelease?\nwhen VersionReq\n  req.prerelease?\nelse\n  false\nend"},"external_var":false},{"html_id":"requirement:Requirement-instance-method","name":"requirement","abstract":false,"location":{"filename":"src/dependency.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L9"},"def":{"name":"requirement","return_type":"Requirement","visibility":"Public","body":"@requirement"},"external_var":false},{"html_id":"requirement=(requirement:Requirement)-instance-method","name":"requirement=","abstract":false,"args":[{"name":"requirement","external_name":"requirement","restriction":"Requirement"}],"args_string":"(requirement : Requirement)","args_html":"(requirement : <a href=\"../Shards/Requirement.html\">Requirement</a>)","location":{"filename":"src/dependency.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L9"},"def":{"name":"requirement=","args":[{"name":"requirement","external_name":"requirement","restriction":"Requirement"}],"visibility":"Public","body":"@requirement = requirement"},"external_var":false},{"html_id":"resolver:Resolver-instance-method","name":"resolver","abstract":false,"location":{"filename":"src/dependency.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L8"},"def":{"name":"resolver","return_type":"Resolver","visibility":"Public","body":"@resolver"},"external_var":false},{"html_id":"resolver=(resolver:Resolver)-instance-method","name":"resolver=","abstract":false,"args":[{"name":"resolver","external_name":"resolver","restriction":"Resolver"}],"args_string":"(resolver : Resolver)","args_html":"(resolver : <a href=\"../Shards/Resolver.html\">Resolver</a>)","location":{"filename":"src/dependency.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L8"},"def":{"name":"resolver=","args":[{"name":"resolver","external_name":"resolver","restriction":"Resolver"}],"visibility":"Public","body":"@resolver = resolver"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/dependency.cr","line_number":103,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L103"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(((io << name) << \" (\") << report_requirement) << \")\""},"external_var":false},{"html_id":"to_yaml(yaml:YAML::Builder)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":"YAML::Builder"}],"args_string":"(yaml : YAML::Builder)","args_html":"(yaml : YAML::Builder)","location":{"filename":"src/dependency.cr","line_number":53,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/dependency.cr#L53"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":"YAML::Builder"}],"visibility":"Public","body":"yaml.scalar(name)\nyaml.mapping do\n  yaml.scalar(resolver.class.key)\n  yaml.scalar(resolver.source)\n  requirement.to_yaml(yaml)\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/DiffReport","path":"Shards/DiffReport.html","kind":"class","full_name":"Shards::DiffReport","name":"DiffReport","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/diff_report.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(changes:Array(Shards::LockfileDiffer::Change),from_label:String=\"HEAD\",to_label:String=\"workingtree\")-class-method","name":"new","abstract":false,"args":[{"name":"changes","external_name":"changes","restriction":"::Array(::Shards::LockfileDiffer::Change)"},{"name":"from_label","default_value":"\"HEAD\"","external_name":"from_label","restriction":"::String"},{"name":"to_label","default_value":"\"working tree\"","external_name":"to_label","restriction":"::String"}],"args_string":"(changes : Array(Shards::LockfileDiffer::Change), from_label : String = \"HEAD\", to_label : String = \"working tree\")","args_html":"(changes : Array(<a href=\"../Shards/LockfileDiffer/Change.html\">Shards::LockfileDiffer::Change</a>), from_label : String = <span class=\"s\">&quot;HEAD&quot;</span>, to_label : String = <span class=\"s\">&quot;working tree&quot;</span>)","location":{"filename":"src/diff_report.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L10"},"def":{"name":"new","args":[{"name":"changes","external_name":"changes","restriction":"::Array(::Shards::LockfileDiffer::Change)"},{"name":"from_label","default_value":"\"HEAD\"","external_name":"from_label","restriction":"::String"},{"name":"to_label","default_value":"\"working tree\"","external_name":"to_label","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(changes, from_label, to_label)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"any_changes?:Bool-instance-method","name":"any_changes?","abstract":false,"location":{"filename":"src/diff_report.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L13"},"def":{"name":"any_changes?","return_type":"Bool","visibility":"Public","body":"changes.any? do |c| c.status != LockfileDiffer::Status::Unchanged end"},"external_var":false},{"html_id":"changes:Array(LockfileDiffer::Change)-instance-method","name":"changes","abstract":false,"location":{"filename":"src/diff_report.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L6"},"def":{"name":"changes","return_type":"Array(LockfileDiffer::Change)","visibility":"Public","body":"@changes"},"external_var":false},{"html_id":"from_label:String-instance-method","name":"from_label","abstract":false,"location":{"filename":"src/diff_report.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L7"},"def":{"name":"from_label","return_type":"String","visibility":"Public","body":"@from_label"},"external_var":false},{"html_id":"to_json(io:IO=STDOUT):Nil-instance-method","name":"to_json","abstract":false,"args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"args_string":"(io : IO = STDOUT) : Nil","args_html":"(io : IO = <span class=\"t\">STDOUT</span>) : Nil","location":{"filename":"src/diff_report.cr","line_number":61,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L61"},"def":{"name":"to_json","args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"return_type":"Nil","visibility":"Public","body":"actual = changes.reject do |c| c.status == LockfileDiffer::Status::Unchanged end\n\nadded_arr = actual.select() do |__arg0| __arg0.status.added? end\nremoved_arr = actual.select() do |__arg1| __arg1.status.removed? end\nupdated_arr = actual.select() do |__arg2| __arg2.status.updated? end\n\nresult = {\n  from: from_label,\n  to: to_label,\n  changes: {\n    added: added_arr.map do |c| change_to_json_hash(c) end,\n    removed: removed_arr.map do |c| change_to_json_hash(c) end,\n    updated: updated_arr.map do |c| change_to_json_hash(c) end,\n  },\n  summary: {\n    added: added_arr.size,\n    removed: removed_arr.size,\n    updated: updated_arr.size,\n  },\n}\n\nio.puts(result.to_json)\n"},"external_var":false},{"html_id":"to_label:String-instance-method","name":"to_label","abstract":false,"location":{"filename":"src/diff_report.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L8"},"def":{"name":"to_label","return_type":"String","visibility":"Public","body":"@to_label"},"external_var":false},{"html_id":"to_markdown(io:IO=STDOUT):Nil-instance-method","name":"to_markdown","abstract":false,"args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"args_string":"(io : IO = STDOUT) : Nil","args_html":"(io : IO = <span class=\"t\">STDOUT</span>) : Nil","location":{"filename":"src/diff_report.cr","line_number":86,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L86"},"def":{"name":"to_markdown","args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"return_type":"Nil","visibility":"Public","body":"actual = changes.reject do |c| c.status == LockfileDiffer::Status::Unchanged end\n\nio.puts(\"## Dependency Changes\")\nio.puts\nio.puts(\"| Status | Dependency | Version | Source |\")\nio.puts(\"|--------|-----------|---------|--------|\")\n\nactual.each do |change|\n  status_str = change.status.to_s\n  version_str = case change.status\n  when .added?\n    change.to_version.to_s\n  when .removed?\n    change.from_version.to_s\n  when .updated?\n    \"#{change.from_version} -> #{change.to_version}\"\n  else\n    \"\"\n  end\n  source_str = (change.to_source || change.from_source) || \"\"\n  io.puts(\"| #{status_str} | #{change.name} | #{version_str} | #{source_str} |\")\nend\n\nadded = actual.count() do |__arg3| __arg3.status.added? end\nupdated = actual.count() do |__arg4| __arg4.status.updated? end\nremoved = actual.count() do |__arg5| __arg5.status.removed? end\n\nio.puts\nio.puts(\"**Summary:** #{added} added, #{updated} updated, #{removed} removed\")\n"},"external_var":false},{"html_id":"to_terminal(io:IO=STDOUT):Nil-instance-method","name":"to_terminal","abstract":false,"args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"args_string":"(io : IO = STDOUT) : Nil","args_html":"(io : IO = <span class=\"t\">STDOUT</span>) : Nil","location":{"filename":"src/diff_report.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/diff_report.cr#L17"},"def":{"name":"to_terminal","args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"return_type":"Nil","visibility":"Public","body":"actual = changes.reject do |c| c.status == LockfileDiffer::Status::Unchanged end\nif actual.empty?\n  return\nend\n\nio.puts(\"Dependency Changes (from #{from_label} to #{to_label}):\")\nio.puts\n\nadded = 0\nupdated = 0\nremoved = 0\n\nactual.each do |change|\n  case change.status\n  when .added?\n    added = added + 1\n    icon = \"+\"\n    version_str = \"-> #{change.to_version}\"\n    source_str = change.to_source ? \"  #{change.to_resolver_key}:#{change.to_source}\" : \"\"\n    io.puts(\"  #{icon} #{change.name.ljust(20)} #{version_str}#{source_str}\")\n  when .updated?\n    updated = updated + 1\n    icon = \"^\"\n    version_str = \"#{change.from_version} -> #{change.to_version}\"\n    commit_str = \"\"\n    if (change.from_commit && change.to_commit) && (change.from_commit != change.to_commit)\n      commit_str = \"  (commit #{change.from_commit.not_nil![0..6]}..#{change.to_commit.not_nil![0..6]})\"\n    end\n    source_change = \"\"\n    if change.from_source != change.to_source\n      source_change = \"  SOURCE CHANGED\"\n    end\n    io.puts(\"  #{icon} #{change.name.ljust(20)} #{version_str}#{commit_str}#{source_change}\")\n  when .removed?\n    removed = removed + 1\n    icon = \"x\"\n    version_str = \"#{change.from_version} -> removed\"\n    io.puts(\"  #{icon} #{change.name.ljust(20)} #{version_str}\")\n  end\nend\n\nio.puts\nio.puts(\"Summary: #{added} added, #{updated} updated, #{removed} removed\")\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Docs","path":"Shards/Docs.html","kind":"module","full_name":"Shards::Docs","name":"Docs","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L18"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"# Shards Documentation\n\nShards is the dependency manager for the Crystal programming language.\nIt reads `shard.yml` to resolve, install, and update dependencies from\nsource repositories.\n\n## Features\n\n- **Dependency resolution** via `shard.yml` with semantic versioning\n- **Lock files** (`shard.lock`) for reproducible builds\n- **Build targets** for compiling Crystal executables\n- **Postinstall scripts** with version-aware execution tracking\n- **AI documentation distribution** from shard dependencies\n- **MCP server distribution** via `.mcp-shards.json`\n\nSee `Shards::Docs` submodules for detailed guides on each feature area.","summary":"<h1><a id=\"shards-documentation\" class=\"anchor\" href=\"#shards-documentation\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>Shards Documentation</h1>","types":[{"html_id":"Ashard/Shards/Docs/AIDocumentation","path":"Shards/Docs/AIDocumentation.html","kind":"module","full_name":"Shards::Docs::AIDocumentation","name":"AIDocumentation","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":85,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L85"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## AI Documentation Distribution\n\nShards can distribute AI coding agent documentation alongside library\ncode. When you run `shards install`, AI docs from dependencies are\nautomatically installed into the project's `.claude/` directory.\n\n### How It Works\n\nThe `AIDocsInstaller` scans each installed dependency for AI-relevant\nfiles and copies them into the project with shard-namespaced paths.\n\n### Auto-detected locations\n\nThese paths are scanned in each dependency:\n\n| Source in shard | What it is |\n|---|---|\n| `.claude/skills/<name>/` | Claude Code skills |\n| `.claude/agents/<name>.md` | Agent definitions |\n| `.claude/commands/<name>.md` | Slash commands |\n| `CLAUDE.md` | General AI context |\n| `AGENTS.md` | Agent specifications |\n| `.mcp.json` | MCP server configs |\n\n### Installation mapping\n\nFiles are namespaced by shard name to prevent conflicts:\n\n| Source | Destination |\n|---|---|\n| `.claude/skills/<name>/` | `.claude/skills/<shard>--<name>/` |\n| `.claude/agents/<name>.md` | `.claude/agents/<shard>--<name>.md` |\n| `.claude/commands/<name>.md` | `.claude/commands/<shard>:<name>.md` |\n| `CLAUDE.md` (no skills) | `.claude/skills/<shard>--docs/SKILL.md` |\n| `CLAUDE.md` (with skills) | `.claude/skills/<shard>--docs/reference/CLAUDE.md` |\n| `AGENTS.md` | `.claude/skills/<shard>--docs/reference/AGENTS.md` |\n| `.mcp.json` | merged into `.mcp-shards.json` |\n\nWhen a shard ships `CLAUDE.md` but no explicit skills, the content is\nwrapped as a passive skill with frontmatter (`user-invocable: false`).\n\n### Conflict detection\n\n`AIDocsInfo` tracks two checksums per file (upstream and installed).\nUser-modified files are preserved during updates, with a `.upstream`\ncopy saved for comparison. See `AIDocsInfo::FileEntry#user_modified?`.\n\n### Security\n\n`.claude/settings.json` and `.claude/settings.local.json` are never\ndistributed, even if present in a dependency.\n\n### shard.yml configuration\n\nThe `ai_docs` section is optional. Auto-detection handles standard\nlocations. Use it only for customization:\n\n```yaml\nai_docs:\n  include:\n    - docs/claude/custom_guide.md\n  exclude:\n    - .claude/skills/internal_dev_tool/\n```\n\nSee `Spec::AIDocs`, `AIDocsInstaller`, `AIDocsInfo`.","summary":"<h2><a id=\"ai-documentation-distribution\" class=\"anchor\" href=\"#ai-documentation-distribution\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>AI Documentation Distribution</h2>"},{"html_id":"Ashard/Shards/Docs/CLIReference","path":"Shards/Docs/CLIReference.html","kind":"module","full_name":"Shards::Docs::CLIReference","name":"CLIReference","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":256,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L256"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## CLI Commands Reference\n\n### Core commands\n\n| Command | Description |\n|---|---|\n| `shards install` | Install dependencies from `shard.yml` |\n| `shards update [names...]` | Update dependencies to latest compatible |\n| `shards build [targets...]` | Build targets defined in `shard.yml` |\n| `shards run [target]` | Build and run a target |\n| `shards check` | Verify all dependencies are installed |\n| `shards list [--tree]` | List installed dependencies |\n| `shards lock [--update]` | Lock dependencies without installing |\n| `shards outdated [--pre]` | Show outdated dependencies |\n| `shards prune` | Remove unused dependencies |\n| `shards version [path]` | Print the shard version |\n| `shards init` | Generate a new `shard.yml` |\n\n### AI docs commands\n\n| Command | Description |\n|---|---|\n| `shards ai-docs` | Show installed AI docs status |\n| `shards ai-docs diff <shard>` | Diff local changes vs upstream |\n| `shards ai-docs reset <shard> [file]` | Reset to upstream version |\n| `shards ai-docs update [shard]` | Force re-install AI docs |\n| `shards ai-docs merge-mcp` | Merge shard MCP configs into `.mcp.json` |\n| `shards run-script [names...]` | Run pending postinstall scripts |\n| `shards docs [options]` | Generate themed docs with AI buttons |\n| `shards sbom [options]` | Generate SBOM (SPDX/CycloneDX) |\n\n### MCP lifecycle commands\n\n| Command | Description |\n|---|---|\n| `shards mcp` | Show MCP server status (default) |\n| `shards mcp start [name]` | Start all or one MCP server |\n| `shards mcp stop [name]` | Stop all or one MCP server |\n| `shards mcp restart [name]` | Restart all or one MCP server |\n| `shards mcp logs <name>` | Tail server logs (`--no-follow`, `--lines=N`) |\n\n### Global flags\n\n| Flag | Description |\n|---|---|\n| `--frozen` | Strictly install locked versions |\n| `--without-development` | Skip dev dependencies |\n| `--production` | `--frozen --without-development` |\n| `--skip-postinstall` | Skip postinstall scripts |\n| `--skip-executables` | Skip executable installation |\n| `--skip-ai-docs` | Skip AI documentation installation |\n| `--local` | Use local cache only |\n| `--jobs=N` | Parallel downloads (default: 8) |\n\nSee individual command classes in `Commands`.","summary":"<h2><a id=\"cli-commands-reference\" class=\"anchor\" href=\"#cli-commands-reference\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>CLI Commands Reference</h2>"},{"html_id":"Ashard/Shards/Docs/DocsGeneration","path":"Shards/Docs/DocsGeneration.html","kind":"module","full_name":"Shards::Docs::DocsGeneration","name":"DocsGeneration","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":454,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L454"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## Documentation Generation and Theming\n\nThe `shards docs` command wraps `crystal docs` to add theming support,\nAI assistant integration buttons, LLM-oriented text exports, and\npublishable copies of project agent files.\n\n### Usage\n\n```\nshards docs                       # Generate docs with defaults\nshards docs --skip-ai-buttons     # No AI buttons\nshards docs --skip-agent-files    # Do not copy .claude/.mcp resources\nshards docs --skip-llms           # Do not generate llms.txt exports\nshards docs -o my_docs            # Custom output directory\n```\n\nAll standard `crystal docs` options are passed through.\n\n### Theming with CSS Variables\n\n`shards docs` injects CSS custom properties into the generated\nstylesheet. To create a custom theme, create `docs-theme/style.css`\nin your project root and override the variables:\n\n```css\n:root {\n  --sidebar-bg: #1a1a2e;\n  --sidebar-text: #e0e0e0;\n  --accent-primary: #e94560;\n  --type-name-color: #e94560;\n  --signature-color: #e94560;\n  --link-color: #0f3460;\n}\n```\n\nAvailable CSS variables cover sidebar colors, main content colors,\ncode/signature styling, syntax highlighting, and more. See\n`Commands::Docs::CSS_VARIABLES` for the full list.\n\n### AI Assistant Buttons\n\nEach generated page includes buttons to discuss the API with:\n- **Claude** (claude.ai)\n- **ChatGPT** (chatgpt.com)\n- **Gemini** (gemini.google.com)\n- **View as Markdown** (opens the parallel `.md` file)\n\nThe buttons extract page content and construct a prompt that\nincludes the type name, project name, and documentation.\n\n### Markdown Files\n\nParallel `.md` files are generated for every HTML page, making\nthe documentation easily consumable by AI coding assistants,\nCLI tools, and any system that prefers plain text.\n\n`shards docs` also emits:\n- `llms.txt` — concise machine-oriented index of the generated docs\n- `llms-full.txt` — concatenated markdown export of the docs set\n- `llms.json` — manifest of markdown and agent resources\n\nIf the project contains `.claude/` files or `.mcp.json`, they are copied\ninto `agent-files/` inside the docs output with HTML/JSON/Markdown indexes\nso the published docs site can distribute them directly.\n\nSee `Commands::Docs`.","summary":"<h2><a id=\"documentation-generation-and-theming\" class=\"anchor\" href=\"#documentation-generation-and-theming\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>Documentation Generation and Theming</h2>"},{"html_id":"Ashard/Shards/Docs/MCPDistribution","path":"Shards/Docs/MCPDistribution.html","kind":"module","full_name":"Shards::Docs::MCPDistribution","name":"MCPDistribution","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":158,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L158"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## MCP Server Distribution\n\nShards that ship `.mcp.json` can distribute MCP (Model Context Protocol)\nserver configurations to consuming projects.\n\n### How it works\n\nWhen a dependency contains `.mcp.json`, the `AIDocsInstaller`:\n\n1. Parses the JSON and extracts `mcpServers` entries\n2. Namespaces server names as `<shard>/<server_name>`\n3. Rewrites relative command/args paths to `lib/<shard>/...`\n4. Merges into `.mcp-shards.json` at the project root\n\nThe user's `.mcp.json` is never modified automatically. To merge\nshard servers into the user's config:\n\n```\nshards ai - docs merge - mcp\n```\n\n### Example .mcp.json in a shard\n\n```json\n{\n  \"mcpServers\": {\n    \"db-explorer\": {\n      \"command\": \"./bin/mcp-server\",\n      \"args\": [\"--mode\", \"readonly\"]\n    }\n  }\n}\n```\n\nAfter installation, this becomes `<shard>/db-explorer` in `.mcp-shards.json`\nwith the command rewritten to `lib/<shard>/bin/mcp-server`.\n\nSee `AIDocsInstaller#install_mcp_config`, `Commands::AIDocs`.","summary":"<h2><a id=\"mcp-server-distribution\" class=\"anchor\" href=\"#mcp-server-distribution\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>MCP Server Distribution</h2>"},{"html_id":"Ashard/Shards/Docs/MCPLifecycle","path":"Shards/Docs/MCPLifecycle.html","kind":"module","full_name":"Shards::Docs::MCPLifecycle","name":"MCPLifecycle","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":198,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L198"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## MCP Server Lifecycle Management\n\nThe `shards mcp` command manages the runtime lifecycle of MCP servers\ndistributed via `.mcp-shards.json`. This completes the pipeline from\ndistribution (handled by `shards install`) to execution.\n\n### Commands\n\n```\nshards mcp                         # Show server status (default)\nshards mcp start [server_name]     # Start all or one server\nshards mcp stop [server_name]      # Stop all or one server\nshards mcp restart [server_name]   # Restart all or one server\nshards mcp logs <name> [--no-follow] [--lines=N]\n```\n\n### Runtime state\n\nAll managed state lives in `.shards/mcp/`:\n- `servers.json`: PID, port, timestamps per server\n- `<name>.log`: per-server stdout/stderr logs\n- `bin/`: cached builds for `crystal_main` servers\n\n### Process management\n\nServers are spawned via `Process.new` (non-blocking) with output\nredirected to log files. PID tracking uses `LibC.kill(pid, 0)`.\nShutdown sends SIGTERM, waits 5 seconds, then SIGKILL if needed.\nStale PIDs are detected and cleaned on every status check.\n\n### Name resolution\n\nServer names use the existing namespacing from `.mcp-shards.json`\n(e.g., `my_shard/explorer`). Partial name matching is supported:\n`explorer` finds `my_shard/explorer` if unambiguous.\n\nSee `MCPManager`, `Commands::MCP`.","summary":"<h2><a id=\"mcp-server-lifecycle-management\" class=\"anchor\" href=\"#mcp-server-lifecycle-management\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>MCP Server Lifecycle Management</h2>"},{"html_id":"Ashard/Shards/Docs/PostinstallScripts","path":"Shards/Docs/PostinstallScripts.html","kind":"module","full_name":"Shards::Docs::PostinstallScripts","name":"PostinstallScripts","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":117,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L117"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## Postinstall Scripts\n\nShards supports postinstall scripts defined in `shard.yml`:\n\n```yaml\nscripts:\n  postinstall: make ext\n```\n\n### Version-aware execution\n\nPostinstall scripts use `PostinstallInfo` for tracking:\n\n- **First install**: the script runs automatically, and its hash is recorded\n- **Subsequent installs** (same script): skipped silently\n- **Script changed**: a warning is emitted, the user must run\n  `shards run-script <shard>` explicitly\n\nThis prevents unexpected re-execution of potentially destructive scripts\nwhile still notifying users when scripts change.\n\n### Manual execution\n\n```\nshards run - script          # run all pending scripts\nshards run - script my_shard # run for specific shard\n```\n\nSee `PostinstallInfo`, `Commands::RunScript`, `Package#postinstall`.","summary":"<h2><a id=\"postinstall-scripts\" class=\"anchor\" href=\"#postinstall-scripts\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>Postinstall Scripts</h2>"},{"html_id":"Ashard/Shards/Docs/PublishingGuide","path":"Shards/Docs/PublishingGuide.html","kind":"module","full_name":"Shards::Docs::PublishingGuide","name":"PublishingGuide","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":385,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L385"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## Publishing AI Docs for Your Shard\n\n### Recommended: ship skills\n\nCreate `.claude/skills/` in your shard repository:\n\n```\nyour_shard/\n  .claude/\n    skills/\n      getting-started/\n        SKILL.md\n      api-reference/\n        SKILL.md\n  src/\n  shard.yml\n```\n\nEach `SKILL.md` needs 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\n### Simple: ship CLAUDE.md\n\nFor basic documentation, add a `CLAUDE.md` at your shard root.\nIt is auto-converted to a passive skill during installation.\n\n### Optional: customize with shard.yml\n\n```yaml\nai_docs:\n  include:\n    - docs/claude/advanced_guide.md\n  exclude:\n    - .claude/skills/internal_dev_tool/\n```\n\n### Ship MCP servers\n\nAdd `.mcp.json` to your shard root with standard MCP configuration.\nRelative paths in `command` and `args` are automatically rewritten.\n\nSee `AIDocsInstaller`, `Docs::AIDocumentation`, `Docs::MCPDistribution`.","summary":"<h2><a id=\"publishing-ai-docs-for-your-shard\" class=\"anchor\" href=\"#publishing-ai-docs-for-your-shard\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>Publishing AI Docs for Your Shard</h2>"},{"html_id":"Ashard/Shards/Docs/SBOMGeneration","path":"Shards/Docs/SBOMGeneration.html","kind":"module","full_name":"Shards::Docs::SBOMGeneration","name":"SBOMGeneration","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":481,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L481"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## Software Bill of Materials (SBOM) Generation\n\nThe `shards sbom` command generates a machine-readable inventory of all\ndependencies in SPDX 2.3 or CycloneDX 1.6 JSON format for compliance\nauditing (SOC 2, ISO 27001).\n\n### Usage\n\n```\nshards sbom                          # SPDX 2.3 JSON (default)\nshards sbom --format=cyclonedx       # CycloneDX 1.6 JSON\nshards sbom --output=custom.json     # Custom output path\nshards sbom --include-dev            # Include dev dependencies\n```\n\n### Data sources\n\nThe command reads `shard.lock` for locked versions, then loads each\ndependency's `shard.yml` from `lib/<name>/` for metadata (license,\nauthors, description). Package URLs (purls) are derived from resolver\nsource URLs, with GitHub/GitLab/Bitbucket sources mapped to their\nrespective purl types.\n\nSee `Commands::SBOM`.","summary":"<h2><a id=\"software-bill-of-materials-sbom-generation\" class=\"anchor\" href=\"#software-bill-of-materials-sbom-generation\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>Software Bill of Materials (SBOM) Generation</h2>"},{"html_id":"Ashard/Shards/Docs/ShardYmlFormat","path":"Shards/Docs/ShardYmlFormat.html","kind":"module","full_name":"Shards::Docs::ShardYmlFormat","name":"ShardYmlFormat","abstract":false,"locations":[{"filename":"src/docs.cr","line_number":331,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/docs.cr#L331"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Docs","kind":"module","full_name":"Shards::Docs","name":"Docs"},"doc":"## shard.yml Format\n\n### Required fields\n\n```yaml\nname: my_shard\nversion: 1.0.0\n```\n\n### Dependencies\n\n```yaml\ndependencies:\n  kemal:\n    github: kemalcr/kemal\n    version: ~> 1.0\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: <url>` | Any git URL |\n| `hg: <url>` | Mercurial |\n| `fossil: <url>` | Fossil |\n| `path: <path>` | Local path |\n\n### Version constraints\n\n| Pattern | Meaning |\n|---|---|\n| `*` | Any version |\n| `1.0.0` | Exact version |\n| `>= 1.0.0` | Minimum version |\n| `~> 1.0` | >= 1.0.0, < 2.0.0 |\n| `~> 1.0.3` | >= 1.0.3, < 1.1.0 |\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```\n\n### AI documentation (optional)\n\n```yaml\nai_docs:\n  include:\n    - docs/claude/custom_guide.md\n  exclude:\n    - .claude/skills/internal_dev_tool/\n```\n\nSee `Spec`, `Spec::AIDocs`, `Dependency`.","summary":"<h2><a id=\"shard.yml-format\" class=\"anchor\" href=\"#shard.yml-format\">  <svg class=\"octicon-link\" aria-hidden=\"true\">\n    <use href=\"#octicon-link\"/>\n  </svg>\n</a>shard.yml Format</h2>"}]},{"html_id":"Ashard/Shards/Error","path":"Shards/Error.html","kind":"class","full_name":"Shards::Error","name":"Error","abstract":false,"superclass":{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},"ancestors":[{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/errors.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/ChecksumMismatch","kind":"class","full_name":"Shards::ChecksumMismatch","name":"ChecksumMismatch"},{"html_id":"Ashard/Shards/Conflict","kind":"class","full_name":"Shards::Conflict","name":"Conflict"},{"html_id":"Ashard/Shards/InvalidLock","kind":"class","full_name":"Shards::InvalidLock","name":"InvalidLock"},{"html_id":"Ashard/Shards/LockConflict","kind":"class","full_name":"Shards::LockConflict","name":"LockConflict"},{"html_id":"Ashard/Shards/ParseError","kind":"class","full_name":"Shards::ParseError","name":"ParseError"},{"html_id":"Ashard/Shards/Script/Error","kind":"class","full_name":"Shards::Script::Error","name":"Error"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"}},{"html_id":"Ashard/Shards/FossilBranchRef","path":"Shards/FossilBranchRef.html","kind":"struct","full_name":"Shards::FossilBranchRef","name":"FossilBranchRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},"ancestors":[{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/fossil.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L14"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(branch:String)-class-method","name":"new","abstract":false,"args":[{"name":"branch","external_name":"branch","restriction":"String"}],"args_string":"(branch : String)","args_html":"(branch : String)","location":{"filename":"src/resolvers/fossil.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L15"},"def":{"name":"new","args":[{"name":"branch","external_name":"branch","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(branch)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"to_fossil_ref:String-instance-method","name":"to_fossil_ref","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L18"},"def":{"name":"to_fossil_ref","visibility":"Public","body":"@branch"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/fossil.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L22"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"branch \") << @branch"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/fossil.cr","line_number":26,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L26"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"branch\")\nyaml.scalar(@branch)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/FossilCommitRef","path":"Shards/FossilCommitRef.html","kind":"struct","full_name":"Shards::FossilCommitRef","name":"FossilCommitRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},"ancestors":[{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/fossil.cr","line_number":50,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L50"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(commit:String)-class-method","name":"new","abstract":false,"args":[{"name":"commit","external_name":"commit","restriction":"String"}],"args_string":"(commit : String)","args_html":"(commit : String)","location":{"filename":"src/resolvers/fossil.cr","line_number":53,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L53"},"def":{"name":"new","args":[{"name":"commit","external_name":"commit","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(commit)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"=~(other:FossilCommitRef)-instance-method","name":"=~","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"FossilCommitRef"}],"args_string":"(other : FossilCommitRef)","args_html":"(other : <a href=\"../Shards/FossilCommitRef.html\">FossilCommitRef</a>)","location":{"filename":"src/resolvers/fossil.cr","line_number":56,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L56"},"def":{"name":"=~","args":[{"name":"other","external_name":"other","restriction":"FossilCommitRef"}],"visibility":"Public","body":"(commit.starts_with?(other.commit)) || (other.commit.starts_with?(commit))"},"external_var":false},{"html_id":"commit:String-instance-method","name":"commit","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":51,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L51"},"def":{"name":"commit","return_type":"String","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"full_info-instance-method","name":"full_info","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":68,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L68"},"def":{"name":"full_info","visibility":"Public","body":"\"commit #{@commit}\""},"external_var":false},{"html_id":"to_fossil_ref:String-instance-method","name":"to_fossil_ref","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":60,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L60"},"def":{"name":"to_fossil_ref","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/fossil.cr","line_number":64,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L64"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"commit \") << @commit[0...7]"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/fossil.cr","line_number":72,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L72"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"commit\")\nyaml.scalar(@commit)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/FossilRef","path":"Shards/FossilRef.html","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef","abstract":true,"superclass":{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},"ancestors":[{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/fossil.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/FossilBranchRef","kind":"struct","full_name":"Shards::FossilBranchRef","name":"FossilBranchRef"},{"html_id":"Ashard/Shards/FossilCommitRef","kind":"struct","full_name":"Shards::FossilCommitRef","name":"FossilCommitRef"},{"html_id":"Ashard/Shards/FossilTagRef","kind":"struct","full_name":"Shards::FossilTagRef","name":"FossilTagRef"},{"html_id":"Ashard/Shards/FossilTrunkRef","kind":"struct","full_name":"Shards::FossilTrunkRef","name":"FossilTrunkRef"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"instance_methods":[{"html_id":"full_info-instance-method","name":"full_info","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L9"},"def":{"name":"full_info","visibility":"Public","body":"to_s"},"external_var":false}]},{"html_id":"Ashard/Shards/FossilResolver","path":"Shards/FossilResolver.html","kind":"class","full_name":"Shards::FossilResolver","name":"FossilResolver","abstract":false,"superclass":{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},"ancestors":[{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/fossil.cr","line_number":92,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L92"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"key-class-method","name":"key","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":102,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L102"},"def":{"name":"key","visibility":"Public","body":"\"fossil\""},"external_var":false},{"html_id":"normalize_key_source(key:String,source:String):Tuple(String,String)-class-method","name":"normalize_key_source","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(key : String, source : String) : Tuple(String, String)","args_html":"(key : String, source : String) : Tuple(String, String)","location":{"filename":"src/resolvers/fossil.cr","line_number":106,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L106"},"def":{"name":"normalize_key_source","args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"return_type":"::Tuple(String, String)","visibility":"Public","body":"case key\nwhen \"fossil\"\n  {\"fossil\", source}\nelse\n  raise(\"Unknown resolver #{key}\")\nend"},"external_var":false}],"instance_methods":[{"html_id":"available_releases:Array(Version)-instance-method","name":"available_releases","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":181,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L181"},"def":{"name":"available_releases","return_type":"Array(Version)","visibility":"Public","body":"update_local_cache\nversions_from_tags\n"},"external_var":false},{"html_id":"commit_sha1_at(ref:FossilRef)-instance-method","name":"commit_sha1_at","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"FossilRef"}],"args_string":"(ref : FossilRef)","args_html":"(ref : <a href=\"../Shards/FossilRef.html\">FossilRef</a>)","location":{"filename":"src/resolvers/fossil.cr","line_number":241,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L241"},"def":{"name":"commit_sha1_at","args":[{"name":"ref","external_name":"ref","restriction":"FossilRef"}],"visibility":"Public","body":"if FossilResolver.fossil_version_maj <= 2 &&\nFossilResolver.fossil_version_min < 14\n  shortShas = capture(\"fossil timeline #{Process.quote(ref.to_fossil_ref)} -t ci -W 0 -n 1 -R #{Process.quote(local_fossil_file)}\")\n\n\n  retLines = shortShas.lines.map do |line|\n    ((/^.+ \\[(.+)\\].*/).match(line)).try(&.[](1))\n  end\n\n\n  retLines.reject! do |__arg2| __arg2.nil? end\n  if retLines.empty?\n    return \"\"\n  end\n\n\n\n  whatis = capture(\"fossil whatis #{retLines[0]} -R #{Process.quote(local_fossil_file)}\")\n  ((/artifact:\\s+(.+)/).match(whatis)).try(&.[](1)) || \"\"\nelse\n  (capture(\"fossil timeline #{Process.quote(ref.to_fossil_ref)} -t ci -F %H -n 1 -R #{Process.quote(local_fossil_file)}\")).lines[0]\nend"},"external_var":false},{"html_id":"fossil_url-instance-method","name":"fossil_url","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":294,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L294"},"def":{"name":"fossil_url","visibility":"Public","body":"source.strip"},"external_var":false},{"html_id":"install_sources(version:Version,install_path:String)-instance-method","name":"install_sources","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"args_string":"(version : Version, install_path : String)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>, install_path : String)","location":{"filename":"src/resolvers/fossil.cr","line_number":221,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L221"},"def":{"name":"install_sources","args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"visibility":"Public","body":"update_local_cache\nref = fossil_ref(version)\n\nif File.exists?(install_path)\n  FileUtils.rm_r(install_path)\nend\nDir.mkdir_p(install_path)\nLog.debug do \"Local path: #{local_path}\" end\nLog.debug do \"Install path: #{install_path}\" end\n\n\n\nif FossilResolver.fossil_version_maj <= 2 &&\nFossilResolver.fossil_version_min < 12\n  Log.debug do \"Opening Fossil repo #{local_fossil_file} in directory #{install_path}\" end\n  run(\"fossil open #{local_fossil_file} #{Process.quote(ref.to_fossil_ref)} --nested\", install_path)\nelse\n  run(\"fossil open #{local_fossil_file} #{Process.quote(ref.to_fossil_ref)}  --nested --workdir #{install_path}\")\nend\n"},"external_var":false},{"html_id":"latest_version_for_ref(ref:FossilRef|Nil):Version-instance-method","name":"latest_version_for_ref","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"FossilRef | ::Nil"}],"args_string":"(ref : FossilRef | Nil) : Version","args_html":"(ref : <a href=\"../Shards/FossilRef.html\">FossilRef</a> | Nil) : <a href=\"../Shards/Version.html\">Version</a>","location":{"filename":"src/resolvers/fossil.cr","line_number":186,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L186"},"def":{"name":"latest_version_for_ref","args":[{"name":"ref","external_name":"ref","restriction":"FossilRef | ::Nil"}],"return_type":"Version","visibility":"Public","body":"update_local_cache\nref || (ref = FossilTrunkRef.new)\nbegin\n  commit = commit_sha1_at(ref)\nrescue Error\n  raise(Error.new(\"Could not find #{ref.full_info} for shard #{name.inspect} in the repository #{source}\"))\nend\n\nif spec = spec_at_ref(ref, commit)\n  Version.new(\"#{spec.version.value}+fossil.commit.#{commit}\")\nelse\n  raise(Error.new(\"No #{SPEC_FILENAME} was found for shard #{name.inspect} at commit #{commit}\"))\nend\n"},"external_var":false},{"html_id":"local_fossil_file-instance-method","name":"local_fossil_file","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":290,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L290"},"def":{"name":"local_fossil_file","visibility":"Public","body":"@local_fossil_file || (@local_fossil_file = (Path[local_path].join(\"#{name}.fossil\")).normalize.to_s)"},"external_var":false},{"html_id":"local_path-instance-method","name":"local_path","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":271,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L271"},"def":{"name":"local_path","visibility":"Public","body":"@local_path || (\n  @local_path = (begin\n    uri = parse_uri(fossil_url)\n\n    path = uri.path\n    path = Path[path]\n\n    if (anchor = path.anchor)\n      path = Path[path.drive.to_s.rchop(\":\"), path.relative_to(anchor)]\n    end\n\n    if host = uri.host\n      File.join(Shards.cache_path, host)\n    else\n      File.join(Shards.cache_path, path)\n    end\n  end)\n)"},"external_var":false},{"html_id":"matches_ref?(ref:FossilRef,version:Version)-instance-method","name":"matches_ref?","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"FossilRef"},{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(ref : FossilRef, version : Version)","args_html":"(ref : <a href=\"../Shards/FossilRef.html\">FossilRef</a>, version : <a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/resolvers/fossil.cr","line_number":202,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L202"},"def":{"name":"matches_ref?","args":[{"name":"ref","external_name":"ref","restriction":"FossilRef"},{"name":"version","external_name":"version","restriction":"Version"}],"visibility":"Public","body":"case ref\nwhen FossilCommitRef\n  ref =~ (fossil_ref(version))\nwhen FossilBranchRef, FossilTrunkRef\n  version.has_metadata?\nelse\n  true\nend"},"external_var":false},{"html_id":"parse_requirement(params:Hash(String,String)):Requirement-instance-method","name":"parse_requirement","abstract":false,"args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"args_string":"(params : Hash(String, String)) : Requirement","args_html":"(params : Hash(String, String)) : <a href=\"../Shards/Requirement.html\">Requirement</a>","location":{"filename":"src/resolvers/fossil.cr","line_number":298,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L298"},"def":{"name":"parse_requirement","args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"return_type":"Requirement","visibility":"Public","body":"params.each do |key, value|\n  case key\n  when \"branch\"\n    return FossilBranchRef.new(value)\n  when \"tag\"\n    return FossilTagRef.new(value)\n  when \"commit\"\n    return FossilCommitRef.new(value)\n  else\n  end\nend\n\nsuper(params)\n"},"external_var":false},{"html_id":"read_spec(version:Version):String|Nil-instance-method","name":"read_spec","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String | Nil","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String | Nil","location":{"filename":"src/resolvers/fossil.cr","line_number":149,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L149"},"def":{"name":"read_spec","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String | ::Nil","visibility":"Public","body":"update_local_cache\nref = fossil_ref(version)\n\nif file_exists?(ref, SPEC_FILENAME)\n  capture(\"fossil cat -R #{Process.quote(local_fossil_file)} #{Process.quote(SPEC_FILENAME)} -r #{Process.quote(ref.to_fossil_ref)}\")\nelse\n  Log.debug do \"Missing \\\"#{SPEC_FILENAME}\\\" for #{name.inspect} at #{ref}\" end\n  nil\nend\n"},"external_var":false},{"html_id":"report_version(version:Version):String-instance-method","name":"report_version","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String","location":{"filename":"src/resolvers/fossil.cr","line_number":495,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L495"},"def":{"name":"report_version","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String","visibility":"Public","body":"fossil_version = parse_fossil_version(version)\nif commit = fossil_version.commit\n  \"#{fossil_version.value} at #{commit[0...7]}\"\nelse\n  version.value\nend\n"},"external_var":false},{"html_id":"update_local_cache-instance-method","name":"update_local_cache","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":336,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L336"},"def":{"name":"update_local_cache","visibility":"Public","body":"if cloned_repository? && origin_changed?\n  delete_repository\n  @updated_cache = false\nend\n\nif Shards.local? || @updated_cache\n  return\nend\nLog.info do \"Fetching #{fossil_url}\" end\n\nif cloned_repository?\n  if valid_repository?\n    fetch_repository\n  else\n    delete_repository\n    mirror_repository\n  end\nelse\n  mirror_repository\nend\n\n@updated_cache = true\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/FossilResolver/FossilVersion","path":"Shards/FossilResolver/FossilVersion.html","kind":"struct","full_name":"Shards::FossilResolver::FossilVersion","name":"FossilVersion","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/fossil.cr","line_number":314,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L314"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/FossilResolver","kind":"class","full_name":"Shards::FossilResolver","name":"FossilResolver"},"constructors":[{"html_id":"new(value:String,commit:String|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"commit","default_value":"nil","external_name":"commit","restriction":"String | ::Nil"}],"args_string":"(value : String, commit : String | Nil = nil)","args_html":"(value : String, commit : String | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/resolvers/fossil.cr","line_number":314,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L314"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"commit","default_value":"nil","external_name":"commit","restriction":"String | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, commit)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":314,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L314"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@value.clone, @commit.clone)"},"external_var":false},{"html_id":"commit:String|Nil-instance-method","name":"commit","abstract":false,"def":{"name":"commit","return_type":"String | ::Nil","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"copy_with(value_value=@value,commit_commit=@commit)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_value","default_value":"@value","external_name":"value","restriction":""},{"name":"_commit","default_value":"@commit","external_name":"commit","restriction":""}],"args_string":"(value _value = @value, commit _commit = @commit)","args_html":"(value _value = @value, commit _commit = @commit)","location":{"filename":"src/resolvers/fossil.cr","line_number":314,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L314"},"def":{"name":"copy_with","args":[{"name":"_value","default_value":"@value","external_name":"value","restriction":""},{"name":"_commit","default_value":"@commit","external_name":"commit","restriction":""}],"visibility":"Public","body":"self.class.new(_value, _commit)"},"external_var":false},{"html_id":"value:String-instance-method","name":"value","abstract":false,"def":{"name":"value","return_type":"String","visibility":"Public","body":"@value"},"external_var":false}]}]},{"html_id":"Ashard/Shards/FossilTagRef","path":"Shards/FossilTagRef.html","kind":"struct","full_name":"Shards::FossilTagRef","name":"FossilTagRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},"ancestors":[{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/fossil.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L32"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(tag:String)-class-method","name":"new","abstract":false,"args":[{"name":"tag","external_name":"tag","restriction":"String"}],"args_string":"(tag : String)","args_html":"(tag : String)","location":{"filename":"src/resolvers/fossil.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L33"},"def":{"name":"new","args":[{"name":"tag","external_name":"tag","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(tag)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"to_fossil_ref:String-instance-method","name":"to_fossil_ref","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L36"},"def":{"name":"to_fossil_ref","visibility":"Public","body":"@tag"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/fossil.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L40"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"tag \") << @tag"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/fossil.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L44"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"tag\")\nyaml.scalar(@tag)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/FossilTrunkRef","path":"Shards/FossilTrunkRef.html","kind":"struct","full_name":"Shards::FossilTrunkRef","name":"FossilTrunkRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},"ancestors":[{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/fossil.cr","line_number":78,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L78"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"instance_methods":[{"html_id":"to_fossil_ref-instance-method","name":"to_fossil_ref","abstract":false,"location":{"filename":"src/resolvers/fossil.cr","line_number":79,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L79"},"def":{"name":"to_fossil_ref","visibility":"Public","body":"\"trunk\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/fossil.cr","line_number":83,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L83"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"io << \"trunk\""},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/fossil.cr","line_number":87,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/fossil.cr#L87"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"raise(NotImplementedError.new(\"FossilTrunkRef is for internal use only\"))"},"external_var":false}]},{"html_id":"Ashard/Shards/GitBranchRef","path":"Shards/GitBranchRef.html","kind":"struct","full_name":"Shards::GitBranchRef","name":"GitBranchRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},"ancestors":[{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/git.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L14"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(branch:String)-class-method","name":"new","abstract":false,"args":[{"name":"branch","external_name":"branch","restriction":"String"}],"args_string":"(branch : String)","args_html":"(branch : String)","location":{"filename":"src/resolvers/git.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L15"},"def":{"name":"new","args":[{"name":"branch","external_name":"branch","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(branch)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"to_git_ref-instance-method","name":"to_git_ref","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L18"},"def":{"name":"to_git_ref","visibility":"Public","body":"\"refs/heads/#{@branch}\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/git.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L22"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"branch \") << @branch"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/git.cr","line_number":26,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L26"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"branch\")\nyaml.scalar(@branch)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/GitCommitRef","path":"Shards/GitCommitRef.html","kind":"struct","full_name":"Shards::GitCommitRef","name":"GitCommitRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},"ancestors":[{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/git.cr","line_number":50,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L50"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(commit:String)-class-method","name":"new","abstract":false,"args":[{"name":"commit","external_name":"commit","restriction":"String"}],"args_string":"(commit : String)","args_html":"(commit : String)","location":{"filename":"src/resolvers/git.cr","line_number":53,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L53"},"def":{"name":"new","args":[{"name":"commit","external_name":"commit","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(commit)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"=~(other:GitCommitRef)-instance-method","name":"=~","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"GitCommitRef"}],"args_string":"(other : GitCommitRef)","args_html":"(other : <a href=\"../Shards/GitCommitRef.html\">GitCommitRef</a>)","location":{"filename":"src/resolvers/git.cr","line_number":56,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L56"},"def":{"name":"=~","args":[{"name":"other","external_name":"other","restriction":"GitCommitRef"}],"visibility":"Public","body":"(commit.starts_with?(other.commit)) || (other.commit.starts_with?(commit))"},"external_var":false},{"html_id":"commit:String-instance-method","name":"commit","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":51,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L51"},"def":{"name":"commit","return_type":"String","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"full_info-instance-method","name":"full_info","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":68,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L68"},"def":{"name":"full_info","visibility":"Public","body":"\"commit #{@commit}\""},"external_var":false},{"html_id":"to_git_ref:String-instance-method","name":"to_git_ref","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":60,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L60"},"def":{"name":"to_git_ref","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/git.cr","line_number":64,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L64"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"commit \") << @commit[0...7]"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/git.cr","line_number":72,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L72"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"commit\")\nyaml.scalar(@commit)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/GitHeadRef","path":"Shards/GitHeadRef.html","kind":"struct","full_name":"Shards::GitHeadRef","name":"GitHeadRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},"ancestors":[{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/git.cr","line_number":78,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L78"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"instance_methods":[{"html_id":"to_git_ref-instance-method","name":"to_git_ref","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":79,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L79"},"def":{"name":"to_git_ref","visibility":"Public","body":"\"HEAD\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/git.cr","line_number":83,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L83"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"io << \"HEAD\""},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/git.cr","line_number":87,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L87"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"raise(NotImplementedError.new(\"GitHeadRef is for internal use only\"))"},"external_var":false}]},{"html_id":"Ashard/Shards/GitRef","path":"Shards/GitRef.html","kind":"struct","full_name":"Shards::GitRef","name":"GitRef","abstract":true,"superclass":{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},"ancestors":[{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/git.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/GitBranchRef","kind":"struct","full_name":"Shards::GitBranchRef","name":"GitBranchRef"},{"html_id":"Ashard/Shards/GitCommitRef","kind":"struct","full_name":"Shards::GitCommitRef","name":"GitCommitRef"},{"html_id":"Ashard/Shards/GitHeadRef","kind":"struct","full_name":"Shards::GitHeadRef","name":"GitHeadRef"},{"html_id":"Ashard/Shards/GitTagRef","kind":"struct","full_name":"Shards::GitTagRef","name":"GitTagRef"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"instance_methods":[{"html_id":"full_info-instance-method","name":"full_info","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L9"},"def":{"name":"full_info","visibility":"Public","body":"to_s"},"external_var":false}]},{"html_id":"Ashard/Shards/GitResolver","path":"Shards/GitResolver.html","kind":"class","full_name":"Shards::GitResolver","name":"GitResolver","abstract":false,"superclass":{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},"ancestors":[{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/git.cr","line_number":92,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L92"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"key-class-method","name":"key","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":99,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L99"},"def":{"name":"key","visibility":"Public","body":"\"git\""},"external_var":false},{"html_id":"normalize_key_source(key:String,source:String):Tuple(String,String)-class-method","name":"normalize_key_source","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(key : String, source : String) : Tuple(String, String)","args_html":"(key : String, source : String) : Tuple(String, String)","location":{"filename":"src/resolvers/git.cr","line_number":114,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L114"},"def":{"name":"normalize_key_source","args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"return_type":"::Tuple(String, String)","visibility":"Public","body":"case key\nwhen \"git\"\n  uri = URI.parse(source)\n  downcased_host = uri.host.try(&.downcase)\n  scheme = uri.scheme.try(&.downcase)\n  if ((scheme.in?(\"git\", \"http\", \"https\")) && downcased_host) && (downcased_host.in?(KNOWN_PROVIDERS))\n    uri.scheme = \"https\"\n    downcased_path = uri.path.downcase\n    uri.path = downcased_path.ends_with?(\".git\") ? downcased_path : \"#{downcased_path}.git\"\n    uri.host = downcased_host.lchop(\"www.\")\n    {\"git\", uri.to_s}\n  else\n    {\"git\", source}\n  end\nwhen \"github\", \"bitbucket\", \"gitlab\"\n  {\"git\", \"https://#{key}.com/#{source.downcase}.git\"}\nwhen \"codeberg\"\n  {\"git\", \"https://#{key}.org/#{source.downcase}.git\"}\nelse\n  raise(\"Unknown resolver #{key}\")\nend"},"external_var":false}],"instance_methods":[{"html_id":"available_releases:Array(Version)-instance-method","name":"available_releases","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":186,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L186"},"def":{"name":"available_releases","return_type":"Array(Version)","visibility":"Public","body":"update_local_cache\nversions_from_tags\n"},"external_var":false},{"html_id":"commit_sha1_at(ref:GitRef)-instance-method","name":"commit_sha1_at","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"GitRef"}],"args_string":"(ref : GitRef)","args_html":"(ref : <a href=\"../Shards/GitRef.html\">GitRef</a>)","location":{"filename":"src/resolvers/git.cr","line_number":231,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L231"},"def":{"name":"commit_sha1_at","args":[{"name":"ref","external_name":"ref","restriction":"GitRef"}],"visibility":"Public","body":"(capture(\"git log -n 1 --pretty=%H #{Process.quote(ref.to_git_ref)}\")).strip"},"external_var":false},{"html_id":"git_url-instance-method","name":"git_url","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":255,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L255"},"def":{"name":"git_url","visibility":"Public","body":"source.strip"},"external_var":false},{"html_id":"install_sources(version:Version,install_path:String)-instance-method","name":"install_sources","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"args_string":"(version : Version, install_path : String)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>, install_path : String)","location":{"filename":"src/resolvers/git.cr","line_number":223,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L223"},"def":{"name":"install_sources","args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"visibility":"Public","body":"update_local_cache\nref = git_ref(version)\n\nDir.mkdir_p(install_path)\nrun(\"git --work-tree=#{Process.quote(install_path)} checkout #{Process.quote(ref.to_git_ref)} -- .\")\n"},"external_var":false},{"html_id":"latest_version_for_ref(ref:GitRef|Nil):Version-instance-method","name":"latest_version_for_ref","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"GitRef | ::Nil"}],"args_string":"(ref : GitRef | Nil) : Version","args_html":"(ref : <a href=\"../Shards/GitRef.html\">GitRef</a> | Nil) : <a href=\"../Shards/Version.html\">Version</a>","location":{"filename":"src/resolvers/git.cr","line_number":191,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L191"},"def":{"name":"latest_version_for_ref","args":[{"name":"ref","external_name":"ref","restriction":"GitRef | ::Nil"}],"return_type":"Version","visibility":"Public","body":"update_local_cache\nref || (ref = GitHeadRef.new)\nbegin\n  commit = commit_sha1_at(ref)\nrescue Error\n  raise(Error.new(\"Could not find #{ref.full_info} for shard #{name.inspect} in the repository #{source}\"))\nend\n\nspec = spec_at_ref(ref, commit)\nVersion.new(\"#{spec.version.value}+git.commit.#{commit}\")\n"},"external_var":false},{"html_id":"local_path-instance-method","name":"local_path","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":235,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L235"},"def":{"name":"local_path","visibility":"Public","body":"@local_path || (\n  @local_path = (begin\n    uri = parse_uri(git_url)\n\n    path = uri.path\n    if path.ends_with?(\".git\")\n    else\n      path = path + \".git\"\n    end\n    path = Path[path]\n\n    if (anchor = path.anchor)\n      path = Path[path.drive.to_s.rchop(\":\"), path.relative_to(anchor)]\n    end\n\n    if host = uri.host\n      File.join(Shards.cache_path, host, path)\n    else\n      File.join(Shards.cache_path, path)\n    end\n  end)\n)"},"external_var":false},{"html_id":"matches_ref?(ref:GitRef,version:Version)-instance-method","name":"matches_ref?","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"GitRef"},{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(ref : GitRef, version : Version)","args_html":"(ref : <a href=\"../Shards/GitRef.html\">GitRef</a>, version : <a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/resolvers/git.cr","line_number":204,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L204"},"def":{"name":"matches_ref?","args":[{"name":"ref","external_name":"ref","restriction":"GitRef"},{"name":"version","external_name":"version","restriction":"Version"}],"visibility":"Public","body":"case ref\nwhen GitCommitRef\n  ref =~ (git_ref(version))\nwhen GitBranchRef, GitHeadRef\n  version.has_metadata?\nelse\n  true\nend"},"external_var":false},{"html_id":"parse_requirement(params:Hash(String,String)):Requirement-instance-method","name":"parse_requirement","abstract":false,"args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"args_string":"(params : Hash(String, String)) : Requirement","args_html":"(params : Hash(String, String)) : <a href=\"../Shards/Requirement.html\">Requirement</a>","location":{"filename":"src/resolvers/git.cr","line_number":259,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L259"},"def":{"name":"parse_requirement","args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"return_type":"Requirement","visibility":"Public","body":"params.each do |key, value|\n  case key\n  when \"branch\"\n    return GitBranchRef.new(value)\n  when \"tag\"\n    return GitTagRef.new(value)\n  when \"commit\"\n    return GitCommitRef.new(value)\n  else\n  end\nend\n\nsuper(params)\n"},"external_var":false},{"html_id":"read_spec(version:Version):String|Nil-instance-method","name":"read_spec","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String | Nil","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String | Nil","location":{"filename":"src/resolvers/git.cr","line_number":154,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L154"},"def":{"name":"read_spec","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String | ::Nil","visibility":"Public","body":"update_local_cache\nref = git_ref(version)\n\nif file_exists?(ref, SPEC_FILENAME)\n  capture(\"git show #{Process.quote(\"#{ref.to_git_ref}:#{SPEC_FILENAME}\")}\")\nelse\n  Log.debug do \"Missing \\\"#{SPEC_FILENAME}\\\" for #{name.inspect} at #{ref}\" end\n  nil\nend\n"},"external_var":false},{"html_id":"report_version(version:Version):String-instance-method","name":"report_version","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String","location":{"filename":"src/resolvers/git.cr","line_number":459,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L459"},"def":{"name":"report_version","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String","visibility":"Public","body":"git_version = parse_git_version(version)\nif commit = git_version.commit\n  \"#{git_version.value} at #{commit[0...7]}\"\nelse\n  version.value\nend\n"},"external_var":false},{"html_id":"update_local_cache-instance-method","name":"update_local_cache","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":297,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L297"},"def":{"name":"update_local_cache","visibility":"Public","body":"if cloned_repository? && origin_changed?\n  delete_repository\n  @updated_cache = false\nend\n\nif Shards.local? || @updated_cache\n  return\nend\nLog.info do \"Fetching #{git_url}\" end\n\nif cloned_repository?\n  if valid_repository?\n    fetch_repository\n  else\n    delete_repository\n    mirror_repository\n  end\nelse\n  mirror_repository\nend\n\n@updated_cache = true\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/GitResolver/GitVersion","path":"Shards/GitResolver/GitVersion.html","kind":"struct","full_name":"Shards::GitResolver::GitVersion","name":"GitVersion","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/git.cr","line_number":275,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L275"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/GitResolver","kind":"class","full_name":"Shards::GitResolver","name":"GitResolver"},"constructors":[{"html_id":"new(value:String,commit:String|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"commit","default_value":"nil","external_name":"commit","restriction":"String | ::Nil"}],"args_string":"(value : String, commit : String | Nil = nil)","args_html":"(value : String, commit : String | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/resolvers/git.cr","line_number":275,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L275"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"commit","default_value":"nil","external_name":"commit","restriction":"String | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, commit)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":275,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L275"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@value.clone, @commit.clone)"},"external_var":false},{"html_id":"commit:String|Nil-instance-method","name":"commit","abstract":false,"def":{"name":"commit","return_type":"String | ::Nil","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"copy_with(value_value=@value,commit_commit=@commit)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_value","default_value":"@value","external_name":"value","restriction":""},{"name":"_commit","default_value":"@commit","external_name":"commit","restriction":""}],"args_string":"(value _value = @value, commit _commit = @commit)","args_html":"(value _value = @value, commit _commit = @commit)","location":{"filename":"src/resolvers/git.cr","line_number":275,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L275"},"def":{"name":"copy_with","args":[{"name":"_value","default_value":"@value","external_name":"value","restriction":""},{"name":"_commit","default_value":"@commit","external_name":"commit","restriction":""}],"visibility":"Public","body":"self.class.new(_value, _commit)"},"external_var":false},{"html_id":"value:String-instance-method","name":"value","abstract":false,"def":{"name":"value","return_type":"String","visibility":"Public","body":"@value"},"external_var":false}]}]},{"html_id":"Ashard/Shards/GitTagRef","path":"Shards/GitTagRef.html","kind":"struct","full_name":"Shards::GitTagRef","name":"GitTagRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},"ancestors":[{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/git.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L32"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(tag:String)-class-method","name":"new","abstract":false,"args":[{"name":"tag","external_name":"tag","restriction":"String"}],"args_string":"(tag : String)","args_html":"(tag : String)","location":{"filename":"src/resolvers/git.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L33"},"def":{"name":"new","args":[{"name":"tag","external_name":"tag","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(tag)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"to_git_ref-instance-method","name":"to_git_ref","abstract":false,"location":{"filename":"src/resolvers/git.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L36"},"def":{"name":"to_git_ref","visibility":"Public","body":"\"refs/tags/#{@tag}\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/git.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L40"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"tag \") << @tag"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/git.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/git.cr#L44"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"tag\")\nyaml.scalar(@tag)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Helpers","path":"Shards/Helpers.html","kind":"module","full_name":"Shards::Helpers","name":"Helpers","abstract":false,"locations":[{"filename":"src/helpers.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/helpers.cr#L32"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"developer_mode?:Bool-class-method","name":"developer_mode?","abstract":false,"location":{"filename":"src/helpers.cr","line_number":112,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/helpers.cr#L112"},"def":{"name":"developer_mode?","return_type":"Bool","visibility":"Public","body":"{% if flag?(:win32) %}\n      key = %q(SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock).to_utf16\n      !!Crystal::System::WindowsRegistry.open?(LibC::HKEY_LOCAL_MACHINE, key) do |handle|\n        value = uninitialized LibC::DWORD\n        name = \"AllowDevelopmentWithoutDevLicense\".to_utf16\n        bytes = Slice.new(pointerof(value), 1).to_unsafe_bytes\n        type, len = Crystal::System::WindowsRegistry.get_raw(handle, name, bytes) || return false\n        return type.dword? && len == sizeof(typeof(value)) && value != 0\n      end\n    {% else %}\n      raise NotImplementedError.new(\"Shards::Helpers.developer_mode?\")\n    {% end %}"},"external_var":false},{"html_id":"exe(name)-class-method","name":"exe","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""}],"args_string":"(name)","args_html":"(name)","location":{"filename":"src/helpers.cr","line_number":59,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/helpers.cr#L59"},"def":{"name":"exe","args":[{"name":"name","external_name":"name","restriction":""}],"visibility":"Public","body":"{% if flag?(:win32) %}\n      name + \".exe\"\n    {% else %}\n      name\n    {% end %}"},"external_var":false},{"html_id":"privilege_enabled?(privilege_name:String):Bool-class-method","name":"privilege_enabled?","abstract":false,"args":[{"name":"privilege_name","external_name":"privilege_name","restriction":"String"}],"args_string":"(privilege_name : String) : Bool","args_html":"(privilege_name : String) : Bool","location":{"filename":"src/helpers.cr","line_number":67,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/helpers.cr#L67"},"def":{"name":"privilege_enabled?","args":[{"name":"privilege_name","external_name":"privilege_name","restriction":"String"}],"return_type":"Bool","visibility":"Public","body":"{% if flag?(:win32) %}\n      if LibC.LookupPrivilegeValueW(nil, privilege_name.to_utf16, out privilege_luid) == 0\n        return false\n      end\n\n      # if the process token already has the privilege, and the privilege is already enabled,\n      # we don't need to do anything else\n      if LibC.OpenProcessToken(LibC.GetCurrentProcess, LibC::TOKEN_QUERY, out token) != 0\n        begin\n          LibC.GetTokenInformation(token, LibC::TokenPrivileges, nil, 0, out len)\n          buf = Pointer(UInt8).malloc(len).as(LibC::TOKEN_PRIVILEGES*)\n          LibC.GetTokenInformation(token, LibC::TokenPrivileges, buf, len, out _)\n          privileges = Slice.new(pointerof(buf.value.@privileges).as(LibC::LUID_AND_ATTRIBUTES*), buf.value.privilegeCount)\n          # if the process token doesn't have the privilege, there is no way\n          # `AdjustTokenPrivileges` could grant or enable it\n          privilege = privileges.find(&.luid.== privilege_luid)\n          return false unless privilege\n          return true if privilege.attributes.bits_set?(LibC::SE_PRIVILEGE_ENABLED)\n        ensure\n          LibC.CloseHandle(token)\n        end\n      end\n\n      if LibC.OpenProcessToken(LibC.GetCurrentProcess, LibC::TOKEN_ADJUST_PRIVILEGES, out adjust_token) != 0\n        new_privileges = LibC::TOKEN_PRIVILEGES.new(\n          privilegeCount: 1,\n          privileges: StaticArray[\n            LibC::LUID_AND_ATTRIBUTES.new(\n              luid: privilege_luid,\n              attributes: LibC::SE_PRIVILEGE_ENABLED,\n            ),\n          ],\n        )\n        if LibC.AdjustTokenPrivileges(adjust_token, 0, pointerof(new_privileges), 0, nil, nil) != 0\n          return true if WinError.value.error_success?\n        end\n      end\n\n      false\n    {% else %}\n      raise NotImplementedError.new(\"Shards::Helpers.privilege_enabled?\")\n    {% end %}"},"external_var":false},{"html_id":"rm_rf(path:String):Nil-class-method","name":"rm_rf","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : Nil","args_html":"(path : String) : Nil","location":{"filename":"src/helpers.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/helpers.cr#L33"},"def":{"name":"rm_rf","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"Nil","visibility":"Public","body":"begin\n  if !(File.symlink?(path)) && (Dir.exists?(path))\n    Dir.each_child(path) do |entry|\n      src = File.join(path, entry)\n      rm_rf(src)\n    end\n    Dir.delete(path)\n  else\n    begin\n      File.delete(path)\n    rescue File::AccessDeniedError\n      File.chmod(path, 438)\n      File.delete(path)\n    end\n  end\nrescue File::Error\nend"},"external_var":false},{"html_id":"rm_rf_children(dir:String):Nil-class-method","name":"rm_rf_children","abstract":false,"args":[{"name":"dir","external_name":"dir","restriction":"String"}],"args_string":"(dir : String) : Nil","args_html":"(dir : String) : Nil","location":{"filename":"src/helpers.cr","line_number":53,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/helpers.cr#L53"},"def":{"name":"rm_rf_children","args":[{"name":"dir","external_name":"dir","restriction":"String"}],"return_type":"Nil","visibility":"Public","body":"Dir.each_child(dir) do |child|\n  rm_rf(File.join(dir, child))\nend"},"external_var":false}]},{"html_id":"Ashard/Shards/HgBookmarkRef","path":"Shards/HgBookmarkRef.html","kind":"struct","full_name":"Shards::HgBookmarkRef","name":"HgBookmarkRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},"ancestors":[{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L36"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(bookmark:String)-class-method","name":"new","abstract":false,"args":[{"name":"bookmark","external_name":"bookmark","restriction":"String"}],"args_string":"(bookmark : String)","args_html":"(bookmark : String)","location":{"filename":"src/resolvers/hg.cr","line_number":37,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L37"},"def":{"name":"new","args":[{"name":"bookmark","external_name":"bookmark","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(bookmark)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"to_hg_ref:String-instance-method","name":"to_hg_ref","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L40"},"def":{"name":"to_hg_ref","visibility":"Public","body":"@bookmark"},"external_var":false},{"html_id":"to_hg_revset-instance-method","name":"to_hg_revset","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L44"},"def":{"name":"to_hg_revset","visibility":"Public","body":"\"bookmark(\\\"#{@bookmark}\\\")\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/hg.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L48"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"bookmark \") << @bookmark"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/hg.cr","line_number":52,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L52"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"bookmark\")\nyaml.scalar(@bookmark)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/HgBranchRef","path":"Shards/HgBranchRef.html","kind":"struct","full_name":"Shards::HgBranchRef","name":"HgBranchRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},"ancestors":[{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L14"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(branch:String)-class-method","name":"new","abstract":false,"args":[{"name":"branch","external_name":"branch","restriction":"String"}],"args_string":"(branch : String)","args_html":"(branch : String)","location":{"filename":"src/resolvers/hg.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L15"},"def":{"name":"new","args":[{"name":"branch","external_name":"branch","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(branch)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"to_hg_ref:String-instance-method","name":"to_hg_ref","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L18"},"def":{"name":"to_hg_ref","visibility":"Public","body":"@branch"},"external_var":false},{"html_id":"to_hg_revset-instance-method","name":"to_hg_revset","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L22"},"def":{"name":"to_hg_revset","visibility":"Public","body":"\"branch(\\\"#{@branch}\\\") and head()\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/hg.cr","line_number":26,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L26"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"branch \") << @branch"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/hg.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L30"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"branch\")\nyaml.scalar(@branch)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/HgCommitRef","path":"Shards/HgCommitRef.html","kind":"struct","full_name":"Shards::HgCommitRef","name":"HgCommitRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},"ancestors":[{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":80,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L80"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(commit:String)-class-method","name":"new","abstract":false,"args":[{"name":"commit","external_name":"commit","restriction":"String"}],"args_string":"(commit : String)","args_html":"(commit : String)","location":{"filename":"src/resolvers/hg.cr","line_number":83,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L83"},"def":{"name":"new","args":[{"name":"commit","external_name":"commit","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(commit)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"=~(other:HgCommitRef)-instance-method","name":"=~","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"HgCommitRef"}],"args_string":"(other : HgCommitRef)","args_html":"(other : <a href=\"../Shards/HgCommitRef.html\">HgCommitRef</a>)","location":{"filename":"src/resolvers/hg.cr","line_number":86,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L86"},"def":{"name":"=~","args":[{"name":"other","external_name":"other","restriction":"HgCommitRef"}],"visibility":"Public","body":"(commit.starts_with?(other.commit)) || (other.commit.starts_with?(commit))"},"external_var":false},{"html_id":"commit:String-instance-method","name":"commit","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":81,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L81"},"def":{"name":"commit","return_type":"String","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"full_info-instance-method","name":"full_info","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":102,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L102"},"def":{"name":"full_info","visibility":"Public","body":"\"commit #{@commit}\""},"external_var":false},{"html_id":"to_hg_ref:String-instance-method","name":"to_hg_ref","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":90,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L90"},"def":{"name":"to_hg_ref","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"to_hg_revset:String-instance-method","name":"to_hg_revset","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":94,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L94"},"def":{"name":"to_hg_revset","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/hg.cr","line_number":98,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L98"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"commit \") << @commit[0...7]"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/hg.cr","line_number":106,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L106"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"commit\")\nyaml.scalar(@commit)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/HgCurrentRef","path":"Shards/HgCurrentRef.html","kind":"struct","full_name":"Shards::HgCurrentRef","name":"HgCurrentRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},"ancestors":[{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":112,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L112"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"instance_methods":[{"html_id":"to_hg_ref-instance-method","name":"to_hg_ref","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":117,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L117"},"def":{"name":"to_hg_ref","visibility":"Public","body":"\".\""},"external_var":false},{"html_id":"to_hg_revset-instance-method","name":"to_hg_revset","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":113,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L113"},"def":{"name":"to_hg_revset","visibility":"Public","body":"\".\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/hg.cr","line_number":121,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L121"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"io << \"current\""},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/hg.cr","line_number":125,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L125"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"raise(NotImplementedError.new(\"HgCurrentRef is for internal use only\"))"},"external_var":false}]},{"html_id":"Ashard/Shards/HgRef","path":"Shards/HgRef.html","kind":"struct","full_name":"Shards::HgRef","name":"HgRef","abstract":true,"superclass":{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},"ancestors":[{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/HgBookmarkRef","kind":"struct","full_name":"Shards::HgBookmarkRef","name":"HgBookmarkRef"},{"html_id":"Ashard/Shards/HgBranchRef","kind":"struct","full_name":"Shards::HgBranchRef","name":"HgBranchRef"},{"html_id":"Ashard/Shards/HgCommitRef","kind":"struct","full_name":"Shards::HgCommitRef","name":"HgCommitRef"},{"html_id":"Ashard/Shards/HgCurrentRef","kind":"struct","full_name":"Shards::HgCurrentRef","name":"HgCurrentRef"},{"html_id":"Ashard/Shards/HgTagRef","kind":"struct","full_name":"Shards::HgTagRef","name":"HgTagRef"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"instance_methods":[{"html_id":"full_info-instance-method","name":"full_info","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L9"},"def":{"name":"full_info","visibility":"Public","body":"to_s"},"external_var":false}]},{"html_id":"Ashard/Shards/HgResolver","path":"Shards/HgResolver.html","kind":"class","full_name":"Shards::HgResolver","name":"HgResolver","abstract":false,"superclass":{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},"ancestors":[{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":130,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L130"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"key-class-method","name":"key","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":136,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L136"},"def":{"name":"key","visibility":"Public","body":"\"hg\""},"external_var":false},{"html_id":"normalize_key_source(key:String,source:String):Tuple(String,String)-class-method","name":"normalize_key_source","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(key : String, source : String) : Tuple(String, String)","args_html":"(key : String, source : String) : Tuple(String, String)","location":{"filename":"src/resolvers/hg.cr","line_number":140,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L140"},"def":{"name":"normalize_key_source","args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"return_type":"::Tuple(String, String)","visibility":"Public","body":"case key\nwhen \"hg\"\n  {\"hg\", source}\nelse\n  raise(\"Unknown resolver #{key}\")\nend"},"external_var":false}],"instance_methods":[{"html_id":"available_releases:Array(Version)-instance-method","name":"available_releases","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":189,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L189"},"def":{"name":"available_releases","return_type":"Array(Version)","visibility":"Public","body":"update_local_cache\nversions_from_tags\n"},"external_var":false},{"html_id":"commit_sha1_at(ref:HgRef)-instance-method","name":"commit_sha1_at","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"HgRef"}],"args_string":"(ref : HgRef)","args_html":"(ref : <a href=\"../Shards/HgRef.html\">HgRef</a>)","location":{"filename":"src/resolvers/hg.cr","line_number":239,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L239"},"def":{"name":"commit_sha1_at","args":[{"name":"ref","external_name":"ref","restriction":"HgRef"}],"visibility":"Public","body":"(capture(\"hg log -r #{Process.quote(ref.to_hg_revset)} --template #{Process.quote(\"{node}\\n\")}\")).strip"},"external_var":false},{"html_id":"hg_url-instance-method","name":"hg_url","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":262,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L262"},"def":{"name":"hg_url","visibility":"Public","body":"source.strip"},"external_var":false},{"html_id":"install_sources(version:Version,install_path:String)-instance-method","name":"install_sources","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"args_string":"(version : Version, install_path : String)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>, install_path : String)","location":{"filename":"src/resolvers/hg.cr","line_number":230,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L230"},"def":{"name":"install_sources","args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"visibility":"Public","body":"update_local_cache\nref = hg_ref(version)\n\nif File.exists?(install_path)\n  FileUtils.rm_r(install_path)\nend\nDir.mkdir_p(install_path)\nrun(\"hg clone --quiet -u #{Process.quote(ref.to_hg_ref)} -- #{Process.quote(local_path)} #{Process.quote(install_path)}\")\n"},"external_var":false},{"html_id":"latest_version_for_ref(ref:HgRef|Nil):Version-instance-method","name":"latest_version_for_ref","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"HgRef | ::Nil"}],"args_string":"(ref : HgRef | Nil) : Version","args_html":"(ref : <a href=\"../Shards/HgRef.html\">HgRef</a> | Nil) : <a href=\"../Shards/Version.html\">Version</a>","location":{"filename":"src/resolvers/hg.cr","line_number":194,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L194"},"def":{"name":"latest_version_for_ref","args":[{"name":"ref","external_name":"ref","restriction":"HgRef | ::Nil"}],"return_type":"Version","visibility":"Public","body":"update_local_cache\nref || (ref = HgCurrentRef.new)\nbegin\n  commit = commit_sha1_at(ref)\nrescue Error\n  raise(Error.new(\"Could not find #{ref.full_info} for shard #{name.inspect} in the repository #{source}\"))\nend\n\nif spec = spec_at_ref(ref)\n  Version.new(\"#{spec.version.value}+hg.commit.#{commit}\")\nelse\n  raise(Error.new(\"No #{SPEC_FILENAME} was found for shard #{name.inspect} at commit #{commit}\"))\nend\n"},"external_var":false},{"html_id":"local_path-instance-method","name":"local_path","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":243,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L243"},"def":{"name":"local_path","visibility":"Public","body":"@local_path || (\n  @local_path = (begin\n    uri = parse_uri(hg_url)\n\n    path = uri.path\n    path = Path[path]\n\n    if (anchor = path.anchor)\n      path = Path[path.drive.to_s.rchop(\":\"), path.relative_to(anchor)]\n    end\n\n    if host = uri.host\n      File.join(Shards.cache_path, host, path)\n    else\n      File.join(Shards.cache_path, path)\n    end\n  end)\n)"},"external_var":false},{"html_id":"matches_ref?(ref:HgRef,version:Version)-instance-method","name":"matches_ref?","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"HgRef"},{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(ref : HgRef, version : Version)","args_html":"(ref : <a href=\"../Shards/HgRef.html\">HgRef</a>, version : <a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/resolvers/hg.cr","line_number":210,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L210"},"def":{"name":"matches_ref?","args":[{"name":"ref","external_name":"ref","restriction":"HgRef"},{"name":"version","external_name":"version","restriction":"Version"}],"visibility":"Public","body":"case ref\nwhen HgCommitRef\n  ref =~ (hg_ref(version))\nwhen HgBranchRef, HgBookmarkRef, HgCurrentRef\n  version.has_metadata?\nelse\n  true\nend"},"external_var":false},{"html_id":"parse_requirement(params:Hash(String,String)):Requirement-instance-method","name":"parse_requirement","abstract":false,"args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"args_string":"(params : Hash(String, String)) : Requirement","args_html":"(params : Hash(String, String)) : <a href=\"../Shards/Requirement.html\">Requirement</a>","location":{"filename":"src/resolvers/hg.cr","line_number":266,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L266"},"def":{"name":"parse_requirement","args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"return_type":"Requirement","visibility":"Public","body":"params.each do |key, value|\n  case key\n  when \"branch\"\n    return HgBranchRef.new(value)\n  when \"bookmark\"\n    return HgBookmarkRef.new(value)\n  when \"tag\"\n    return HgTagRef.new(value)\n  when \"commit\"\n    return HgCommitRef.new(value)\n  end\nend\n\nsuper(params)\n"},"external_var":false},{"html_id":"read_spec(version:Version):String|Nil-instance-method","name":"read_spec","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String | Nil","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String | Nil","location":{"filename":"src/resolvers/hg.cr","line_number":160,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L160"},"def":{"name":"read_spec","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String | ::Nil","visibility":"Public","body":"update_local_cache\nref = hg_ref(version)\n\nif file_exists?(ref, SPEC_FILENAME)\n  capture(\"hg cat -r #{Process.quote(ref.to_hg_revset)} #{Process.quote(SPEC_FILENAME)}\")\nelse\n  Log.debug do \"Missing \\\"#{SPEC_FILENAME}\\\" for #{name.inspect} at #{ref}\" end\n  nil\nend\n"},"external_var":false},{"html_id":"report_version(version:Version):String-instance-method","name":"report_version","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String","location":{"filename":"src/resolvers/hg.cr","line_number":467,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L467"},"def":{"name":"report_version","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String","visibility":"Public","body":"hg_version = parse_hg_version(version)\nif commit = hg_version.commit\n  \"#{hg_version.value} at #{commit[0...7]}\"\nelse\n  version.value\nend\n"},"external_var":false},{"html_id":"update_local_cache-instance-method","name":"update_local_cache","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":305,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L305"},"def":{"name":"update_local_cache","visibility":"Public","body":"if cloned_repository? && origin_changed?\n  delete_repository\n  @updated_cache = false\nend\n\nif Shards.local? || @updated_cache\n  return\nend\nLog.info do \"Fetching #{hg_url}\" end\n\nif cloned_repository?\n  if valid_repository?\n    fetch_repository\n  else\n    delete_repository\n    mirror_repository\n  end\nelse\n  mirror_repository\nend\n\n@updated_cache = true\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/HgResolver/HgVersion","path":"Shards/HgResolver/HgVersion.html","kind":"struct","full_name":"Shards::HgResolver::HgVersion","name":"HgVersion","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":283,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L283"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/HgResolver","kind":"class","full_name":"Shards::HgResolver","name":"HgResolver"},"constructors":[{"html_id":"new(value:String,commit:String|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"commit","default_value":"nil","external_name":"commit","restriction":"String | ::Nil"}],"args_string":"(value : String, commit : String | Nil = nil)","args_html":"(value : String, commit : String | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/resolvers/hg.cr","line_number":283,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L283"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"commit","default_value":"nil","external_name":"commit","restriction":"String | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, commit)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":283,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L283"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@value.clone, @commit.clone)"},"external_var":false},{"html_id":"commit:String|Nil-instance-method","name":"commit","abstract":false,"def":{"name":"commit","return_type":"String | ::Nil","visibility":"Public","body":"@commit"},"external_var":false},{"html_id":"copy_with(value_value=@value,commit_commit=@commit)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_value","default_value":"@value","external_name":"value","restriction":""},{"name":"_commit","default_value":"@commit","external_name":"commit","restriction":""}],"args_string":"(value _value = @value, commit _commit = @commit)","args_html":"(value _value = @value, commit _commit = @commit)","location":{"filename":"src/resolvers/hg.cr","line_number":283,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L283"},"def":{"name":"copy_with","args":[{"name":"_value","default_value":"@value","external_name":"value","restriction":""},{"name":"_commit","default_value":"@commit","external_name":"commit","restriction":""}],"visibility":"Public","body":"self.class.new(_value, _commit)"},"external_var":false},{"html_id":"value:String-instance-method","name":"value","abstract":false,"def":{"name":"value","return_type":"String","visibility":"Public","body":"@value"},"external_var":false}]}]},{"html_id":"Ashard/Shards/HgTagRef","path":"Shards/HgTagRef.html","kind":"struct","full_name":"Shards::HgTagRef","name":"HgTagRef","abstract":false,"superclass":{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},"ancestors":[{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"},{"html_id":"Ashard/Shards/Ref","kind":"struct","full_name":"Shards::Ref","name":"Ref"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/hg.cr","line_number":58,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L58"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(tag:String)-class-method","name":"new","abstract":false,"args":[{"name":"tag","external_name":"tag","restriction":"String"}],"args_string":"(tag : String)","args_html":"(tag : String)","location":{"filename":"src/resolvers/hg.cr","line_number":59,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L59"},"def":{"name":"new","args":[{"name":"tag","external_name":"tag","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(tag)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"to_hg_ref:String-instance-method","name":"to_hg_ref","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":62,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L62"},"def":{"name":"to_hg_ref","visibility":"Public","body":"@tag"},"external_var":false},{"html_id":"to_hg_revset-instance-method","name":"to_hg_revset","abstract":false,"location":{"filename":"src/resolvers/hg.cr","line_number":66,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L66"},"def":{"name":"to_hg_revset","visibility":"Public","body":"\"tag(\\\"#{@tag}\\\")\""},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/resolvers/hg.cr","line_number":70,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L70"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(io << \"tag \") << @tag"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/resolvers/hg.cr","line_number":74,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/hg.cr#L74"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"tag\")\nyaml.scalar(@tag)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/IgnoreRule","path":"Shards/IgnoreRule.html","kind":"struct","full_name":"Shards::IgnoreRule","name":"IgnoreRule","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/vulnerability_scanner.cr","line_number":65,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L65"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Ignore rule loaded from .shards-audit-ignore or --ignore flag.","summary":"<p>Ignore rule loaded from .shards-audit-ignore or --ignore flag.</p>","constructors":[{"html_id":"new(id:String,reason:Nil|String=nil,expires:Time|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"::String"},{"name":"reason","default_value":"nil","external_name":"reason","restriction":"::Nil | ::String"},{"name":"expires","default_value":"nil","external_name":"expires","restriction":"::Time | ::Nil"}],"args_string":"(id : String, reason : Nil | String = nil, expires : Time | Nil = nil)","args_html":"(id : String, reason : Nil | String = <span class=\"n\">nil</span>, expires : Time | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/vulnerability_scanner.cr","line_number":70,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L70"},"def":{"name":"new","args":[{"name":"id","external_name":"id","restriction":"::String"},{"name":"reason","default_value":"nil","external_name":"reason","restriction":"::Nil | ::String"},{"name":"expires","default_value":"nil","external_name":"expires","restriction":"::Time | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(id, reason, expires)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"active?:Bool-instance-method","name":"active?","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":81,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L81"},"def":{"name":"active?","return_type":"Bool","visibility":"Public","body":"!expired?"},"external_var":false},{"html_id":"expired?:Bool-instance-method","name":"expired?","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":73,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L73"},"def":{"name":"expired?","return_type":"Bool","visibility":"Public","body":"if exp = @expires\n  Time.utc > exp\nelse\n  false\nend"},"external_var":false},{"html_id":"expires:Time|Nil-instance-method","name":"expires","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":68,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L68"},"def":{"name":"expires","return_type":"Time | ::Nil","visibility":"Public","body":"@expires"},"external_var":false},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":66,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L66"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"},"external_var":false},{"html_id":"reason:String|Nil-instance-method","name":"reason","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":67,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L67"},"def":{"name":"reason","return_type":"String | ::Nil","visibility":"Public","body":"@reason"},"external_var":false}]},{"html_id":"Ashard/Shards/Info","path":"Shards/Info.html","kind":"class","full_name":"Shards::Info","name":"Info","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/info.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/info.cr#L3"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(install_path:String=Shards.install_path)-class-method","name":"new","abstract":false,"args":[{"name":"install_path","default_value":"Shards.install_path","external_name":"install_path","restriction":"::String"}],"args_string":"(install_path : String = Shards.install_path)","args_html":"(install_path : String = <span class=\"t\">Shards</span>.install_path)","location":{"filename":"src/info.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/info.cr#L7"},"def":{"name":"new","args":[{"name":"install_path","default_value":"Shards.install_path","external_name":"install_path","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(install_path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"info_path-instance-method","name":"info_path","abstract":false,"location":{"filename":"src/info.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/info.cr#L48"},"def":{"name":"info_path","visibility":"Public","body":"File.join(@install_path, \".shards.info\")"},"external_var":false},{"html_id":"install_path:String-instance-method","name":"install_path","abstract":false,"location":{"filename":"src/info.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/info.cr#L4"},"def":{"name":"install_path","return_type":"String","visibility":"Public","body":"@install_path"},"external_var":false},{"html_id":"installed:Hash(String,Shards::Package)-instance-method","name":"installed","abstract":false,"location":{"filename":"src/info.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/info.cr#L5"},"def":{"name":"installed","visibility":"Public","body":"@installed"},"external_var":false},{"html_id":"reload-instance-method","name":"reload","abstract":false,"location":{"filename":"src/info.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/info.cr#L11"},"def":{"name":"reload","visibility":"Public","body":"path = info_path\nif File.exists?(path)\n  @installed = (Lock.from_file(path)).shards.index_by(&.name)\nelse\n  @installed.clear\nend\n"},"external_var":false},{"html_id":"save-instance-method","name":"save","abstract":false,"location":{"filename":"src/info.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/info.cr#L20"},"def":{"name":"save","visibility":"Public","body":"Dir.mkdir_p(@install_path)\n\nif File.exists?(info_path)\nelse\n  Dir.each_child(@install_path) do |name|\n    if name.ends_with?(\".sha1\")\n      File.delete(File.join(@install_path, name))\n    end\n  end\nend\n\nFile.open(info_path, \"w\") do |file|\n  YAML.build(file) do |yaml|\n    yaml.mapping do\n      yaml.scalar(\"version\")\n      yaml.scalar(\"1.0\")\n\n      yaml.scalar(\"shards\")\n      yaml.mapping do\n        installed.each do |name, dep|\n          dep.to_yaml(yaml)\n        end\n      end\n    end\n  end\nend\n"},"external_var":false}]},{"html_id":"Ashard/Shards/InvalidLock","path":"Shards/InvalidLock.html","kind":"class","full_name":"Shards::InvalidLock","name":"InvalidLock","abstract":false,"superclass":{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},"ancestors":[{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/errors.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L19"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/errors.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L20"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}]},{"html_id":"Ashard/Shards/LicensePolicy","path":"Shards/LicensePolicy.html","kind":"class","full_name":"Shards::LicensePolicy","name":"LicensePolicy","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_policy.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"DEFAULT_POLICY_FILENAME","name":"DEFAULT_POLICY_FILENAME","value":"\".shards-license-policy.yml\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"compute_summary(results:Array(DependencyResult)):Summary-class-method","name":"compute_summary","abstract":false,"args":[{"name":"results","external_name":"results","restriction":"Array(DependencyResult)"}],"args_string":"(results : Array(DependencyResult)) : Summary","args_html":"(results : Array(<a href=\"../Shards/LicensePolicy/DependencyResult.html\">DependencyResult</a>)) : <a href=\"../Shards/LicensePolicy/Summary.html\">Summary</a>","location":{"filename":"src/license_policy.cr","line_number":248,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L248"},"def":{"name":"compute_summary","args":[{"name":"results","external_name":"results","restriction":"Array(DependencyResult)"}],"return_type":"Summary","visibility":"Public","body":"allowed = 0\ndenied = 0\nunlicensed = 0\nunknown = 0\noverridden = 0\n\nresults.each do |r|\n  case r.verdict\n  when Verdict::Allowed\n    allowed = allowed + 1\n  when Verdict::Denied\n    denied = denied + 1\n  when Verdict::Unlicensed\n    unlicensed = unlicensed + 1\n  when Verdict::Unknown\n    unknown = unknown + 1\n  when Verdict::Overridden\n    overridden = overridden + 1\n  end\nend\n\nSummary.new(total: results.size.to_i32, allowed: allowed.to_i32, denied: denied.to_i32, unlicensed: unlicensed.to_i32, unknown: unknown.to_i32, overridden: overridden.to_i32)\n"},"external_var":false},{"html_id":"evaluate(packages:Array(Package),root_spec:Spec,policy:PolicyConfig|Nil,detect:Bool=false):PolicyReport-class-method","name":"evaluate","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"},{"name":"root_spec","external_name":"root_spec","restriction":"Spec"},{"name":"policy","external_name":"policy","restriction":"PolicyConfig | ::Nil"},{"name":"detect","default_value":"false","external_name":"detect","restriction":"Bool"}],"args_string":"(packages : Array(Package), root_spec : Spec, policy : PolicyConfig | Nil, detect : Bool = false) : PolicyReport","args_html":"(packages : Array(<a href=\"../Shards/Package.html\">Package</a>), root_spec : <a href=\"../Shards/Spec.html\">Spec</a>, policy : <a href=\"../Shards/LicensePolicy/PolicyConfig.html\">PolicyConfig</a> | Nil, detect : Bool = <span class=\"n\">false</span>) : <a href=\"../Shards/LicensePolicy/PolicyReport.html\">PolicyReport</a>","location":{"filename":"src/license_policy.cr","line_number":120,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L120"},"def":{"name":"evaluate","args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"},{"name":"root_spec","external_name":"root_spec","restriction":"Spec"},{"name":"policy","external_name":"policy","restriction":"PolicyConfig | ::Nil"},{"name":"detect","default_value":"false","external_name":"detect","restriction":"Bool"}],"return_type":"PolicyReport","visibility":"Public","body":"results = packages.map do |pkg| evaluate_package(pkg, policy, detect) end\nsummary = compute_summary(results)\nPolicyReport.new(root_name: root_spec.name, root_version: root_spec.version.to_s, root_license: root_spec.license, dependencies: results, policy_used: !policy.nil?, summary: summary)\n"},"external_var":false},{"html_id":"evaluate_against_policy(license:String|Nil,policy:PolicyConfig|Nil):Verdict-class-method","name":"evaluate_against_policy","abstract":false,"args":[{"name":"license","external_name":"license","restriction":"String | ::Nil"},{"name":"policy","external_name":"policy","restriction":"PolicyConfig | ::Nil"}],"args_string":"(license : String | Nil, policy : PolicyConfig | Nil) : Verdict","args_html":"(license : String | Nil, policy : <a href=\"../Shards/LicensePolicy/PolicyConfig.html\">PolicyConfig</a> | Nil) : <a href=\"../Shards/LicensePolicy/Verdict.html\">Verdict</a>","location":{"filename":"src/license_policy.cr","line_number":138,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L138"},"def":{"name":"evaluate_against_policy","args":[{"name":"license","external_name":"license","restriction":"String | ::Nil"},{"name":"policy","external_name":"policy","restriction":"PolicyConfig | ::Nil"}],"return_type":"Verdict","visibility":"Public","body":"if license.nil? || license.empty?\n  return Verdict::Unlicensed\nend\nif policy.nil?\n  return Verdict::Unknown\nend\n\n\nbegin\n  expr = SPDX::Parser.parse(license)\n\n\n  ids = expr.license_ids\n  ids.each do |id|\n    if policy.denied.includes?(id)\n      return Verdict::Denied\n    end\n  end\n\n\n  if expr.satisfied_by?(policy.allowed)\n    return Verdict::Allowed\n  end\n\n\n  return Verdict::Unknown\nrescue Shards::Error\nend\n\n\nif policy.denied.includes?(license)\n  return Verdict::Denied\nend\nif policy.allowed.includes?(license)\n  return Verdict::Allowed\nend\nVerdict::Unknown\n"},"external_var":false},{"html_id":"load_policy(path:String|Nil):PolicyConfig|Nil-class-method","name":"load_policy","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String | ::Nil"}],"args_string":"(path : String | Nil) : PolicyConfig | Nil","args_html":"(path : String | Nil) : <a href=\"../Shards/LicensePolicy/PolicyConfig.html\">PolicyConfig</a> | Nil","location":{"filename":"src/license_policy.cr","line_number":56,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L56"},"def":{"name":"load_policy","args":[{"name":"path","external_name":"path","restriction":"String | ::Nil"}],"return_type":"PolicyConfig | ::Nil","visibility":"Public","body":"actual_path = path || DEFAULT_POLICY_FILENAME\nif File.exists?(actual_path)\nelse\n  return nil\nend\nyaml = YAML.parse(File.read(actual_path))\npolicy = yaml[\"policy\"]?\nif policy\nelse\n  return nil\nend\n\nallowed = Set(String).new\nif allowed_list = policy[\"allowed\"]?\n  if arr = allowed_list.as_a?\n    arr.each do |item|\n      if s = item.as_s?\n        allowed << s\n      end\n    end\n  end\nend\n\ndenied = Set(String).new\nif denied_list = policy[\"denied\"]?\n  if arr = denied_list.as_a?\n    arr.each do |item|\n      if s = item.as_s?\n        denied << s\n      end\n    end\n  end\nend\n\nrequire_license = false\nif req = policy[\"require_license\"]?\n  if b = req.as_bool?\n    require_license = b\n  end\nend\n\noverrides = Hash(String, Override).new\nif overrides_map = policy[\"overrides\"]?\n  if h = overrides_map.as_h?\n    h.each do |key, value|\n      name = key.as_s\n      license = \"\"\n      reason : String | ::Nil = nil\n      if vh = value.as_h?\n        if l = vh[\"license\"]?\n          license = l.as_s? || \"\"\n        end\n        if r = vh[\"reason\"]?\n          reason = r.as_s?\n        end\n      end\n      overrides[name] = Override.new(license: license, reason: reason)\n    end\n  end\nend\n\nPolicyConfig.new(allowed: allowed, denied: denied, require_license: require_license, overrides: overrides)\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/LicensePolicy/DependencyResult","path":"Shards/LicensePolicy/DependencyResult.html","kind":"struct","full_name":"Shards::LicensePolicy::DependencyResult","name":"DependencyResult","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_policy.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L27"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/LicensePolicy","kind":"class","full_name":"Shards::LicensePolicy","name":"LicensePolicy"},"constructors":[{"html_id":"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)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"version","external_name":"version","restriction":"String"},{"name":"declared_license","external_name":"declared_license","restriction":"String | ::Nil"},{"name":"detected_license","external_name":"detected_license","restriction":"String | ::Nil"},{"name":"effective_license","external_name":"effective_license","restriction":"String | ::Nil"},{"name":"license_source","external_name":"license_source","restriction":"Symbol"},{"name":"verdict","external_name":"verdict","restriction":"Verdict"},{"name":"override_reason","external_name":"override_reason","restriction":"String | ::Nil"},{"name":"spdx_valid","external_name":"spdx_valid","restriction":"Bool"},{"name":"category","external_name":"category","restriction":"SPDX::Category"},{"name":"scan_result","external_name":"scan_result","restriction":"LicenseScanner::ScanResult | ::Nil"}],"args_string":"(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)","args_html":"(name : String, version : String, declared_license : String | Nil, detected_license : String | Nil, effective_license : String | Nil, license_source : Symbol, verdict : <a href=\"../../Shards/LicensePolicy/Verdict.html\">Verdict</a>, override_reason : String | Nil, spdx_valid : Bool, category : <a href=\"../../Shards/SPDX/Category.html\">SPDX::Category</a>, scan_result : <a href=\"../../Shards/LicenseScanner/ScanResult.html\">LicenseScanner::ScanResult</a> | Nil)","location":{"filename":"src/license_policy.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L27"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"version","external_name":"version","restriction":"String"},{"name":"declared_license","external_name":"declared_license","restriction":"String | ::Nil"},{"name":"detected_license","external_name":"detected_license","restriction":"String | ::Nil"},{"name":"effective_license","external_name":"effective_license","restriction":"String | ::Nil"},{"name":"license_source","external_name":"license_source","restriction":"Symbol"},{"name":"verdict","external_name":"verdict","restriction":"Verdict"},{"name":"override_reason","external_name":"override_reason","restriction":"String | ::Nil"},{"name":"spdx_valid","external_name":"spdx_valid","restriction":"Bool"},{"name":"category","external_name":"category","restriction":"SPDX::Category"},{"name":"scan_result","external_name":"scan_result","restriction":"LicenseScanner::ScanResult | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, version, declared_license, detected_license, effective_license, license_source, verdict, override_reason, spdx_valid, category, scan_result)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"category:SPDX::Category-instance-method","name":"category","abstract":false,"def":{"name":"category","return_type":"SPDX::Category","visibility":"Public","body":"@category"},"external_var":false},{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L27"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@name.clone, @version.clone, @declared_license.clone, @detected_license.clone, @effective_license.clone, @license_source.clone, @verdict.clone, @override_reason.clone, @spdx_valid.clone, @category.clone, @scan_result.clone)"},"external_var":false},{"html_id":"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)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_name","default_value":"@name","external_name":"name","restriction":""},{"name":"_version","default_value":"@version","external_name":"version","restriction":""},{"name":"_declared_license","default_value":"@declared_license","external_name":"declared_license","restriction":""},{"name":"_detected_license","default_value":"@detected_license","external_name":"detected_license","restriction":""},{"name":"_effective_license","default_value":"@effective_license","external_name":"effective_license","restriction":""},{"name":"_license_source","default_value":"@license_source","external_name":"license_source","restriction":""},{"name":"_verdict","default_value":"@verdict","external_name":"verdict","restriction":""},{"name":"_override_reason","default_value":"@override_reason","external_name":"override_reason","restriction":""},{"name":"_spdx_valid","default_value":"@spdx_valid","external_name":"spdx_valid","restriction":""},{"name":"_category","default_value":"@category","external_name":"category","restriction":""},{"name":"_scan_result","default_value":"@scan_result","external_name":"scan_result","restriction":""}],"args_string":"(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)","args_html":"(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)","location":{"filename":"src/license_policy.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L27"},"def":{"name":"copy_with","args":[{"name":"_name","default_value":"@name","external_name":"name","restriction":""},{"name":"_version","default_value":"@version","external_name":"version","restriction":""},{"name":"_declared_license","default_value":"@declared_license","external_name":"declared_license","restriction":""},{"name":"_detected_license","default_value":"@detected_license","external_name":"detected_license","restriction":""},{"name":"_effective_license","default_value":"@effective_license","external_name":"effective_license","restriction":""},{"name":"_license_source","default_value":"@license_source","external_name":"license_source","restriction":""},{"name":"_verdict","default_value":"@verdict","external_name":"verdict","restriction":""},{"name":"_override_reason","default_value":"@override_reason","external_name":"override_reason","restriction":""},{"name":"_spdx_valid","default_value":"@spdx_valid","external_name":"spdx_valid","restriction":""},{"name":"_category","default_value":"@category","external_name":"category","restriction":""},{"name":"_scan_result","default_value":"@scan_result","external_name":"scan_result","restriction":""}],"visibility":"Public","body":"self.class.new(_name, _version, _declared_license, _detected_license, _effective_license, _license_source, _verdict, _override_reason, _spdx_valid, _category, _scan_result)"},"external_var":false},{"html_id":"declared_license:String|Nil-instance-method","name":"declared_license","abstract":false,"def":{"name":"declared_license","return_type":"String | ::Nil","visibility":"Public","body":"@declared_license"},"external_var":false},{"html_id":"detected_license:String|Nil-instance-method","name":"detected_license","abstract":false,"def":{"name":"detected_license","return_type":"String | ::Nil","visibility":"Public","body":"@detected_license"},"external_var":false},{"html_id":"effective_license:String|Nil-instance-method","name":"effective_license","abstract":false,"def":{"name":"effective_license","return_type":"String | ::Nil","visibility":"Public","body":"@effective_license"},"external_var":false},{"html_id":"license_source:Symbol-instance-method","name":"license_source","abstract":false,"def":{"name":"license_source","return_type":"Symbol","visibility":"Public","body":"@license_source"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"override_reason:String|Nil-instance-method","name":"override_reason","abstract":false,"def":{"name":"override_reason","return_type":"String | ::Nil","visibility":"Public","body":"@override_reason"},"external_var":false},{"html_id":"scan_result:LicenseScanner::ScanResult|Nil-instance-method","name":"scan_result","abstract":false,"def":{"name":"scan_result","return_type":"LicenseScanner::ScanResult | ::Nil","visibility":"Public","body":"@scan_result"},"external_var":false},{"html_id":"spdx_valid:Bool-instance-method","name":"spdx_valid","abstract":false,"def":{"name":"spdx_valid","return_type":"Bool","visibility":"Public","body":"@spdx_valid"},"external_var":false},{"html_id":"verdict:Verdict-instance-method","name":"verdict","abstract":false,"def":{"name":"verdict","return_type":"Verdict","visibility":"Public","body":"@verdict"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false}]},{"html_id":"Ashard/Shards/LicensePolicy/Override","path":"Shards/LicensePolicy/Override.html","kind":"struct","full_name":"Shards::LicensePolicy::Override","name":"Override","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_policy.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L15"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/LicensePolicy","kind":"class","full_name":"Shards::LicensePolicy","name":"LicensePolicy"},"constructors":[{"html_id":"new(license:String,reason:String|Nil)-class-method","name":"new","abstract":false,"args":[{"name":"license","external_name":"license","restriction":"String"},{"name":"reason","external_name":"reason","restriction":"String | ::Nil"}],"args_string":"(license : String, reason : String | Nil)","args_html":"(license : String, reason : String | Nil)","location":{"filename":"src/license_policy.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L15"},"def":{"name":"new","args":[{"name":"license","external_name":"license","restriction":"String"},{"name":"reason","external_name":"reason","restriction":"String | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(license, reason)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L15"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@license.clone, @reason.clone)"},"external_var":false},{"html_id":"copy_with(license_license=@license,reason_reason=@reason)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_license","default_value":"@license","external_name":"license","restriction":""},{"name":"_reason","default_value":"@reason","external_name":"reason","restriction":""}],"args_string":"(license _license = @license, reason _reason = @reason)","args_html":"(license _license = @license, reason _reason = @reason)","location":{"filename":"src/license_policy.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L15"},"def":{"name":"copy_with","args":[{"name":"_license","default_value":"@license","external_name":"license","restriction":""},{"name":"_reason","default_value":"@reason","external_name":"reason","restriction":""}],"visibility":"Public","body":"self.class.new(_license, _reason)"},"external_var":false},{"html_id":"license:String-instance-method","name":"license","abstract":false,"def":{"name":"license","return_type":"String","visibility":"Public","body":"@license"},"external_var":false},{"html_id":"reason:String|Nil-instance-method","name":"reason","abstract":false,"def":{"name":"reason","return_type":"String | ::Nil","visibility":"Public","body":"@reason"},"external_var":false}]},{"html_id":"Ashard/Shards/LicensePolicy/PolicyConfig","path":"Shards/LicensePolicy/PolicyConfig.html","kind":"struct","full_name":"Shards::LicensePolicy::PolicyConfig","name":"PolicyConfig","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_policy.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L9"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/LicensePolicy","kind":"class","full_name":"Shards::LicensePolicy","name":"LicensePolicy"},"constructors":[{"html_id":"new(allowed:Set(String),denied:Set(String),require_license:Bool,overrides:Hash(String,Override))-class-method","name":"new","abstract":false,"args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"},{"name":"denied","external_name":"denied","restriction":"Set(String)"},{"name":"require_license","external_name":"require_license","restriction":"Bool"},{"name":"overrides","external_name":"overrides","restriction":"Hash(String, Override)"}],"args_string":"(allowed : Set(String), denied : Set(String), require_license : Bool, overrides : Hash(String, Override))","args_html":"(allowed : Set(String), denied : Set(String), require_license : Bool, overrides : Hash(String, <a href=\"../../Shards/LicensePolicy/Override.html\">Override</a>))","location":{"filename":"src/license_policy.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L9"},"def":{"name":"new","args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"},{"name":"denied","external_name":"denied","restriction":"Set(String)"},{"name":"require_license","external_name":"require_license","restriction":"Bool"},{"name":"overrides","external_name":"overrides","restriction":"Hash(String, Override)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(allowed, denied, require_license, overrides)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"allowed:Set(String)-instance-method","name":"allowed","abstract":false,"def":{"name":"allowed","return_type":"Set(String)","visibility":"Public","body":"@allowed"},"external_var":false},{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L9"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@allowed.clone, @denied.clone, @require_license.clone, @overrides.clone)"},"external_var":false},{"html_id":"copy_with(allowed_allowed=@allowed,denied_denied=@denied,require_license_require_license=@require_license,overrides_overrides=@overrides)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_allowed","default_value":"@allowed","external_name":"allowed","restriction":""},{"name":"_denied","default_value":"@denied","external_name":"denied","restriction":""},{"name":"_require_license","default_value":"@require_license","external_name":"require_license","restriction":""},{"name":"_overrides","default_value":"@overrides","external_name":"overrides","restriction":""}],"args_string":"(allowed _allowed = @allowed, denied _denied = @denied, require_license _require_license = @require_license, overrides _overrides = @overrides)","args_html":"(allowed _allowed = @allowed, denied _denied = @denied, require_license _require_license = @require_license, overrides _overrides = @overrides)","location":{"filename":"src/license_policy.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L9"},"def":{"name":"copy_with","args":[{"name":"_allowed","default_value":"@allowed","external_name":"allowed","restriction":""},{"name":"_denied","default_value":"@denied","external_name":"denied","restriction":""},{"name":"_require_license","default_value":"@require_license","external_name":"require_license","restriction":""},{"name":"_overrides","default_value":"@overrides","external_name":"overrides","restriction":""}],"visibility":"Public","body":"self.class.new(_allowed, _denied, _require_license, _overrides)"},"external_var":false},{"html_id":"denied:Set(String)-instance-method","name":"denied","abstract":false,"def":{"name":"denied","return_type":"Set(String)","visibility":"Public","body":"@denied"},"external_var":false},{"html_id":"overrides:Hash(String,Override)-instance-method","name":"overrides","abstract":false,"def":{"name":"overrides","return_type":"Hash(String, Override)","visibility":"Public","body":"@overrides"},"external_var":false},{"html_id":"require_license:Bool-instance-method","name":"require_license","abstract":false,"def":{"name":"require_license","return_type":"Bool","visibility":"Public","body":"@require_license"},"external_var":false}]},{"html_id":"Ashard/Shards/LicensePolicy/PolicyReport","path":"Shards/LicensePolicy/PolicyReport.html","kind":"struct","full_name":"Shards::LicensePolicy::PolicyReport","name":"PolicyReport","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_policy.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L40"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/LicensePolicy","kind":"class","full_name":"Shards::LicensePolicy","name":"LicensePolicy"},"constructors":[{"html_id":"new(root_name:String,root_version:String,root_license:String|Nil,dependencies:Array(DependencyResult),policy_used:Bool,summary:Summary)-class-method","name":"new","abstract":false,"args":[{"name":"root_name","external_name":"root_name","restriction":"String"},{"name":"root_version","external_name":"root_version","restriction":"String"},{"name":"root_license","external_name":"root_license","restriction":"String | ::Nil"},{"name":"dependencies","external_name":"dependencies","restriction":"Array(DependencyResult)"},{"name":"policy_used","external_name":"policy_used","restriction":"Bool"},{"name":"summary","external_name":"summary","restriction":"Summary"}],"args_string":"(root_name : String, root_version : String, root_license : String | Nil, dependencies : Array(DependencyResult), policy_used : Bool, summary : Summary)","args_html":"(root_name : String, root_version : String, root_license : String | Nil, dependencies : Array(<a href=\"../../Shards/LicensePolicy/DependencyResult.html\">DependencyResult</a>), policy_used : Bool, summary : <a href=\"../../Shards/LicensePolicy/Summary.html\">Summary</a>)","location":{"filename":"src/license_policy.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L40"},"def":{"name":"new","args":[{"name":"root_name","external_name":"root_name","restriction":"String"},{"name":"root_version","external_name":"root_version","restriction":"String"},{"name":"root_license","external_name":"root_license","restriction":"String | ::Nil"},{"name":"dependencies","external_name":"dependencies","restriction":"Array(DependencyResult)"},{"name":"policy_used","external_name":"policy_used","restriction":"Bool"},{"name":"summary","external_name":"summary","restriction":"Summary"}],"visibility":"Public","body":"_ = allocate\n_.initialize(root_name, root_version, root_license, dependencies, policy_used, summary)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L40"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@root_name.clone, @root_version.clone, @root_license.clone, @dependencies.clone, @policy_used.clone, @summary.clone)"},"external_var":false},{"html_id":"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)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_root_name","default_value":"@root_name","external_name":"root_name","restriction":""},{"name":"_root_version","default_value":"@root_version","external_name":"root_version","restriction":""},{"name":"_root_license","default_value":"@root_license","external_name":"root_license","restriction":""},{"name":"_dependencies","default_value":"@dependencies","external_name":"dependencies","restriction":""},{"name":"_policy_used","default_value":"@policy_used","external_name":"policy_used","restriction":""},{"name":"_summary","default_value":"@summary","external_name":"summary","restriction":""}],"args_string":"(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)","args_html":"(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)","location":{"filename":"src/license_policy.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L40"},"def":{"name":"copy_with","args":[{"name":"_root_name","default_value":"@root_name","external_name":"root_name","restriction":""},{"name":"_root_version","default_value":"@root_version","external_name":"root_version","restriction":""},{"name":"_root_license","default_value":"@root_license","external_name":"root_license","restriction":""},{"name":"_dependencies","default_value":"@dependencies","external_name":"dependencies","restriction":""},{"name":"_policy_used","default_value":"@policy_used","external_name":"policy_used","restriction":""},{"name":"_summary","default_value":"@summary","external_name":"summary","restriction":""}],"visibility":"Public","body":"self.class.new(_root_name, _root_version, _root_license, _dependencies, _policy_used, _summary)"},"external_var":false},{"html_id":"dependencies:Array(DependencyResult)-instance-method","name":"dependencies","abstract":false,"def":{"name":"dependencies","return_type":"Array(DependencyResult)","visibility":"Public","body":"@dependencies"},"external_var":false},{"html_id":"policy_used:Bool-instance-method","name":"policy_used","abstract":false,"def":{"name":"policy_used","return_type":"Bool","visibility":"Public","body":"@policy_used"},"external_var":false},{"html_id":"root_license:String|Nil-instance-method","name":"root_license","abstract":false,"def":{"name":"root_license","return_type":"String | ::Nil","visibility":"Public","body":"@root_license"},"external_var":false},{"html_id":"root_name:String-instance-method","name":"root_name","abstract":false,"def":{"name":"root_name","return_type":"String","visibility":"Public","body":"@root_name"},"external_var":false},{"html_id":"root_version:String-instance-method","name":"root_version","abstract":false,"def":{"name":"root_version","return_type":"String","visibility":"Public","body":"@root_version"},"external_var":false},{"html_id":"summary:Summary-instance-method","name":"summary","abstract":false,"def":{"name":"summary","return_type":"Summary","visibility":"Public","body":"@summary"},"external_var":false}]},{"html_id":"Ashard/Shards/LicensePolicy/Summary","path":"Shards/LicensePolicy/Summary.html","kind":"struct","full_name":"Shards::LicensePolicy::Summary","name":"Summary","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_policy.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L48"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/LicensePolicy","kind":"class","full_name":"Shards::LicensePolicy","name":"LicensePolicy"},"constructors":[{"html_id":"new(total:Int32,allowed:Int32,denied:Int32,unlicensed:Int32,unknown:Int32,overridden:Int32)-class-method","name":"new","abstract":false,"args":[{"name":"total","external_name":"total","restriction":"Int32"},{"name":"allowed","external_name":"allowed","restriction":"Int32"},{"name":"denied","external_name":"denied","restriction":"Int32"},{"name":"unlicensed","external_name":"unlicensed","restriction":"Int32"},{"name":"unknown","external_name":"unknown","restriction":"Int32"},{"name":"overridden","external_name":"overridden","restriction":"Int32"}],"args_string":"(total : Int32, allowed : Int32, denied : Int32, unlicensed : Int32, unknown : Int32, overridden : Int32)","args_html":"(total : Int32, allowed : Int32, denied : Int32, unlicensed : Int32, unknown : Int32, overridden : Int32)","location":{"filename":"src/license_policy.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L48"},"def":{"name":"new","args":[{"name":"total","external_name":"total","restriction":"Int32"},{"name":"allowed","external_name":"allowed","restriction":"Int32"},{"name":"denied","external_name":"denied","restriction":"Int32"},{"name":"unlicensed","external_name":"unlicensed","restriction":"Int32"},{"name":"unknown","external_name":"unknown","restriction":"Int32"},{"name":"overridden","external_name":"overridden","restriction":"Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(total, allowed, denied, unlicensed, unknown, overridden)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"allowed:Int32-instance-method","name":"allowed","abstract":false,"def":{"name":"allowed","return_type":"Int32","visibility":"Public","body":"@allowed"},"external_var":false},{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L48"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@total.clone, @allowed.clone, @denied.clone, @unlicensed.clone, @unknown.clone, @overridden.clone)"},"external_var":false},{"html_id":"copy_with(total_total=@total,allowed_allowed=@allowed,denied_denied=@denied,unlicensed_unlicensed=@unlicensed,unknown_unknown=@unknown,overridden_overridden=@overridden)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_total","default_value":"@total","external_name":"total","restriction":""},{"name":"_allowed","default_value":"@allowed","external_name":"allowed","restriction":""},{"name":"_denied","default_value":"@denied","external_name":"denied","restriction":""},{"name":"_unlicensed","default_value":"@unlicensed","external_name":"unlicensed","restriction":""},{"name":"_unknown","default_value":"@unknown","external_name":"unknown","restriction":""},{"name":"_overridden","default_value":"@overridden","external_name":"overridden","restriction":""}],"args_string":"(total _total = @total, allowed _allowed = @allowed, denied _denied = @denied, unlicensed _unlicensed = @unlicensed, unknown _unknown = @unknown, overridden _overridden = @overridden)","args_html":"(total _total = @total, allowed _allowed = @allowed, denied _denied = @denied, unlicensed _unlicensed = @unlicensed, unknown _unknown = @unknown, overridden _overridden = @overridden)","location":{"filename":"src/license_policy.cr","line_number":48,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L48"},"def":{"name":"copy_with","args":[{"name":"_total","default_value":"@total","external_name":"total","restriction":""},{"name":"_allowed","default_value":"@allowed","external_name":"allowed","restriction":""},{"name":"_denied","default_value":"@denied","external_name":"denied","restriction":""},{"name":"_unlicensed","default_value":"@unlicensed","external_name":"unlicensed","restriction":""},{"name":"_unknown","default_value":"@unknown","external_name":"unknown","restriction":""},{"name":"_overridden","default_value":"@overridden","external_name":"overridden","restriction":""}],"visibility":"Public","body":"self.class.new(_total, _allowed, _denied, _unlicensed, _unknown, _overridden)"},"external_var":false},{"html_id":"denied:Int32-instance-method","name":"denied","abstract":false,"def":{"name":"denied","return_type":"Int32","visibility":"Public","body":"@denied"},"external_var":false},{"html_id":"overridden:Int32-instance-method","name":"overridden","abstract":false,"def":{"name":"overridden","return_type":"Int32","visibility":"Public","body":"@overridden"},"external_var":false},{"html_id":"total:Int32-instance-method","name":"total","abstract":false,"def":{"name":"total","return_type":"Int32","visibility":"Public","body":"@total"},"external_var":false},{"html_id":"unknown:Int32-instance-method","name":"unknown","abstract":false,"def":{"name":"unknown","return_type":"Int32","visibility":"Public","body":"@unknown"},"external_var":false},{"html_id":"unlicensed:Int32-instance-method","name":"unlicensed","abstract":false,"def":{"name":"unlicensed","return_type":"Int32","visibility":"Public","body":"@unlicensed"},"external_var":false}]},{"html_id":"Ashard/Shards/LicensePolicy/Verdict","path":"Shards/LicensePolicy/Verdict.html","kind":"enum","full_name":"Shards::LicensePolicy::Verdict","name":"Verdict","abstract":false,"ancestors":[{"html_id":"Ashard/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"Ashard/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_policy.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L19"}],"repository_name":"Ashard","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"Allowed","name":"Allowed","value":"0"},{"id":"Denied","name":"Denied","value":"1"},{"id":"Unlicensed","name":"Unlicensed","value":"2"},{"id":"Unknown","name":"Unknown","value":"3"},{"id":"Overridden","name":"Overridden","value":"4"}],"namespace":{"html_id":"Ashard/Shards/LicensePolicy","kind":"class","full_name":"Shards::LicensePolicy","name":"LicensePolicy"},"instance_methods":[{"html_id":"allowed?-instance-method","name":"allowed?","doc":"Returns `true` if this enum value equals `Allowed`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LicensePolicy/Verdict.html#Allowed\">Allowed</a></code></p>","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L20"},"def":{"name":"allowed?","visibility":"Public","body":"self == Allowed"},"external_var":false},{"html_id":"denied?-instance-method","name":"denied?","doc":"Returns `true` if this enum value equals `Denied`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LicensePolicy/Verdict.html#Denied\">Denied</a></code></p>","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":21,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L21"},"def":{"name":"denied?","visibility":"Public","body":"self == Denied"},"external_var":false},{"html_id":"overridden?-instance-method","name":"overridden?","doc":"Returns `true` if this enum value equals `Overridden`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LicensePolicy/Verdict.html#Overridden\">Overridden</a></code></p>","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":24,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L24"},"def":{"name":"overridden?","visibility":"Public","body":"self == Overridden"},"external_var":false},{"html_id":"unknown?-instance-method","name":"unknown?","doc":"Returns `true` if this enum value equals `Unknown`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LicensePolicy/Verdict.html#Unknown\">Unknown</a></code></p>","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":23,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L23"},"def":{"name":"unknown?","visibility":"Public","body":"self == Unknown"},"external_var":false},{"html_id":"unlicensed?-instance-method","name":"unlicensed?","doc":"Returns `true` if this enum value equals `Unlicensed`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LicensePolicy/Verdict.html#Unlicensed\">Unlicensed</a></code></p>","abstract":false,"location":{"filename":"src/license_policy.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_policy.cr#L22"},"def":{"name":"unlicensed?","visibility":"Public","body":"self == Unlicensed"},"external_var":false}]}]},{"html_id":"Ashard/Shards/LicenseScanner","path":"Shards/LicenseScanner.html","kind":"class","full_name":"Shards::LicenseScanner","name":"LicenseScanner","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_scanner.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"LICENSE_FILE_PATTERNS","name":"LICENSE_FILE_PATTERNS","value":"[\"LICENSE\", \"LICENSE.md\", \"LICENSE.txt\", \"LICENCE\", \"LICENCE.md\", \"LICENCE.txt\", \"LICENSE-MIT\", \"LICENSE-APACHE\", \"COPYING\", \"COPYING.md\", \"COPYING.txt\"]"},{"id":"LICENSE_PATTERNS","name":"LICENSE_PATTERNS","value":"[{/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\"}]"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"detect_license(content:String):Tuple(String|Nil,Symbol)-class-method","name":"detect_license","abstract":false,"args":[{"name":"content","external_name":"content","restriction":"String"}],"args_string":"(content : String) : Tuple(String | Nil, Symbol)","args_html":"(content : String) : Tuple(String | Nil, Symbol)","location":{"filename":"src/license_scanner.cr","line_number":55,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L55"},"def":{"name":"detect_license","args":[{"name":"content","external_name":"content","restriction":"String"}],"return_type":"::Tuple(String | ::Nil, Symbol)","visibility":"Public","body":"LICENSE_PATTERNS.each do |regex, spdx_id|\n  if content.matches?(regex)\n    return {spdx_id, :high}\n  end\nend\n{nil, :none}\n"},"external_var":false},{"html_id":"find_license_file(dir:String):String|Nil-class-method","name":"find_license_file","abstract":false,"args":[{"name":"dir","external_name":"dir","restriction":"String"}],"args_string":"(dir : String) : String | Nil","args_html":"(dir : String) : String | Nil","location":{"filename":"src/license_scanner.cr","line_number":47,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L47"},"def":{"name":"find_license_file","args":[{"name":"dir","external_name":"dir","restriction":"String"}],"return_type":"String | ::Nil","visibility":"Public","body":"LICENSE_FILE_PATTERNS.each do |pattern|\n  path = File.join(dir, pattern)\n  if File.exists?(path)\n    return path\n  end\nend\nnil\n"},"external_var":false},{"html_id":"scan(install_path:String):ScanResult-class-method","name":"scan","abstract":false,"args":[{"name":"install_path","external_name":"install_path","restriction":"String"}],"args_string":"(install_path : String) : ScanResult","args_html":"(install_path : String) : <a href=\"../Shards/LicenseScanner/ScanResult.html\">ScanResult</a>","location":{"filename":"src/license_scanner.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L32"},"def":{"name":"scan","args":[{"name":"install_path","external_name":"install_path","restriction":"String"}],"return_type":"ScanResult","visibility":"Public","body":"license_file = find_license_file(install_path)\nif license_file\n  content = File.read(license_file)\n  detected, confidence = detect_license(content)\n  ScanResult.new(license_file_path: (Path[license_file].relative_to(install_path)).to_s, detected_license: detected, detection_confidence: confidence)\nelse\n  ScanResult.new(license_file_path: nil, detected_license: nil, detection_confidence: :none)\nend\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/LicenseScanner/ScanResult","path":"Shards/LicenseScanner/ScanResult.html","kind":"struct","full_name":"Shards::LicenseScanner::ScanResult","name":"ScanResult","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/license_scanner.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L27"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/LicenseScanner","kind":"class","full_name":"Shards::LicenseScanner","name":"LicenseScanner"},"constructors":[{"html_id":"new(license_file_path:String|Nil,detected_license:String|Nil,detection_confidence:Symbol)-class-method","name":"new","abstract":false,"args":[{"name":"license_file_path","external_name":"license_file_path","restriction":"String | ::Nil"},{"name":"detected_license","external_name":"detected_license","restriction":"String | ::Nil"},{"name":"detection_confidence","external_name":"detection_confidence","restriction":"Symbol"}],"args_string":"(license_file_path : String | Nil, detected_license : String | Nil, detection_confidence : Symbol)","args_html":"(license_file_path : String | Nil, detected_license : String | Nil, detection_confidence : Symbol)","location":{"filename":"src/license_scanner.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L27"},"def":{"name":"new","args":[{"name":"license_file_path","external_name":"license_file_path","restriction":"String | ::Nil"},{"name":"detected_license","external_name":"detected_license","restriction":"String | ::Nil"},{"name":"detection_confidence","external_name":"detection_confidence","restriction":"Symbol"}],"visibility":"Public","body":"_ = allocate\n_.initialize(license_file_path, detected_license, detection_confidence)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/license_scanner.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L27"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@license_file_path.clone, @detected_license.clone, @detection_confidence.clone)"},"external_var":false},{"html_id":"copy_with(license_file_path_license_file_path=@license_file_path,detected_license_detected_license=@detected_license,detection_confidence_detection_confidence=@detection_confidence)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_license_file_path","default_value":"@license_file_path","external_name":"license_file_path","restriction":""},{"name":"_detected_license","default_value":"@detected_license","external_name":"detected_license","restriction":""},{"name":"_detection_confidence","default_value":"@detection_confidence","external_name":"detection_confidence","restriction":""}],"args_string":"(license_file_path _license_file_path = @license_file_path, detected_license _detected_license = @detected_license, detection_confidence _detection_confidence = @detection_confidence)","args_html":"(license_file_path _license_file_path = @license_file_path, detected_license _detected_license = @detected_license, detection_confidence _detection_confidence = @detection_confidence)","location":{"filename":"src/license_scanner.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/license_scanner.cr#L27"},"def":{"name":"copy_with","args":[{"name":"_license_file_path","default_value":"@license_file_path","external_name":"license_file_path","restriction":""},{"name":"_detected_license","default_value":"@detected_license","external_name":"detected_license","restriction":""},{"name":"_detection_confidence","default_value":"@detection_confidence","external_name":"detection_confidence","restriction":""}],"visibility":"Public","body":"self.class.new(_license_file_path, _detected_license, _detection_confidence)"},"external_var":false},{"html_id":"detected_license:String|Nil-instance-method","name":"detected_license","abstract":false,"def":{"name":"detected_license","return_type":"String | ::Nil","visibility":"Public","body":"@detected_license"},"external_var":false},{"html_id":"detection_confidence:Symbol-instance-method","name":"detection_confidence","abstract":false,"def":{"name":"detection_confidence","return_type":"Symbol","visibility":"Public","body":"@detection_confidence"},"external_var":false},{"html_id":"license_file_path:String|Nil-instance-method","name":"license_file_path","abstract":false,"def":{"name":"license_file_path","return_type":"String | ::Nil","visibility":"Public","body":"@license_file_path"},"external_var":false}]}]},{"html_id":"Ashard/Shards/Lock","path":"Shards/Lock.html","kind":"class","full_name":"Shards::Lock","name":"Lock","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lock.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CURRENT_VERSION","name":"CURRENT_VERSION","value":"\"2.0\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"from_file(path)-class-method","name":"from_file","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""}],"args_string":"(path)","args_html":"(path)","location":{"filename":"src/lock.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L15"},"def":{"name":"from_file","args":[{"name":"path","external_name":"path","restriction":""}],"visibility":"Public","body":"if File.exists?(path)\nelse\n  raise(Error.new(\"Missing #{File.basename(path)}\"))\nend\nfrom_yaml(File.read(path))\n"},"external_var":false},{"html_id":"from_yaml(str)-class-method","name":"from_yaml","abstract":false,"args":[{"name":"str","external_name":"str","restriction":""}],"args_string":"(str)","args_html":"(str)","location":{"filename":"src/lock.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L20"},"def":{"name":"from_yaml","args":[{"name":"str","external_name":"str","restriction":""}],"visibility":"Public","body":"begin\n  shards = [] of Package\n\n  pull = YAML::PullParser.new(str)\n  pull.read_stream do\n    pull.read_document do\n      pull.read_mapping do\n        key, version = pull.read_scalar, pull.read_scalar\n\n        if (key == \"version\") && (version.in?(\"1.0\", \"2.0\"))\n        else\n          raise(InvalidLock.new)\n        end\n\n        case key = pull.read_scalar\n        when \"shards\"\n          pull.each_in_mapping do\n\n\n\n\n            dep = Dependency.from_yaml(pull)\n            if package = dep.as_package?\n              shards << package\n            else\n              Log.warn do \"Lock for shard \\\"#{dep.name}\\\" is invalid\" end\n            end\n          end\n        else\n          pull.raise(\"No such attribute #{key} in lock version #{version}\")\n        end\n\n        Lock.new(version, shards)\n      end\n    end\n  end\nrescue ex : YAML::ParseException\n  raise(Error.new(\"Invalid #{LOCK_FILENAME}. Please delete it and run install again.\"))\nensure\n  if pull\n    pull.close\n  end\nend"},"external_var":false},{"html_id":"write(packages:Array(Package),override_path:String|Nil,path:String)-class-method","name":"write","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"},{"name":"override_path","external_name":"override_path","restriction":"String | ::Nil"},{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(packages : Array(Package), override_path : String | Nil, path : String)","args_html":"(packages : Array(<a href=\"../Shards/Package.html\">Package</a>), override_path : String | Nil, path : String)","location":{"filename":"src/lock.cr","line_number":61,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L61"},"def":{"name":"write","args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"},{"name":"override_path","external_name":"override_path","restriction":"String | ::Nil"},{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"File.open(path, \"w\") do |file|\n  write(packages, override_path, file)\nend"},"external_var":false},{"html_id":"write(packages:Array(Package),override_path:String|Nil,io:IO)-class-method","name":"write","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"},{"name":"override_path","external_name":"override_path","restriction":"String | ::Nil"},{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(packages : Array(Package), override_path : String | Nil, io : IO)","args_html":"(packages : Array(<a href=\"../Shards/Package.html\">Package</a>), override_path : String | Nil, io : IO)","location":{"filename":"src/lock.cr","line_number":67,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L67"},"def":{"name":"write","args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"},{"name":"override_path","external_name":"override_path","restriction":"String | ::Nil"},{"name":"io","external_name":"io","restriction":"IO"}],"visibility":"Public","body":"if packages.any?(&.is_override)\n  io << \"# NOTICE: This lockfile contains some overrides from #{override_path}\\n\"\nend\nio << \"version: #{CURRENT_VERSION}\\n\"\nio << \"shards:\"\n\nif packages.empty?\n  io << \" {}\\n\"\nelse\n  io.puts\n  packages.sort_by!(&.name).each do |package|\n    key = package.resolver.class.key\n\n    ((io << \"  \") << package.name) << \":#{package.is_override ? \" # Overridden\" : nil}\\n\"\n    ((((io << \"    \") << key) << \": \") << package.resolver.source) << '\\n'\n    ((io << \"    version: \") << package.version.value) << '\\n'\n    if checksum = package.checksum\n      ((io << \"    checksum: \") << checksum) << '\\n'\n    end\n    io << '\\n'\n  end\nend\n"},"external_var":false}],"constructors":[{"html_id":"new(version:String,shards:Array(Package))-class-method","name":"new","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"},{"name":"shards","external_name":"shards","restriction":"Array(Package)"}],"args_string":"(version : String, shards : Array(Package))","args_html":"(version : String, shards : Array(<a href=\"../Shards/Package.html\">Package</a>))","location":{"filename":"src/lock.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L12"},"def":{"name":"new","args":[{"name":"version","external_name":"version","restriction":"String"},{"name":"shards","external_name":"shards","restriction":"Array(Package)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(version, shards)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"shards:Array(Package)-instance-method","name":"shards","abstract":false,"location":{"filename":"src/lock.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L8"},"def":{"name":"shards","return_type":"Array(Package)","visibility":"Public","body":"@shards"},"external_var":false},{"html_id":"shards=(shards:Array(Package))-instance-method","name":"shards=","abstract":false,"args":[{"name":"shards","external_name":"shards","restriction":"Array(Package)"}],"args_string":"(shards : Array(Package))","args_html":"(shards : Array(<a href=\"../Shards/Package.html\">Package</a>))","location":{"filename":"src/lock.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L8"},"def":{"name":"shards=","args":[{"name":"shards","external_name":"shards","restriction":"Array(Package)"}],"visibility":"Public","body":"@shards = shards"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/lock.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L7"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/lock.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lock.cr#L7"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"},"external_var":false}]},{"html_id":"Ashard/Shards/LockConflict","path":"Shards/LockConflict.html","kind":"class","full_name":"Shards::LockConflict","name":"LockConflict","abstract":false,"superclass":{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},"ancestors":[{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/errors.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L13"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(message)-class-method","name":"new","abstract":false,"args":[{"name":"message","external_name":"message","restriction":""}],"args_string":"(message)","args_html":"(message)","location":{"filename":"src/errors.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L14"},"def":{"name":"new","args":[{"name":"message","external_name":"message","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(message)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}]},{"html_id":"Ashard/Shards/LockfileDiffer","path":"Shards/LockfileDiffer.html","kind":"class","full_name":"Shards::LockfileDiffer","name":"LockfileDiffer","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lockfile_differ.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"diff(from_packages:Array(Package),to_packages:Array(Package)):Array(Change)-class-method","name":"diff","doc":"Compare two package sets and produce changes","summary":"<p>Compare two package sets and produce changes</p>","abstract":false,"args":[{"name":"from_packages","external_name":"from_packages","restriction":"Array(Package)"},{"name":"to_packages","external_name":"to_packages","restriction":"Array(Package)"}],"args_string":"(from_packages : Array(Package), to_packages : Array(Package)) : Array(Change)","args_html":"(from_packages : Array(<a href=\"../Shards/Package.html\">Package</a>), to_packages : Array(<a href=\"../Shards/Package.html\">Package</a>)) : Array(<a href=\"../Shards/LockfileDiffer/Change.html\">Change</a>)","location":{"filename":"src/lockfile_differ.cr","line_number":26,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L26"},"def":{"name":"diff","args":[{"name":"from_packages","external_name":"from_packages","restriction":"Array(Package)"},{"name":"to_packages","external_name":"to_packages","restriction":"Array(Package)"}],"return_type":"Array(Change)","visibility":"Public","body":"from_map = from_packages.to_h do |p| {p.name, p} end\nto_map = to_packages.to_h do |p| {p.name, p} end\nall_names = (from_map.keys + to_map.keys).uniq\n\nchanges = [] of Change\n\nall_names.each do |name|\n  from_pkg = from_map[name]?\n  to_pkg = to_map[name]?\n\n  if from_pkg.nil? && to_pkg\n    changes << Change.new(name: name, status: Status::Added, from_version: nil, to_version: extract_version(to_pkg.version), from_commit: nil, to_commit: extract_commit(to_pkg.version), from_source: nil, to_source: to_pkg.resolver.source, from_resolver_key: nil, to_resolver_key: to_pkg.resolver.class.key)\n  elsif from_pkg && to_pkg.nil?\n    changes << Change.new(name: name, status: Status::Removed, from_version: extract_version(from_pkg.version), to_version: nil, from_commit: extract_commit(from_pkg.version), to_commit: nil, from_source: from_pkg.resolver.source, to_source: nil, from_resolver_key: from_pkg.resolver.class.key, to_resolver_key: nil)\n  elsif from_pkg && to_pkg\n    from_ver = extract_version(from_pkg.version)\n    to_ver = extract_version(to_pkg.version)\n    from_commit_val = extract_commit(from_pkg.version)\n    to_commit_val = extract_commit(to_pkg.version)\n    from_src = from_pkg.resolver.source\n    to_src = to_pkg.resolver.source\n\n    if (((from_ver == to_ver) && (from_commit_val == to_commit_val)) && (from_src == to_src)) && (from_pkg.resolver.class.key == to_pkg.resolver.class.key)\n      changes << Change.new(name: name, status: Status::Unchanged, from_version: from_ver, to_version: to_ver, from_commit: from_commit_val, to_commit: to_commit_val, from_source: from_src, to_source: to_src, from_resolver_key: from_pkg.resolver.class.key, to_resolver_key: to_pkg.resolver.class.key)\n    else\n      changes << Change.new(name: name, status: Status::Updated, from_version: from_ver, to_version: to_ver, from_commit: from_commit_val, to_commit: to_commit_val, from_source: from_src, to_source: to_src, from_resolver_key: from_pkg.resolver.class.key, to_resolver_key: to_pkg.resolver.class.key)\n    end\n  end\nend\n\n\nchanges.sort_by! do |c| {c.status.value, c.name} end\nchanges\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/LockfileDiffer/Change","path":"Shards/LockfileDiffer/Change.html","kind":"struct","full_name":"Shards::LockfileDiffer::Change","name":"Change","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lockfile_differ.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/LockfileDiffer","kind":"class","full_name":"Shards::LockfileDiffer","name":"LockfileDiffer"},"constructors":[{"html_id":"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)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"status","external_name":"status","restriction":"Status"},{"name":"from_version","external_name":"from_version","restriction":"String | ::Nil"},{"name":"to_version","external_name":"to_version","restriction":"String | ::Nil"},{"name":"from_commit","external_name":"from_commit","restriction":"String | ::Nil"},{"name":"to_commit","external_name":"to_commit","restriction":"String | ::Nil"},{"name":"from_source","external_name":"from_source","restriction":"String | ::Nil"},{"name":"to_source","external_name":"to_source","restriction":"String | ::Nil"},{"name":"from_resolver_key","external_name":"from_resolver_key","restriction":"String | ::Nil"},{"name":"to_resolver_key","external_name":"to_resolver_key","restriction":"String | ::Nil"}],"args_string":"(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)","args_html":"(name : String, status : <a href=\"../../Shards/LockfileDiffer/Status.html\">Status</a>, 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)","location":{"filename":"src/lockfile_differ.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L6"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"status","external_name":"status","restriction":"Status"},{"name":"from_version","external_name":"from_version","restriction":"String | ::Nil"},{"name":"to_version","external_name":"to_version","restriction":"String | ::Nil"},{"name":"from_commit","external_name":"from_commit","restriction":"String | ::Nil"},{"name":"to_commit","external_name":"to_commit","restriction":"String | ::Nil"},{"name":"from_source","external_name":"from_source","restriction":"String | ::Nil"},{"name":"to_source","external_name":"to_source","restriction":"String | ::Nil"},{"name":"from_resolver_key","external_name":"from_resolver_key","restriction":"String | ::Nil"},{"name":"to_resolver_key","external_name":"to_resolver_key","restriction":"String | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, status, from_version, to_version, from_commit, to_commit, from_source, to_source, from_resolver_key, to_resolver_key)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/lockfile_differ.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L6"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@name.clone, @status.clone, @from_version.clone, @to_version.clone, @from_commit.clone, @to_commit.clone, @from_source.clone, @to_source.clone, @from_resolver_key.clone, @to_resolver_key.clone)"},"external_var":false},{"html_id":"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)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_name","default_value":"@name","external_name":"name","restriction":""},{"name":"_status","default_value":"@status","external_name":"status","restriction":""},{"name":"_from_version","default_value":"@from_version","external_name":"from_version","restriction":""},{"name":"_to_version","default_value":"@to_version","external_name":"to_version","restriction":""},{"name":"_from_commit","default_value":"@from_commit","external_name":"from_commit","restriction":""},{"name":"_to_commit","default_value":"@to_commit","external_name":"to_commit","restriction":""},{"name":"_from_source","default_value":"@from_source","external_name":"from_source","restriction":""},{"name":"_to_source","default_value":"@to_source","external_name":"to_source","restriction":""},{"name":"_from_resolver_key","default_value":"@from_resolver_key","external_name":"from_resolver_key","restriction":""},{"name":"_to_resolver_key","default_value":"@to_resolver_key","external_name":"to_resolver_key","restriction":""}],"args_string":"(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)","args_html":"(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)","location":{"filename":"src/lockfile_differ.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L6"},"def":{"name":"copy_with","args":[{"name":"_name","default_value":"@name","external_name":"name","restriction":""},{"name":"_status","default_value":"@status","external_name":"status","restriction":""},{"name":"_from_version","default_value":"@from_version","external_name":"from_version","restriction":""},{"name":"_to_version","default_value":"@to_version","external_name":"to_version","restriction":""},{"name":"_from_commit","default_value":"@from_commit","external_name":"from_commit","restriction":""},{"name":"_to_commit","default_value":"@to_commit","external_name":"to_commit","restriction":""},{"name":"_from_source","default_value":"@from_source","external_name":"from_source","restriction":""},{"name":"_to_source","default_value":"@to_source","external_name":"to_source","restriction":""},{"name":"_from_resolver_key","default_value":"@from_resolver_key","external_name":"from_resolver_key","restriction":""},{"name":"_to_resolver_key","default_value":"@to_resolver_key","external_name":"to_resolver_key","restriction":""}],"visibility":"Public","body":"self.class.new(_name, _status, _from_version, _to_version, _from_commit, _to_commit, _from_source, _to_source, _from_resolver_key, _to_resolver_key)"},"external_var":false},{"html_id":"from_commit:String|Nil-instance-method","name":"from_commit","abstract":false,"def":{"name":"from_commit","return_type":"String | ::Nil","visibility":"Public","body":"@from_commit"},"external_var":false},{"html_id":"from_resolver_key:String|Nil-instance-method","name":"from_resolver_key","abstract":false,"def":{"name":"from_resolver_key","return_type":"String | ::Nil","visibility":"Public","body":"@from_resolver_key"},"external_var":false},{"html_id":"from_source:String|Nil-instance-method","name":"from_source","abstract":false,"def":{"name":"from_source","return_type":"String | ::Nil","visibility":"Public","body":"@from_source"},"external_var":false},{"html_id":"from_version:String|Nil-instance-method","name":"from_version","abstract":false,"def":{"name":"from_version","return_type":"String | ::Nil","visibility":"Public","body":"@from_version"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"status:Status-instance-method","name":"status","abstract":false,"def":{"name":"status","return_type":"Status","visibility":"Public","body":"@status"},"external_var":false},{"html_id":"to_commit:String|Nil-instance-method","name":"to_commit","abstract":false,"def":{"name":"to_commit","return_type":"String | ::Nil","visibility":"Public","body":"@to_commit"},"external_var":false},{"html_id":"to_resolver_key:String|Nil-instance-method","name":"to_resolver_key","abstract":false,"def":{"name":"to_resolver_key","return_type":"String | ::Nil","visibility":"Public","body":"@to_resolver_key"},"external_var":false},{"html_id":"to_source:String|Nil-instance-method","name":"to_source","abstract":false,"def":{"name":"to_source","return_type":"String | ::Nil","visibility":"Public","body":"@to_source"},"external_var":false},{"html_id":"to_version:String|Nil-instance-method","name":"to_version","abstract":false,"def":{"name":"to_version","return_type":"String | ::Nil","visibility":"Public","body":"@to_version"},"external_var":false}]},{"html_id":"Ashard/Shards/LockfileDiffer/Status","path":"Shards/LockfileDiffer/Status.html","kind":"enum","full_name":"Shards::LockfileDiffer::Status","name":"Status","abstract":false,"ancestors":[{"html_id":"Ashard/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"Ashard/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lockfile_differ.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L18"}],"repository_name":"Ashard","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"Added","name":"Added","value":"0"},{"id":"Updated","name":"Updated","value":"1"},{"id":"Removed","name":"Removed","value":"2"},{"id":"Unchanged","name":"Unchanged","value":"3"}],"namespace":{"html_id":"Ashard/Shards/LockfileDiffer","kind":"class","full_name":"Shards::LockfileDiffer","name":"LockfileDiffer"},"instance_methods":[{"html_id":"added?-instance-method","name":"added?","doc":"Returns `true` if this enum value equals `Added`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LockfileDiffer/Status.html#Added\">Added</a></code></p>","abstract":false,"location":{"filename":"src/lockfile_differ.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L19"},"def":{"name":"added?","visibility":"Public","body":"self == Added"},"external_var":false},{"html_id":"removed?-instance-method","name":"removed?","doc":"Returns `true` if this enum value equals `Removed`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LockfileDiffer/Status.html#Removed\">Removed</a></code></p>","abstract":false,"location":{"filename":"src/lockfile_differ.cr","line_number":21,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L21"},"def":{"name":"removed?","visibility":"Public","body":"self == Removed"},"external_var":false},{"html_id":"unchanged?-instance-method","name":"unchanged?","doc":"Returns `true` if this enum value equals `Unchanged`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LockfileDiffer/Status.html#Unchanged\">Unchanged</a></code></p>","abstract":false,"location":{"filename":"src/lockfile_differ.cr","line_number":22,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L22"},"def":{"name":"unchanged?","visibility":"Public","body":"self == Unchanged"},"external_var":false},{"html_id":"updated?-instance-method","name":"updated?","doc":"Returns `true` if this enum value equals `Updated`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/LockfileDiffer/Status.html#Updated\">Updated</a></code></p>","abstract":false,"location":{"filename":"src/lockfile_differ.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/lockfile_differ.cr#L20"},"def":{"name":"updated?","visibility":"Public","body":"self == Updated"},"external_var":false}]}]},{"html_id":"Ashard/Shards/MCPManager","path":"Shards/MCPManager.html","kind":"class","full_name":"Shards::MCPManager","name":"MCPManager","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/mcp_manager.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L4"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"BIN_DIR","name":"BIN_DIR","value":"\"bin\""},{"id":"Log","name":"Log","value":"::Log.for(\"shards.mcp\")"},{"id":"MCP_SHARDS_CONFIG","name":"MCP_SHARDS_CONFIG","value":"\".mcp-shards.json\""},{"id":"RUNTIME_DIR","name":"RUNTIME_DIR","value":"\".shards/mcp\""},{"id":"STATE_FILE","name":"STATE_FILE","value":"\"servers.json\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(path:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/mcp_manager.cr","line_number":52,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L52"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"load_configs:Array(ServerConfig)-instance-method","name":"load_configs","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":193,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L193"},"def":{"name":"load_configs","return_type":"Array(ServerConfig)","visibility":"Public","body":"config_path = File.join(path, MCP_SHARDS_CONFIG)\nif File.exists?(config_path)\nelse\n  return [] of ServerConfig\nend\n\njson = JSON.parse(File.read(config_path))\nservers = json[\"mcpServers\"]?.try(&.as_h?) || (return [] of ServerConfig)\n\nservers.compact_map do |name, entry|\n  h = entry.as_h? || (next)\n\n  command = h[\"command\"]?.try(&.as_s?)\n  crystal_main = h[\"crystal_main\"]?.try(&.as_s?)\n  if command || crystal_main\n  else\n    next\n  end\n\n  args = h[\"args\"]?.try() do |__arg3| __arg3.as_a?.try(&.map(&.as_s)) end || ([] of String)\n\n  transport = if (h[\"transport\"]?.try(&.as_s?) == \"sse\") || h[\"url\"]?\n    \"sse\"\n  else\n    \"stdio\"\n  end\n\n  env = {} of String => String\n  if env_hash = h[\"env\"]?.try(&.as_h?)\n    env_hash.each do |k, v|\n      env[k] = v.as_s? || v.to_s\n    end\n  end\n\n  ServerConfig.new(name, command, args, crystal_main, transport, env)\nend\n"},"external_var":false},{"html_id":"logs(name:String,follow:Bool=true,lines:Int32=20)-instance-method","name":"logs","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"follow","default_value":"true","external_name":"follow","restriction":"Bool"},{"name":"lines","default_value":"20","external_name":"lines","restriction":"Int32"}],"args_string":"(name : String, follow : Bool = true, lines : Int32 = 20)","args_html":"(name : String, follow : Bool = <span class=\"n\">true</span>, lines : Int32 = <span class=\"n\">20</span>)","location":{"filename":"src/mcp_manager.cr","line_number":159,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L159"},"def":{"name":"logs","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"follow","default_value":"true","external_name":"follow","restriction":"Bool"},{"name":"lines","default_value":"20","external_name":"lines","restriction":"Int32"}],"visibility":"Public","body":"configs = load_configs\nif configs.empty?\n  raise(Error.new(\"No MCP servers configured.\"))\nend\n\nconfig = resolve_single(configs, name)\nkey = sanitize_name(config.name)\nlog_path = File.join(path, RUNTIME_DIR, \"#{key}.log\")\n\nif File.exists?(log_path)\nelse\n  raise(Error.new(\"No log file found for #{config.name}. Has the server been started?\"))\nend\n\nprint_last_lines(log_path, lines)\n\nif follow\n  last_size = File.size(log_path)\n  loop do\n    sleep(0.5.seconds)\n    current_size = File.size(log_path)\n    if current_size > last_size\n      File.open(log_path) do |f|\n        f.seek(last_size)\n        while line = f.gets\n          puts(line)\n        end\n      end\n      last_size = current_size\n    end\n  end\nend\n"},"external_var":false},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":50,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L50"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"@path"},"external_var":false},{"html_id":"restart(name:String|Nil=nil)-instance-method","name":"restart","abstract":false,"args":[{"name":"name","default_value":"nil","external_name":"name","restriction":"String | ::Nil"}],"args_string":"(name : String | Nil = nil)","args_html":"(name : String | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/mcp_manager.cr","line_number":101,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L101"},"def":{"name":"restart","args":[{"name":"name","default_value":"nil","external_name":"name","restriction":"String | ::Nil"}],"visibility":"Public","body":"configs = load_configs\nif configs.empty?\n  raise(Error.new(\"No MCP servers configured. Ensure .mcp-shards.json exists.\"))\nend\n\ntargets = resolve_targets(configs, name)\nstate = load_state\n\ntargets.each do |config|\n  key = sanitize_name(config.name)\n  if entry = state.servers[key]?\n    stop_server(entry)\n    state.servers.delete(key)\n  end\n\n  start_server(config, state)\nend\n\nsave_state(state)\n"},"external_var":false},{"html_id":"sanitize_name(name:String):String-instance-method","name":"sanitize_name","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String) : String","args_html":"(name : String) : String","location":{"filename":"src/mcp_manager.cr","line_number":425,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L425"},"def":{"name":"sanitize_name","args":[{"name":"name","external_name":"name","restriction":"String"}],"return_type":"String","visibility":"Public","body":"name.gsub(\"/\", \"--\")"},"external_var":false},{"html_id":"start(name:String|Nil=nil)-instance-method","name":"start","abstract":false,"args":[{"name":"name","default_value":"nil","external_name":"name","restriction":"String | ::Nil"}],"args_string":"(name : String | Nil = nil)","args_html":"(name : String | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/mcp_manager.cr","line_number":55,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L55"},"def":{"name":"start","args":[{"name":"name","default_value":"nil","external_name":"name","restriction":"String | ::Nil"}],"visibility":"Public","body":"configs = load_configs\nif configs.empty?\n  raise(Error.new(\"No MCP servers configured. Ensure .mcp-shards.json exists.\"))\nend\n\ntargets = resolve_targets(configs, name)\nstate = load_state\n\ntargets.each do |config|\n  key = sanitize_name(config.name)\n  if existing = state.servers[key]?\n    if process_alive?(existing.pid)\n      Log.info do \"Server #{config.name} is already running (PID #{existing.pid})\" end\n      next\n    end\n\n    state.servers.delete(key)\n  end\n\n  start_server(config, state)\nend\n\nsave_state(state)\n"},"external_var":false},{"html_id":"status:Array(ServerStatusInfo)-instance-method","name":"status","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":132,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L132"},"def":{"name":"status","return_type":"Array(ServerStatusInfo)","visibility":"Public","body":"configs = load_configs\nif configs.empty?\n  return [] of ServerStatusInfo\nend\n\nstate = load_state\nstale_cleaned = false\n\nresults = configs.map do |config|\n  key = sanitize_name(config.name)\n  if entry = state.servers[key]?\n    if process_alive?(entry.pid)\n      started = begin\n        Time.parse_iso8601(entry.started_at)\n      rescue\n        nil\n      end\n      ServerStatusInfo.new(config.name, true, entry.pid, entry.transport, started)\n    else\n      state.servers.delete(key)\n      stale_cleaned = true\n      ServerStatusInfo.new(config.name, false, nil, config.transport, nil)\n    end\n  else\n    ServerStatusInfo.new(config.name, false, nil, config.transport, nil)\n  end\nend\n\nif stale_cleaned\n  save_state(state)\nend\nresults\n"},"external_var":false},{"html_id":"stop(name:String|Nil=nil)-instance-method","name":"stop","abstract":false,"args":[{"name":"name","default_value":"nil","external_name":"name","restriction":"String | ::Nil"}],"args_string":"(name : String | Nil = nil)","args_html":"(name : String | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/mcp_manager.cr","line_number":79,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L79"},"def":{"name":"stop","args":[{"name":"name","default_value":"nil","external_name":"name","restriction":"String | ::Nil"}],"visibility":"Public","body":"configs = load_configs\nif configs.empty?\n  raise(Error.new(\"No MCP servers configured. Ensure .mcp-shards.json exists.\"))\nend\n\ntargets = resolve_targets(configs, name)\nstate = load_state\n\ntargets.each do |config|\n  key = sanitize_name(config.name)\n  entry = state.servers[key]?\n  if entry\n  else\n    Log.info do \"Server #{config.name} is not running\" end\n    next\n  end\n\n  stop_server(entry)\n  state.servers.delete(key)\nend\n\nsave_state(state)\n"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/MCPManager/ServerConfig","path":"Shards/MCPManager/ServerConfig.html","kind":"struct","full_name":"Shards::MCPManager::ServerConfig","name":"ServerConfig","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/mcp_manager.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L12"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/MCPManager","kind":"class","full_name":"Shards::MCPManager","name":"MCPManager"},"constructors":[{"html_id":"new(name:String,command:Nil|String,args:Array(String),crystal_main:Nil|String,transport:String,env:Hash(String,String))-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"command","external_name":"command","restriction":"::Nil | ::String"},{"name":"args","external_name":"args","restriction":"::Array(::String)"},{"name":"crystal_main","external_name":"crystal_main","restriction":"::Nil | ::String"},{"name":"transport","external_name":"transport","restriction":"::String"},{"name":"env","external_name":"env","restriction":"::Hash(::String, ::String)"}],"args_string":"(name : String, command : Nil | String, args : Array(String), crystal_main : Nil | String, transport : String, env : Hash(String, String))","args_html":"(name : String, command : Nil | String, args : Array(String), crystal_main : Nil | String, transport : String, env : Hash(String, String))","location":{"filename":"src/mcp_manager.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L20"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"command","external_name":"command","restriction":"::Nil | ::String"},{"name":"args","external_name":"args","restriction":"::Array(::String)"},{"name":"crystal_main","external_name":"crystal_main","restriction":"::Nil | ::String"},{"name":"transport","external_name":"transport","restriction":"::String"},{"name":"env","external_name":"env","restriction":"::Hash(::String, ::String)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, command, args, crystal_main, transport, env)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"args:Array(String)-instance-method","name":"args","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L15"},"def":{"name":"args","return_type":"Array(String)","visibility":"Public","body":"@args"},"external_var":false},{"html_id":"command:String|Nil-instance-method","name":"command","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L14"},"def":{"name":"command","return_type":"String | ::Nil","visibility":"Public","body":"@command"},"external_var":false},{"html_id":"crystal_main:String|Nil-instance-method","name":"crystal_main","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L16"},"def":{"name":"crystal_main","return_type":"String | ::Nil","visibility":"Public","body":"@crystal_main"},"external_var":false},{"html_id":"env:Hash(String,String)-instance-method","name":"env","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L18"},"def":{"name":"env","return_type":"Hash(String, String)","visibility":"Public","body":"@env"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L13"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"transport:String-instance-method","name":"transport","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L17"},"def":{"name":"transport","return_type":"String","visibility":"Public","body":"@transport"},"external_var":false}]},{"html_id":"Ashard/Shards/MCPManager/ServerState","path":"Shards/MCPManager/ServerState.html","kind":"struct","full_name":"Shards::MCPManager::ServerState","name":"ServerState","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/mcp_manager.cr","line_number":24,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L24"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"Ashard/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"Ashard/Shards/MCPManager","kind":"class","full_name":"Shards::MCPManager","name":"MCPManager"},"constructors":[{"html_id":"new(name:String,pid:Int64,transport:String,port:Int32|Nil,log_file:String,command:String,args:Array(String),started_at:String)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"pid","external_name":"pid","restriction":"::Int64"},{"name":"transport","external_name":"transport","restriction":"::String"},{"name":"port","external_name":"port","restriction":"::Int32 | ::Nil"},{"name":"log_file","external_name":"log_file","restriction":"::String"},{"name":"command","external_name":"command","restriction":"::String"},{"name":"args","external_name":"args","restriction":"::Array(::String)"},{"name":"started_at","external_name":"started_at","restriction":"::String"}],"args_string":"(name : String, pid : Int64, transport : String, port : Int32 | Nil, log_file : String, command : String, args : Array(String), started_at : String)","args_html":"(name : String, pid : Int64, transport : String, port : Int32 | Nil, log_file : String, command : String, args : Array(String), started_at : String)","location":{"filename":"src/mcp_manager.cr","line_number":36,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L36"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"pid","external_name":"pid","restriction":"::Int64"},{"name":"transport","external_name":"transport","restriction":"::String"},{"name":"port","external_name":"port","restriction":"::Int32 | ::Nil"},{"name":"log_file","external_name":"log_file","restriction":"::String"},{"name":"command","external_name":"command","restriction":"::String"},{"name":"args","external_name":"args","restriction":"::Array(::String)"},{"name":"started_at","external_name":"started_at","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, pid, transport, port, log_file, command, args, started_at)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false},{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/mcp_manager.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L25"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"},"external_var":false},{"html_id":"new(*,__pull_for_json_serializablepull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"","external_name":"","restriction":""},{"name":"pull","external_name":"__pull_for_json_serializable","restriction":"::JSON::PullParser"}],"args_string":"(*, __pull_for_json_serializable pull : JSON::PullParser)","args_html":"(*, __pull_for_json_serializable pull : JSON::PullParser)","location":{"filename":"src/mcp_manager.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L25"},"def":{"name":"new","args":[{"name":"","external_name":"","restriction":""},{"name":"pull","external_name":"__pull_for_json_serializable","restriction":"::JSON::PullParser"}],"splat_index":0,"visibility":"Public","body":"_ = allocate\n_.initialize(__pull_for_json_serializable: pull)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"args:Array(String)-instance-method","name":"args","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L33"},"def":{"name":"args","return_type":"Array(String)","visibility":"Public","body":"@args"},"external_var":false},{"html_id":"args=(args:Array(String))-instance-method","name":"args=","abstract":false,"args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"args_string":"(args : Array(String))","args_html":"(args : Array(String))","location":{"filename":"src/mcp_manager.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L33"},"def":{"name":"args=","args":[{"name":"args","external_name":"args","restriction":"Array(String)"}],"visibility":"Public","body":"@args = args"},"external_var":false},{"html_id":"command:String-instance-method","name":"command","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L32"},"def":{"name":"command","return_type":"String","visibility":"Public","body":"@command"},"external_var":false},{"html_id":"command=(command:String)-instance-method","name":"command=","abstract":false,"args":[{"name":"command","external_name":"command","restriction":"String"}],"args_string":"(command : String)","args_html":"(command : String)","location":{"filename":"src/mcp_manager.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L32"},"def":{"name":"command=","args":[{"name":"command","external_name":"command","restriction":"String"}],"visibility":"Public","body":"@command = command"},"external_var":false},{"html_id":"log_file:String-instance-method","name":"log_file","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L31"},"def":{"name":"log_file","return_type":"String","visibility":"Public","body":"@log_file"},"external_var":false},{"html_id":"log_file=(log_file:String)-instance-method","name":"log_file=","abstract":false,"args":[{"name":"log_file","external_name":"log_file","restriction":"String"}],"args_string":"(log_file : String)","args_html":"(log_file : String)","location":{"filename":"src/mcp_manager.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L31"},"def":{"name":"log_file=","args":[{"name":"log_file","external_name":"log_file","restriction":"String"}],"visibility":"Public","body":"@log_file = log_file"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L27"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/mcp_manager.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L27"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"},"external_var":false},{"html_id":"pid:Int64-instance-method","name":"pid","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L28"},"def":{"name":"pid","return_type":"Int64","visibility":"Public","body":"@pid"},"external_var":false},{"html_id":"pid=(pid:Int64)-instance-method","name":"pid=","abstract":false,"args":[{"name":"pid","external_name":"pid","restriction":"Int64"}],"args_string":"(pid : Int64)","args_html":"(pid : Int64)","location":{"filename":"src/mcp_manager.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L28"},"def":{"name":"pid=","args":[{"name":"pid","external_name":"pid","restriction":"Int64"}],"visibility":"Public","body":"@pid = pid"},"external_var":false},{"html_id":"port:Int32|Nil-instance-method","name":"port","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L30"},"def":{"name":"port","return_type":"Int32 | ::Nil","visibility":"Public","body":"@port"},"external_var":false},{"html_id":"port=(port:Int32|Nil)-instance-method","name":"port=","abstract":false,"args":[{"name":"port","external_name":"port","restriction":"Int32 | ::Nil"}],"args_string":"(port : Int32 | Nil)","args_html":"(port : Int32 | Nil)","location":{"filename":"src/mcp_manager.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L30"},"def":{"name":"port=","args":[{"name":"port","external_name":"port","restriction":"Int32 | ::Nil"}],"visibility":"Public","body":"@port = port"},"external_var":false},{"html_id":"started_at:String-instance-method","name":"started_at","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":34,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L34"},"def":{"name":"started_at","return_type":"String","visibility":"Public","body":"@started_at"},"external_var":false},{"html_id":"started_at=(started_at:String)-instance-method","name":"started_at=","abstract":false,"args":[{"name":"started_at","external_name":"started_at","restriction":"String"}],"args_string":"(started_at : String)","args_html":"(started_at : String)","location":{"filename":"src/mcp_manager.cr","line_number":34,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L34"},"def":{"name":"started_at=","args":[{"name":"started_at","external_name":"started_at","restriction":"String"}],"visibility":"Public","body":"@started_at = started_at"},"external_var":false},{"html_id":"transport:String-instance-method","name":"transport","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L29"},"def":{"name":"transport","return_type":"String","visibility":"Public","body":"@transport"},"external_var":false},{"html_id":"transport=(transport:String)-instance-method","name":"transport=","abstract":false,"args":[{"name":"transport","external_name":"transport","restriction":"String"}],"args_string":"(transport : String)","args_html":"(transport : String)","location":{"filename":"src/mcp_manager.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L29"},"def":{"name":"transport=","args":[{"name":"transport","external_name":"transport","restriction":"String"}],"visibility":"Public","body":"@transport = transport"},"external_var":false}]},{"html_id":"Ashard/Shards/MCPManager/ServerStatusInfo","path":"Shards/MCPManager/ServerStatusInfo.html","kind":"struct","full_name":"Shards::MCPManager::ServerStatusInfo","name":"ServerStatusInfo","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/mcp_manager.cr","line_number":121,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L121"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/MCPManager","kind":"class","full_name":"Shards::MCPManager","name":"MCPManager"},"constructors":[{"html_id":"new(name:String,running:Bool,pid:Int64|Nil,transport:String,started_at:Time|Nil)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"running","external_name":"running","restriction":"::Bool"},{"name":"pid","external_name":"pid","restriction":"::Int64 | ::Nil"},{"name":"transport","external_name":"transport","restriction":"::String"},{"name":"started_at","external_name":"started_at","restriction":"::Time | ::Nil"}],"args_string":"(name : String, running : Bool, pid : Int64 | Nil, transport : String, started_at : Time | Nil)","args_html":"(name : String, running : Bool, pid : Int64 | Nil, transport : String, started_at : Time | Nil)","location":{"filename":"src/mcp_manager.cr","line_number":128,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L128"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"running","external_name":"running","restriction":"::Bool"},{"name":"pid","external_name":"pid","restriction":"::Int64 | ::Nil"},{"name":"transport","external_name":"transport","restriction":"::String"},{"name":"started_at","external_name":"started_at","restriction":"::Time | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, running, pid, transport, started_at)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":122,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L122"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"pid:Int64|Nil-instance-method","name":"pid","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":124,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L124"},"def":{"name":"pid","return_type":"Int64 | ::Nil","visibility":"Public","body":"@pid"},"external_var":false},{"html_id":"running:Bool-instance-method","name":"running","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":123,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L123"},"def":{"name":"running","return_type":"Bool","visibility":"Public","body":"@running"},"external_var":false},{"html_id":"started_at:Time|Nil-instance-method","name":"started_at","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":126,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L126"},"def":{"name":"started_at","return_type":"Time | ::Nil","visibility":"Public","body":"@started_at"},"external_var":false},{"html_id":"transport:String-instance-method","name":"transport","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":125,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L125"},"def":{"name":"transport","return_type":"String","visibility":"Public","body":"@transport"},"external_var":false}]},{"html_id":"Ashard/Shards/MCPManager/StateFile","path":"Shards/MCPManager/StateFile.html","kind":"struct","full_name":"Shards::MCPManager::StateFile","name":"StateFile","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/mcp_manager.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L40"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"Ashard/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"Ashard/Shards/MCPManager","kind":"class","full_name":"Shards::MCPManager","name":"MCPManager"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/mcp_manager.cr","line_number":41,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L41"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"},"external_var":false},{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":46,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L46"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false},{"html_id":"new(*,__pull_for_json_serializablepull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"","external_name":"","restriction":""},{"name":"pull","external_name":"__pull_for_json_serializable","restriction":"::JSON::PullParser"}],"args_string":"(*, __pull_for_json_serializable pull : JSON::PullParser)","args_html":"(*, __pull_for_json_serializable pull : JSON::PullParser)","location":{"filename":"src/mcp_manager.cr","line_number":41,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L41"},"def":{"name":"new","args":[{"name":"","external_name":"","restriction":""},{"name":"pull","external_name":"__pull_for_json_serializable","restriction":"::JSON::PullParser"}],"splat_index":0,"visibility":"Public","body":"_ = allocate\n_.initialize(__pull_for_json_serializable: pull)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"servers:Hash(String,ServerState)-instance-method","name":"servers","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L44"},"def":{"name":"servers","return_type":"Hash(String, ServerState)","visibility":"Public","body":"@servers"},"external_var":false},{"html_id":"servers=(servers:Hash(String,ServerState))-instance-method","name":"servers=","abstract":false,"args":[{"name":"servers","external_name":"servers","restriction":"Hash(String, ServerState)"}],"args_string":"(servers : Hash(String, ServerState))","args_html":"(servers : Hash(String, <a href=\"../../Shards/MCPManager/ServerState.html\">ServerState</a>))","location":{"filename":"src/mcp_manager.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L44"},"def":{"name":"servers=","args":[{"name":"servers","external_name":"servers","restriction":"Hash(String, ServerState)"}],"visibility":"Public","body":"@servers = servers"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/mcp_manager.cr","line_number":43,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L43"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/mcp_manager.cr","line_number":43,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/mcp_manager.cr#L43"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"},"external_var":false}]}]},{"html_id":"Ashard/Shards/MolinilloSolver","path":"Shards/MolinilloSolver.html","kind":"class","full_name":"Shards::MolinilloSolver","name":"MolinilloSolver","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Molinillo/UI","kind":"module","full_name":"Molinillo::UI","name":"UI"},{"html_id":"Ashard/Molinillo/SpecificationProvider","kind":"module","full_name":"Molinillo::SpecificationProvider","name":"SpecificationProvider"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/molinillo_solver.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"Ashard/Molinillo/SpecificationProvider","kind":"module","full_name":"Molinillo::SpecificationProvider","name":"SpecificationProvider"},{"html_id":"Ashard/Molinillo/UI","kind":"module","full_name":"Molinillo::UI","name":"UI"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"crystal_version_req(specification:Shards::Spec)-class-method","name":"crystal_version_req","abstract":false,"args":[{"name":"specification","external_name":"specification","restriction":"Shards::Spec"}],"args_string":"(specification : Shards::Spec)","args_html":"(specification : <a href=\"../Shards/Spec.html\">Shards::Spec</a>)","location":{"filename":"src/molinillo_solver.cr","line_number":219,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L219"},"def":{"name":"crystal_version_req","args":[{"name":"specification","external_name":"specification","restriction":"Shards::Spec"}],"visibility":"Public","body":"crystal_pattern = if crystal_version = specification.crystal\n  if crystal_version =~ (/^\\d+\\.\\d+(\\.\\d+)?$/)\n    \">= #{crystal_version}\"\n  else\n    crystal_version\n  end\nelse\n  \"*\"\nend\n\nVersionReq.new(crystal_pattern)\n"},"external_var":false}],"constructors":[{"html_id":"new(spec:Spec,override:Override|Nil=nil,*,prereleases:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"spec","external_name":"spec","restriction":"Spec"},{"name":"override","default_value":"nil","external_name":"override","restriction":"Override | ::Nil"},{"name":"","external_name":"","restriction":""},{"name":"prereleases","default_value":"false","external_name":"prereleases","restriction":"::Bool"}],"args_string":"(spec : Spec, override : Override | Nil = nil, *, prereleases : Bool = false)","args_html":"(spec : <a href=\"../Shards/Spec.html\">Spec</a>, override : <a href=\"../Shards/Override.html\">Override</a> | Nil = <span class=\"n\">nil</span>, *, prereleases : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/molinillo_solver.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L13"},"def":{"name":"new","args":[{"name":"spec","external_name":"spec","restriction":"Spec"},{"name":"override","default_value":"nil","external_name":"override","restriction":"Override | ::Nil"},{"name":"","external_name":"","restriction":""},{"name":"prereleases","default_value":"false","external_name":"prereleases","restriction":"::Bool"}],"splat_index":2,"visibility":"Public","body":"_ = allocate\n_.initialize(spec, override, prereleases: prereleases)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"after_resolution-instance-method","name":"after_resolution","doc":"Called after resolution ends (either successfully or with an error).\nBy default, prints a newline.\n\n@return [void]","summary":"<p>Called after resolution ends (either successfully or with an error).</p>","abstract":false,"location":{"filename":"src/molinillo_solver.cr","line_number":262,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L262"},"def":{"name":"after_resolution","visibility":"Public","body":""},"external_var":false},{"html_id":"apply_overrides(deps:Array(Dependency))-instance-method","name":"apply_overrides","abstract":false,"args":[{"name":"deps","external_name":"deps","restriction":"Array(Dependency)"}],"args_string":"(deps : Array(Dependency))","args_html":"(deps : Array(<a href=\"../Shards/Dependency.html\">Dependency</a>))","location":{"filename":"src/molinillo_solver.cr","line_number":203,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L203"},"def":{"name":"apply_overrides","args":[{"name":"deps","external_name":"deps","restriction":"Array(Dependency)"}],"visibility":"Public","body":"deps.map do |dep| (on_override(dep)) || dep end"},"external_var":false},{"html_id":"before_resolution-instance-method","name":"before_resolution","doc":"Called before resolution begins.\n\n@return [void]","summary":"<p>Called before resolution begins.</p>","abstract":false,"location":{"filename":"src/molinillo_solver.cr","line_number":259,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L259"},"def":{"name":"before_resolution","visibility":"Public","body":""},"external_var":false},{"html_id":"dependencies_for(specification:S):Array(R)-instance-method","name":"dependencies_for","doc":"Returns the dependencies of `specification`.\n@note This method should be 'pure', i.e. the return value should depend\n  only on the `specification` parameter.\n\n@param [Object] specification\n@return [Array<Object>] the dependencies that are required by the given\n  `specification`.","summary":"<p>Returns the dependencies of <code>specification</code>.</p>","abstract":false,"args":[{"name":"specification","external_name":"specification","restriction":"S"}],"args_string":"(specification : S) : Array(R)","args_html":"(specification : <a href=\"../Shards/Spec.html\">S</a>) : Array(<a href=\"../Shards/Dependency.html\">R</a>)","location":{"filename":"src/molinillo_solver.cr","line_number":215,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L215"},"def":{"name":"dependencies_for","args":[{"name":"specification","external_name":"specification","restriction":"S"}],"return_type":"Array(R)","visibility":"Public","body":"apply_overrides(specification.dependencies)"},"external_var":false},{"html_id":"indicate_progress-instance-method","name":"indicate_progress","doc":"Called roughly every {#progress_rate}, this method should convey progress\nto the user.\n\n@return [void]","summary":"<p>Called roughly every {#progress_rate}, this method should convey progress to the user.</p>","abstract":false,"location":{"filename":"src/molinillo_solver.cr","line_number":265,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L265"},"def":{"name":"indicate_progress","visibility":"Public","body":""},"external_var":false},{"html_id":"locks=(locks:Array(Package)|Nil)-instance-method","name":"locks=","abstract":false,"args":[{"name":"locks","external_name":"locks","restriction":"Array(Package) | ::Nil"}],"args_string":"(locks : Array(Package) | Nil)","args_html":"(locks : Array(<a href=\"../Shards/Package.html\">Package</a>) | Nil)","location":{"filename":"src/molinillo_solver.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L6"},"def":{"name":"locks=","args":[{"name":"locks","external_name":"locks","restriction":"Array(Package) | ::Nil"}],"visibility":"Public","body":"@locks = locks"},"external_var":false},{"html_id":"name_for(spec:Shards::Spec)-instance-method","name":"name_for","abstract":false,"args":[{"name":"spec","external_name":"spec","restriction":"Shards::Spec"}],"args_string":"(spec : Shards::Spec)","args_html":"(spec : <a href=\"../Shards/Spec.html\">Shards::Spec</a>)","location":{"filename":"src/molinillo_solver.cr","line_number":167,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L167"},"def":{"name":"name_for","args":[{"name":"spec","external_name":"spec","restriction":"Shards::Spec"}],"visibility":"Public","body":"spec.resolver.not_nil!.name"},"external_var":false},{"html_id":"name_for(dependency:Shards::Dependency)-instance-method","name":"name_for","doc":"Returns the name for the given `dependency`.\n@note This method should be 'pure', i.e. the return value should depend\n  only on the `dependency` parameter.\n\n@param [Object] dependency\n@return [String] the name for the given `dependency`.","summary":"<p>Returns the name for the given <code>dependency</code>.</p>","abstract":false,"args":[{"name":"dependency","external_name":"dependency","restriction":"Shards::Dependency"}],"args_string":"(dependency : Shards::Dependency)","args_html":"(dependency : <a href=\"../Shards/Dependency.html\">Shards::Dependency</a>)","location":{"filename":"src/molinillo_solver.cr","line_number":171,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L171"},"def":{"name":"name_for","args":[{"name":"dependency","external_name":"dependency","restriction":"Shards::Dependency"}],"visibility":"Public","body":"dependency.name"},"external_var":false},{"html_id":"name_for_explicit_dependency_source-instance-method","name":"name_for_explicit_dependency_source","doc":"@return [String] the name of the source of explicit dependencies, i.e.\n  those passed to {Resolver#resolve} directly.","summary":"<p>@return [String] the name of the source of explicit dependencies, i.e.</p>","abstract":false,"location":{"filename":"src/molinillo_solver.cr","line_number":207,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L207"},"def":{"name":"name_for_explicit_dependency_source","visibility":"Public","body":"SPEC_FILENAME"},"external_var":false},{"html_id":"name_for_locking_dependency_source-instance-method","name":"name_for_locking_dependency_source","doc":"@return [String] the name of the source of 'locked' dependencies, i.e.\n  those passed to {Resolver#resolve} directly as the `base`","summary":"<p>@return [String] the name of the source of 'locked' dependencies, i.e.</p>","abstract":false,"location":{"filename":"src/molinillo_solver.cr","line_number":211,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L211"},"def":{"name":"name_for_locking_dependency_source","visibility":"Public","body":"LOCK_FILENAME"},"external_var":false},{"html_id":"on_override(dependency:Dependency|Shards::Spec):Dependency|Nil-instance-method","name":"on_override","abstract":false,"args":[{"name":"dependency","external_name":"dependency","restriction":"Dependency | Shards::Spec"}],"args_string":"(dependency : Dependency | Shards::Spec) : Dependency | Nil","args_html":"(dependency : <a href=\"../Shards/Dependency.html\">Dependency</a> | <a href=\"../Shards/Spec.html\">Shards::Spec</a>) : <a href=\"../Shards/Dependency.html\">Dependency</a> | Nil","location":{"filename":"src/molinillo_solver.cr","line_number":199,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L199"},"def":{"name":"on_override","args":[{"name":"dependency","external_name":"dependency","restriction":"Dependency | Shards::Spec"}],"return_type":"Dependency | ::Nil","visibility":"Public","body":"@override.try() do |__arg0| __arg0.dependencies.find do |o| o.name == dependency.name end end"},"external_var":false},{"html_id":"prepare(development:Bool|Nil=true)-instance-method","name":"prepare","abstract":false,"args":[{"name":"development","default_value":"true","external_name":"development","restriction":"::Bool | ::Nil"}],"args_string":"(development : Bool | Nil = true)","args_html":"(development : Bool | Nil = <span class=\"n\">true</span>)","location":{"filename":"src/molinillo_solver.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L17"},"def":{"name":"prepare","args":[{"name":"development","default_value":"true","external_name":"development","restriction":"::Bool | ::Nil"}],"visibility":"Public","body":"@development = development"},"external_var":false},{"html_id":"requirement_satisfied_by?(dependency,activated,spec)-instance-method","name":"requirement_satisfied_by?","abstract":false,"args":[{"name":"dependency","external_name":"dependency","restriction":""},{"name":"activated","external_name":"activated","restriction":""},{"name":"spec","external_name":"spec","restriction":""}],"args_string":"(dependency, activated, spec)","args_html":"(dependency, activated, spec)","location":{"filename":"src/molinillo_solver.cr","line_number":234,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L234"},"def":{"name":"requirement_satisfied_by?","args":[{"name":"dependency","external_name":"dependency","restriction":""},{"name":"activated","external_name":"activated","restriction":""},{"name":"spec","external_name":"spec","restriction":""}],"visibility":"Public","body":"if @prereleases\nelsif (!spec.version.has_metadata? && spec.version.prerelease?) && !dependency.prerelease?\n  vertex = activated.vertex_named(spec.name)\n  if (!vertex) || vertex.requirements.none?(&.prerelease?)\n    return false\n  end\nend\n\ndependency.matches?(spec.version)\n"},"external_var":false},{"html_id":"search_for(dependency:R):Array(S)-instance-method","name":"search_for","doc":"Search for the specifications that match the given dependency.\nThe specifications in the returned array will be considered in reverse\norder, so the latest version ought to be last.\n@note This method should be 'pure', i.e. the return value should depend\n  only on the `dependency` parameter.\n\n@param [Object] dependency\n@return [Array<Object>] the specifications that satisfy the given\n  `dependency`.","summary":"<p>Search for the specifications that match the given dependency.</p>","abstract":false,"args":[{"name":"dependency","external_name":"dependency","restriction":"R"}],"args_string":"(dependency : R) : Array(S)","args_html":"(dependency : <a href=\"../Shards/Dependency.html\">R</a>) : Array(<a href=\"../Shards/Spec.html\">S</a>)","location":{"filename":"src/molinillo_solver.cr","line_number":178,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L178"},"def":{"name":"search_for","args":[{"name":"dependency","external_name":"dependency","restriction":"R"}],"return_type":"Array(S)","visibility":"Public","body":"Log.with_context do\n  Log.context.set(package: dependency.name)\n  check_single_resolver_by_name(dependency.resolver)\n\n  __temp_a7004145_3 = {dependency.name, dependency.requirement}\n  @search_results[__temp_a7004145_3]? || (\n    @search_results[__temp_a7004145_3] = begin\n      resolver = dependency.resolver\n      versions = (Versions.sort(versions_for(dependency, resolver))).reverse\n      result = versions.map do |version|\n        __temp_a7004145_1 = {dependency.name, version}\n        @specs[__temp_a7004145_1]? || (\n          @specs[__temp_a7004145_1] = begin\n            (resolver.spec(version)).tap do |spec|\n              spec.version = version\n            end\n          end\n        )\n      end\n\n      result\n    end\n  )\nend"},"external_var":false},{"html_id":"solve:Array(Package)-instance-method","name":"solve","abstract":false,"location":{"filename":"src/molinillo_solver.cr","line_number":97,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/molinillo_solver.cr#L97"},"def":{"name":"solve","return_type":"Array(Package)","visibility":"Public","body":"deps = if @development\n  @spec.dependencies + @spec.development_dependencies\nelse\n  @spec.dependencies\nend\ndeps = apply_overrides(deps)\n\nprefetch_local_caches(deps)\n\nbase = Molinillo::DependencyGraph(Dependency, Dependency).new\nif locks = @locks\n  lock_index = locks.to_h do |d| {d.name, d} end\n\n  add_lock(base, lock_index, deps)\nend\n\nresult = (Molinillo::Resolver(Dependency, Spec)\n  .new(self, self))\n  .resolve(deps, base)\n\npackages = [] of Package\n(tsort(result)).each do |v|\n  if v.payload\n  else\n    next\n  end\n  spec = (v.payload.as?(Spec)) || (raise(\"BUG: returned graph payload was not a Spec\"))\n  if spec.name == \"crystal\"\n    next\n  end\n  v.requirements.each do |dependency|\n    if dependency.name == spec.name\n    else\n      raise(Error.new(\"Error shard name (#{spec.name}) doesn't match dependency name (#{dependency.name})\"))\n    end\n    if spec.read_from_yaml?\n      if spec.mismatched_version?\n        Log.warn do \"Shard \\\"#{spec.name}\\\" version (#{spec.original_version.value}) doesn't match tag version (#{spec.version.value})\" end\n      end\n    else\n      Log.warn do \"Shard \\\"#{spec.name}\\\" version (#{spec.version}) doesn't have a shard.yml file\" end\n    end\n  end\n  resolver = spec.resolver || (raise(\"BUG: returned Spec has no resolver\"))\n  version = spec.version\n\n  packages << (Package.new(spec.name, resolver, version, !on_override(spec).nil?))\nend\n\npackages\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Override","path":"Shards/Override.html","kind":"class","full_name":"Shards::Override","name":"Override","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/override.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/override.cr#L9"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"from_file(path,validate=false)-class-method","name":"from_file","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"args_string":"(path, validate = false)","args_html":"(path, validate = <span class=\"n\">false</span>)","location":{"filename":"src/override.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/override.cr#L10"},"def":{"name":"from_file","args":[{"name":"path","external_name":"path","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"visibility":"Public","body":"if File.directory?(path)\n  path = File.join(path, OVERRIDE_FILENAME)\nend\nif File.exists?(path)\nelse\n  raise(Error.new(\"Missing #{File.basename(path)}\"))\nend\nfrom_yaml(File.read(path), path, validate)\n"},"external_var":false},{"html_id":"from_yaml(input,filename=OVERRIDE_FILENAME,validate=false)-class-method","name":"from_yaml","abstract":false,"args":[{"name":"input","external_name":"input","restriction":""},{"name":"filename","default_value":"OVERRIDE_FILENAME","external_name":"filename","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"args_string":"(input, filename = OVERRIDE_FILENAME, validate = false)","args_html":"(input, filename = <span class=\"t\">OVERRIDE_FILENAME</span>, validate = <span class=\"n\">false</span>)","location":{"filename":"src/override.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/override.cr#L16"},"def":{"name":"from_yaml","args":[{"name":"input","external_name":"input","restriction":""},{"name":"filename","default_value":"OVERRIDE_FILENAME","external_name":"filename","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"visibility":"Public","body":"begin\n  parser = YAML::PullParser.new(input)\n  parser.read_stream do\n    if parser.kind.stream_end?\n      return new([] of Dependency)\n    end\n    parser.read_document do\n      new(parser, validate)\n    end\n  end\nrescue ex : YAML::ParseException\n  raise(ParseError.new(ex.message, input, filename, ex.line_number, ex.column_number))\nensure\n  if parser\n    parser.close\n  end\nend"},"external_var":false}],"constructors":[{"html_id":"new(pull:YAML::PullParser,validate=false):self-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"args_string":"(pull : YAML::PullParser, validate = false) : self","args_html":"(pull : <a href=\"../YAML/PullParser.html\">YAML::PullParser</a>, validate = <span class=\"n\">false</span>) : <span class=\"k\">self</span>","location":{"filename":"src/override.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/override.cr#L32"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"return_type":"self","visibility":"Public","body":"dependencies = nil\npull.each_in_mapping do\n  line, column = pull.location\n\n  case key = pull.read_scalar\n  when \"dependencies\"\n    check_duplicate(dependencies, \"dependencies\", line, column)\n    dependencies = [] of Dependency\n    pull.each_in_mapping do\n      dependencies << (Dependency.from_yaml(pull))\n    end\n  else\n    if validate\n      pull.raise(\"unknown attribute: #{key}\", line, column)\n    else\n      pull.skip\n    end\n  end\nend\nnew(dependencies || ([] of Dependency))\n"},"external_var":false},{"html_id":"new(dependencies:Array(Dependency))-class-method","name":"new","abstract":false,"args":[{"name":"dependencies","external_name":"dependencies","restriction":"Array(Dependency)"}],"args_string":"(dependencies : Array(Dependency))","args_html":"(dependencies : Array(<a href=\"../Shards/Dependency.html\">Dependency</a>))","location":{"filename":"src/override.cr","line_number":63,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/override.cr#L63"},"def":{"name":"new","args":[{"name":"dependencies","external_name":"dependencies","restriction":"Array(Dependency)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(dependencies)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"dependencies:Array(Dependency)-instance-method","name":"dependencies","abstract":false,"location":{"filename":"src/override.cr","line_number":61,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/override.cr#L61"},"def":{"name":"dependencies","return_type":"Array(Dependency)","visibility":"Public","body":"@dependencies"},"external_var":false}]},{"html_id":"Ashard/Shards/Package","path":"Shards/Package.html","kind":"class","full_name":"Shards::Package","name":"Package","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/package.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(name:String,resolver:Shards::Resolver,version:Shards::Version,is_override:Bool=false,checksum:String|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"resolver","external_name":"resolver","restriction":"::Shards::Resolver"},{"name":"version","external_name":"version","restriction":"::Shards::Version"},{"name":"is_override","default_value":"false","external_name":"is_override","restriction":"::Bool"},{"name":"checksum","default_value":"nil","external_name":"checksum","restriction":"String | ::Nil"}],"args_string":"(name : String, resolver : Shards::Resolver, version : Shards::Version, is_override : Bool = false, checksum : String | Nil = nil)","args_html":"(name : String, resolver : <a href=\"../Shards/Resolver.html\">Shards::Resolver</a>, version : <a href=\"../Shards/Version.html\">Shards::Version</a>, is_override : Bool = <span class=\"n\">false</span>, checksum : String | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/package.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L14"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"resolver","external_name":"resolver","restriction":"::Shards::Resolver"},{"name":"version","external_name":"version","restriction":"::Shards::Version"},{"name":"is_override","default_value":"false","external_name":"is_override","restriction":"::Bool"},{"name":"checksum","default_value":"nil","external_name":"checksum","restriction":"String | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, resolver, version, is_override, checksum)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"==(other:self)-instance-method","name":"==","doc":"Returns `true` if this reference is the same as *other*. Invokes `same?`.","summary":"<p>Returns <code>true</code> if this reference is the same as <em>other</em>.</p>","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"self"}],"args_string":"(other : self)","args_html":"(other : <span class=\"k\">self</span>)","location":{"filename":"src/package.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L17"},"def":{"name":"==","args":[{"name":"other","external_name":"other","restriction":"self"}],"visibility":"Public","body":"if same?(other)\n  return true\nend\n\n\nif @name == (other.@name)\nelse\n  return false\nend\n\nif @resolver == (other.@resolver)\nelse\n  return false\nend\n\nif @version == (other.@version)\nelse\n  return false\nend\n\ntrue\n"},"external_var":false},{"html_id":"checksum:String|Nil-instance-method","name":"checksum","abstract":false,"location":{"filename":"src/package.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L11"},"def":{"name":"checksum","return_type":"String | ::Nil","visibility":"Public","body":"@checksum"},"external_var":false},{"html_id":"checksum=(checksum:String|Nil)-instance-method","name":"checksum=","abstract":false,"args":[{"name":"checksum","external_name":"checksum","restriction":"String | ::Nil"}],"args_string":"(checksum : String | Nil)","args_html":"(checksum : String | Nil)","location":{"filename":"src/package.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L11"},"def":{"name":"checksum=","args":[{"name":"checksum","external_name":"checksum","restriction":"String | ::Nil"}],"visibility":"Public","body":"@checksum = checksum"},"external_var":false},{"html_id":"compute_checksum:String|Nil-instance-method","name":"compute_checksum","abstract":false,"location":{"filename":"src/package.cr","line_number":62,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L62"},"def":{"name":"compute_checksum","return_type":"String | ::Nil","visibility":"Public","body":"if File.exists?(install_path)\nelse\n  return nil\nend\nChecksum.compute(install_path)\n"},"external_var":false},{"html_id":"find_executable_file(install_path,name)-instance-method","name":"find_executable_file","abstract":false,"args":[{"name":"install_path","external_name":"install_path","restriction":""},{"name":"name","external_name":"name","restriction":""}],"args_string":"(install_path, name)","args_html":"(install_path, name)","location":{"filename":"src/package.cr","line_number":177,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L177"},"def":{"name":"find_executable_file","args":[{"name":"install_path","external_name":"install_path","restriction":""},{"name":"name","external_name":"name","restriction":""}],"visibility":"Public","body":"each_executable_path(name) do |path|\n  if File.exists?(install_path.join(path))\n    return path\n  end\nend"},"external_var":false},{"html_id":"install-instance-method","name":"install","abstract":false,"location":{"filename":"src/package.cr","line_number":67,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L67"},"def":{"name":"install","visibility":"Public","body":"Log.with_context do\n  Log.context.set(package: name)\n\n  cleanup_install_directory\n\n\n  resolver.install_sources(version, install_path)\n\n\n\n  if resolver.is_a?(PathResolver)\n  else\n    install_lib_path\n  end\nend\n\nShards.info.installed[name] = self\nShards.info.save\n"},"external_var":false},{"html_id":"install_executables-instance-method","name":"install_executables","abstract":false,"location":{"filename":"src/package.cr","line_number":147,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L147"},"def":{"name":"install_executables","visibility":"Public","body":"if ((!installed?) || spec.executables.empty?) || Shards.skip_executables?\n  return\nend\n\nDir.mkdir_p(Shards.bin_path)\n\nLog.with_context do\n  Log.context.set(package: name)\n  spec.executables.each do |name|\n    exe_name = find_executable_file(Path[install_path], name)\n    if exe_name\n    else\n      raise(Shards::Error.new(\"Could not find executable #{name.inspect} for #{@name.inspect}\"))\n    end\n    Log.debug do \"Install #{exe_name}\" end\n    source = File.join(install_path, exe_name)\n    destination = File.join(Shards.bin_path, File.basename(exe_name))\n\n    if File.exists?(destination)\n      if File.same?(destination, source)\n        next\n      end\n      File.delete(destination)\n    end\n\n    begin\n      File.link(source, destination)\n    rescue File::Error\n      FileUtils.cp(source, destination)\n    end\n  end\nend\n"},"external_var":false},{"html_id":"install_path-instance-method","name":"install_path","abstract":false,"location":{"filename":"src/package.cr","line_number":58,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L58"},"def":{"name":"install_path","visibility":"Public","body":"File.join(Shards.install_path, name)"},"external_var":false},{"html_id":"installed?-instance-method","name":"installed?","abstract":false,"location":{"filename":"src/package.cr","line_number":49,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L49"},"def":{"name":"installed?","visibility":"Public","body":"if File.exists?(install_path)\nelse\n  return false\nend\nif installed = Shards.info.installed[name]?\n  (installed.resolver == resolver) && (installed.version == version)\nelse\n  false\nend\n"},"external_var":false},{"html_id":"is_override:Bool-instance-method","name":"is_override","abstract":false,"location":{"filename":"src/package.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L10"},"def":{"name":"is_override","return_type":"Bool","visibility":"Public","body":"@is_override"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/package.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"postinstall-instance-method","name":"postinstall","abstract":false,"location":{"filename":"src/package.cr","line_number":102,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L102"},"def":{"name":"postinstall","visibility":"Public","body":"begin\n  if installed?\n  else\n    return\n  end\n  if command = spec.scripts[\"postinstall\"]?\n  else\n    return\n  end\n\n  if Shards.skip_postinstall?\n    Log.info do \"Postinstall of #{name}: #{command} (skipped)\" end\n    return\n  end\n\n  script_hash = PostinstallInfo.hash_script(command)\n  info = Shards.postinstall_info\n\n  if entry = info.shards[name]?\n    if entry.has_run && (entry.script_hash == script_hash)\n      return\n    elsif entry.has_run && (entry.script_hash != script_hash)\n      Log.warn do \"Postinstall script for #{name} has changed.\" end\n      Log.warn do \"  Run `shards run-script #{name}` to execute it.\" end\n      info.shards[name] = PostinstallInfo::Entry.new(script_hash, has_run: false)\n      info.save\n      return\n    end\n  end\n\n  Log.info do \"Postinstall of #{name}: #{command}\" end\n  Script.run(install_path, command, \"postinstall\", name)\n  info.shards[name] = PostinstallInfo::Entry.new(script_hash, has_run: true)\n  info.save\nrescue ex : Script::Error\n  cleanup_install_directory\n  raise(ex)\nend"},"external_var":false},{"html_id":"report_version-instance-method","name":"report_version","abstract":false,"location":{"filename":"src/package.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L19"},"def":{"name":"report_version","visibility":"Public","body":"resolver.report_version(version)"},"external_var":false},{"html_id":"resolver:Resolver-instance-method","name":"resolver","abstract":false,"location":{"filename":"src/package.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L8"},"def":{"name":"resolver","return_type":"Resolver","visibility":"Public","body":"@resolver"},"external_var":false},{"html_id":"run_script(name,skip)-instance-method","name":"run_script","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"skip","external_name":"skip","restriction":""}],"args_string":"(name, skip)","args_html":"(name, skip)","location":{"filename":"src/package.cr","line_number":136,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L136"},"def":{"name":"run_script","args":[{"name":"name","external_name":"name","restriction":""},{"name":"skip","external_name":"skip","restriction":""}],"visibility":"Public","body":"if installed? && (command = spec.scripts[name]?)\n  if !skip\n    Log.info do \"#{name.capitalize} of #{self.name}: #{command}\" end\n    Script.run(install_path, command, name, self.name)\n  else\n    Log.info do \"#{name.capitalize} of #{self.name}: #{command} (skipped)\" end\n  end\nend"},"external_var":false},{"html_id":"spec-instance-method","name":"spec","abstract":false,"location":{"filename":"src/package.cr","line_number":23,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L23"},"def":{"name":"spec","visibility":"Public","body":"@spec || (\n  @spec = (if installed?\n    read_installed_spec\n  else\n    resolver.spec(version)\n  end)\n)"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/package.cr","line_number":193,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L193"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"(((io << name) << \" (\") << report_version) << \")\""},"external_var":false},{"html_id":"to_yaml(builder)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"builder","external_name":"builder","restriction":""}],"args_string":"(builder)","args_html":"(builder)","location":{"filename":"src/package.cr","line_number":189,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L189"},"def":{"name":"to_yaml","args":[{"name":"builder","external_name":"builder","restriction":""}],"visibility":"Public","body":"(Dependency.new(name, resolver, version)).to_yaml(builder)"},"external_var":false},{"html_id":"version:Version-instance-method","name":"version","abstract":false,"location":{"filename":"src/package.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/package.cr#L9"},"def":{"name":"version","return_type":"Version","visibility":"Public","body":"@version"},"external_var":false}]},{"html_id":"Ashard/Shards/PackageScanResult","path":"Shards/PackageScanResult.html","kind":"struct","full_name":"Shards::PackageScanResult","name":"PackageScanResult","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/vulnerability_scanner.cr","line_number":51,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L51"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Holds the scan result for a single package.","summary":"<p>Holds the scan result for a single package.</p>","constructors":[{"html_id":"new(package:Shards::Package,purl:Nil|String,vulnerabilities:Array(Shards::Vulnerability)=[]ofVulnerability)-class-method","name":"new","abstract":false,"args":[{"name":"package","external_name":"package","restriction":"::Shards::Package"},{"name":"purl","external_name":"purl","restriction":"::Nil | ::String"},{"name":"vulnerabilities","default_value":"[] of Vulnerability","external_name":"vulnerabilities","restriction":"::Array(::Shards::Vulnerability)"}],"args_string":"(package : Shards::Package, purl : Nil | String, vulnerabilities : Array(Shards::Vulnerability) = [] of Vulnerability)","args_html":"(package : <a href=\"../Shards/Package.html\">Shards::Package</a>, purl : Nil | String, vulnerabilities : Array(<a href=\"../Shards/Vulnerability.html\">Shards::Vulnerability</a>) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">Vulnerability</span>)","location":{"filename":"src/vulnerability_scanner.cr","line_number":56,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L56"},"def":{"name":"new","args":[{"name":"package","external_name":"package","restriction":"::Shards::Package"},{"name":"purl","external_name":"purl","restriction":"::Nil | ::String"},{"name":"vulnerabilities","default_value":"[] of Vulnerability","external_name":"vulnerabilities","restriction":"::Array(::Shards::Vulnerability)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(package, purl, vulnerabilities)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"package:Package-instance-method","name":"package","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":52,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L52"},"def":{"name":"package","return_type":"Package","visibility":"Public","body":"@package"},"external_var":false},{"html_id":"purl:String|Nil-instance-method","name":"purl","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":53,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L53"},"def":{"name":"purl","return_type":"String | ::Nil","visibility":"Public","body":"@purl"},"external_var":false},{"html_id":"vulnerabilities:Array(Vulnerability)-instance-method","name":"vulnerabilities","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":54,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L54"},"def":{"name":"vulnerabilities","return_type":"Array(Vulnerability)","visibility":"Public","body":"@vulnerabilities"},"external_var":false},{"html_id":"vulnerable?:Bool-instance-method","name":"vulnerable?","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":59,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L59"},"def":{"name":"vulnerable?","return_type":"Bool","visibility":"Public","body":"!vulnerabilities.empty?"},"external_var":false}]},{"html_id":"Ashard/Shards/ParseError","path":"Shards/ParseError.html","kind":"class","full_name":"Shards::ParseError","name":"ParseError","abstract":false,"superclass":{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},"ancestors":[{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/errors.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L25"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(message,input:String,filename:String,line_number,column_number)-class-method","name":"new","abstract":false,"args":[{"name":"message","external_name":"message","restriction":""},{"name":"input","external_name":"input","restriction":"::String"},{"name":"filename","external_name":"filename","restriction":"::String"},{"name":"line_number","external_name":"line_number","restriction":""},{"name":"column_number","external_name":"column_number","restriction":""}],"args_string":"(message, input : String, filename : String, line_number, column_number)","args_html":"(message, input : String, filename : String, line_number, column_number)","location":{"filename":"src/errors.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L32"},"def":{"name":"new","args":[{"name":"message","external_name":"message","restriction":""},{"name":"input","external_name":"input","restriction":"::String"},{"name":"filename","external_name":"filename","restriction":"::String"},{"name":"line_number","external_name":"line_number","restriction":""},{"name":"column_number","external_name":"column_number","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(message, input, filename, line_number, column_number)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"column_number:Int32-instance-method","name":"column_number","abstract":false,"location":{"filename":"src/errors.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L29"},"def":{"name":"column_number","return_type":"Int32","visibility":"Public","body":"@column_number"},"external_var":false},{"html_id":"filename:String-instance-method","name":"filename","abstract":false,"location":{"filename":"src/errors.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L27"},"def":{"name":"filename","return_type":"String","visibility":"Public","body":"@filename"},"external_var":false},{"html_id":"input:String-instance-method","name":"input","abstract":false,"location":{"filename":"src/errors.cr","line_number":26,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L26"},"def":{"name":"input","return_type":"String","visibility":"Public","body":"@input"},"external_var":false},{"html_id":"line_number:Int32-instance-method","name":"line_number","abstract":false,"location":{"filename":"src/errors.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L28"},"def":{"name":"line_number","return_type":"Int32","visibility":"Public","body":"@line_number"},"external_var":false},{"html_id":"resolver:Resolver|Nil-instance-method","name":"resolver","abstract":false,"location":{"filename":"src/errors.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L30"},"def":{"name":"resolver","return_type":"Resolver | ::Nil","visibility":"Public","body":"@resolver"},"external_var":false},{"html_id":"resolver=(resolver:Resolver|Nil)-instance-method","name":"resolver=","abstract":false,"args":[{"name":"resolver","external_name":"resolver","restriction":"Resolver | ::Nil"}],"args_string":"(resolver : Resolver | Nil)","args_html":"(resolver : <a href=\"../Shards/Resolver.html\">Resolver</a> | Nil)","location":{"filename":"src/errors.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L30"},"def":{"name":"resolver=","args":[{"name":"resolver","external_name":"resolver","restriction":"Resolver | ::Nil"}],"visibility":"Public","body":"@resolver = resolver"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/errors.cr","line_number":38,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/errors.cr#L38"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"io << \"Error in \"\nif resolver = self.resolver\n  resolver.name.inspect_unquoted(io)\n  io << ':'\nend\n\nfilename = self.filename\nfilename = Path[filename].relative_to(Dir.current)\n\nio.puts(\"#{filename}: #{message}\")\nio.puts\n\nlines = input.lines\nfrom = line_number - 3\nif from < 0\n  from = 0\nend\n\nlines[from...line_number].each_with_index do |line, i|\n  io.puts(\"  #{(from + i) + 1}. #{line}\")\nend\n\narrow = String.build do |s|\n  s << \"     \"\n  (column_number - 1).times do s << ' ' end\n  s << '^'\nend\nio.puts((arrow.colorize(:green)).bold)\nio.puts\n\nio.flush\n"},"external_var":false}]},{"html_id":"Ashard/Shards/PathResolver","path":"Shards/PathResolver.html","kind":"class","full_name":"Shards::PathResolver","name":"PathResolver","abstract":false,"superclass":{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},"ancestors":[{"html_id":"Ashard/Shards/Resolver","kind":"class","full_name":"Shards::Resolver","name":"Resolver"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/path.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L4"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"key-class-method","name":"key","abstract":false,"location":{"filename":"src/resolvers/path.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L5"},"def":{"name":"key","visibility":"Public","body":"\"path\""},"external_var":false}],"instance_methods":[{"html_id":"available_releases:Array(Version)-instance-method","name":"available_releases","abstract":false,"location":{"filename":"src/resolvers/path.cr","line_number":23,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L23"},"def":{"name":"available_releases","return_type":"Array(Version)","visibility":"Public","body":"[(spec(nil)).version]"},"external_var":false},{"html_id":"install_sources(version,install_path)-instance-method","name":"install_sources","abstract":false,"args":[{"name":"version","external_name":"version","restriction":""},{"name":"install_path","external_name":"install_path","restriction":""}],"args_string":"(version, install_path)","args_html":"(version, install_path)","location":{"filename":"src/resolvers/path.cr","line_number":37,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L37"},"def":{"name":"install_sources","args":[{"name":"version","external_name":"version","restriction":""},{"name":"install_path","external_name":"install_path","restriction":""}],"visibility":"Public","body":"path = expanded_local_path\n\nDir.mkdir_p(File.dirname(install_path))\nFile.symlink(path, install_path)\n"},"external_var":false},{"html_id":"local_path-instance-method","name":"local_path","abstract":false,"location":{"filename":"src/resolvers/path.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L27"},"def":{"name":"local_path","visibility":"Public","body":"source"},"external_var":false},{"html_id":"read_spec(version=nil):String|Nil-instance-method","name":"read_spec","abstract":false,"args":[{"name":"version","default_value":"nil","external_name":"version","restriction":""}],"args_string":"(version = nil) : String | Nil","args_html":"(version = <span class=\"n\">nil</span>) : String | Nil","location":{"filename":"src/resolvers/path.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L9"},"def":{"name":"read_spec","args":[{"name":"version","default_value":"nil","external_name":"version","restriction":""}],"return_type":"String | ::Nil","visibility":"Public","body":"spec_path = File.join(expanded_local_path, SPEC_FILENAME)\n\nif File.exists?(spec_path)\n  File.read(spec_path)\nelse\n  raise(Error.new(\"Missing #{SPEC_FILENAME.inspect} for #{name.inspect} at #{(File.expand_path(local_path)).inspect}\"))\nend\n"},"external_var":false},{"html_id":"report_version(version:Version):String-instance-method","name":"report_version","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String","location":{"filename":"src/resolvers/path.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L44"},"def":{"name":"report_version","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String","visibility":"Public","body":"\"#{version.value} at #{source}\""},"external_var":false},{"html_id":"spec(version=nil)-instance-method","name":"spec","abstract":false,"args":[{"name":"version","default_value":"nil","external_name":"version","restriction":""}],"args_string":"(version = nil)","args_html":"(version = <span class=\"n\">nil</span>)","location":{"filename":"src/resolvers/path.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/path.cr#L19"},"def":{"name":"spec","args":[{"name":"version","default_value":"nil","external_name":"version","restriction":""}],"visibility":"Public","body":"(load_spec(version)) || (raise(Error.new(\"Can't read spec for #{name.inspect}\")))"},"external_var":false}]},{"html_id":"Ashard/Shards/Policy","path":"Shards/Policy.html","kind":"class","full_name":"Shards::Policy","name":"Policy","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CURRENT_VERSION","name":"CURRENT_VERSION","value":"\"1\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"from_file(path:String):self-class-method","name":"from_file","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : self","args_html":"(path : String) : <span class=\"k\">self</span>","location":{"filename":"src/policy.cr","line_number":104,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L104"},"def":{"name":"from_file","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"self","visibility":"Public","body":"if File.exists?(path)\nelse\n  raise(Error.new(\"Missing #{File.basename(path)}\"))\nend\nfrom_yaml(File.read(path), path)\n"},"external_var":false},{"html_id":"from_yaml(input:String,filename=POLICY_FILENAME):self-class-method","name":"from_yaml","abstract":false,"args":[{"name":"input","external_name":"input","restriction":"String"},{"name":"filename","default_value":"POLICY_FILENAME","external_name":"filename","restriction":""}],"args_string":"(input : String, filename = POLICY_FILENAME) : self","args_html":"(input : String, filename = <span class=\"t\">POLICY_FILENAME</span>) : <span class=\"k\">self</span>","location":{"filename":"src/policy.cr","line_number":109,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L109"},"def":{"name":"from_yaml","args":[{"name":"input","external_name":"input","restriction":"String"},{"name":"filename","default_value":"POLICY_FILENAME","external_name":"filename","restriction":""}],"return_type":"self","visibility":"Public","body":"begin\n  parser = YAML::PullParser.new(input)\n  parser.read_stream do\n    if parser.kind.stream_end?\n      return new\n    end\n    parser.read_document do\n      new(parser)\n    end\n  end\nrescue ex : YAML::ParseException\n  raise(ParseError.new(ex.message, input, filename, ex.line_number, ex.column_number))\nensure\n  if parser\n    parser.close\n  end\nend"},"external_var":false},{"html_id":"new(pull:YAML::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"args_string":"(pull : YAML::PullParser)","args_html":"(pull : <a href=\"../YAML/PullParser.html\">YAML::PullParser</a>)","location":{"filename":"src/policy.cr","line_number":125,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L125"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"visibility":"Public","body":"_ = allocate\n_.initialize(pull)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false},{"html_id":"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)=[]ofCustomRule)-class-method","name":"new","abstract":false,"args":[{"name":"version","default_value":"CURRENT_VERSION","external_name":"version","restriction":"::String"},{"name":"sources","default_value":"SourceRules.new","external_name":"sources","restriction":"::Shards::Policy::SourceRules"},{"name":"dependencies","default_value":"DependencyRules.new","external_name":"dependencies","restriction":"::Shards::Policy::DependencyRules"},{"name":"freshness","default_value":"FreshnessRules.new","external_name":"freshness","restriction":"::Shards::Policy::FreshnessRules"},{"name":"security","default_value":"SecurityRules.new","external_name":"security","restriction":"::Shards::Policy::SecurityRules"},{"name":"custom","default_value":"[] of CustomRule","external_name":"custom","restriction":"::Array(::Shards::Policy::CustomRule)"}],"args_string":"(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)","args_html":"(version : String = <span class=\"t\">CURRENT_VERSION</span>, sources : <a href=\"../Shards/Policy/SourceRules.html\">Shards::Policy::SourceRules</a> = <span class=\"t\">SourceRules</span>.new, dependencies : <a href=\"../Shards/Policy/DependencyRules.html\">Shards::Policy::DependencyRules</a> = <span class=\"t\">DependencyRules</span>.new, freshness : <a href=\"../Shards/Policy/FreshnessRules.html\">Shards::Policy::FreshnessRules</a> = <span class=\"t\">FreshnessRules</span>.new, security : <a href=\"../Shards/Policy/SecurityRules.html\">Shards::Policy::SecurityRules</a> = <span class=\"t\">SecurityRules</span>.new, custom : Array(<a href=\"../Shards/Policy/CustomRule.html\">Shards::Policy::CustomRule</a>) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">CustomRule</span>)","location":{"filename":"src/policy.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L16"},"def":{"name":"new","args":[{"name":"version","default_value":"CURRENT_VERSION","external_name":"version","restriction":"::String"},{"name":"sources","default_value":"SourceRules.new","external_name":"sources","restriction":"::Shards::Policy::SourceRules"},{"name":"dependencies","default_value":"DependencyRules.new","external_name":"dependencies","restriction":"::Shards::Policy::DependencyRules"},{"name":"freshness","default_value":"FreshnessRules.new","external_name":"freshness","restriction":"::Shards::Policy::FreshnessRules"},{"name":"security","default_value":"SecurityRules.new","external_name":"security","restriction":"::Shards::Policy::SecurityRules"},{"name":"custom","default_value":"[] of CustomRule","external_name":"custom","restriction":"::Array(::Shards::Policy::CustomRule)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(version, sources, dependencies, freshness, security, custom)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"custom:Array(CustomRule)-instance-method","name":"custom","abstract":false,"location":{"filename":"src/policy.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L14"},"def":{"name":"custom","return_type":"Array(CustomRule)","visibility":"Public","body":"@custom"},"external_var":false},{"html_id":"dependencies:DependencyRules-instance-method","name":"dependencies","abstract":false,"location":{"filename":"src/policy.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L11"},"def":{"name":"dependencies","return_type":"DependencyRules","visibility":"Public","body":"@dependencies"},"external_var":false},{"html_id":"freshness:FreshnessRules-instance-method","name":"freshness","abstract":false,"location":{"filename":"src/policy.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L12"},"def":{"name":"freshness","return_type":"FreshnessRules","visibility":"Public","body":"@freshness"},"external_var":false},{"html_id":"security:SecurityRules-instance-method","name":"security","abstract":false,"location":{"filename":"src/policy.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L13"},"def":{"name":"security","return_type":"SecurityRules","visibility":"Public","body":"@security"},"external_var":false},{"html_id":"sources:SourceRules-instance-method","name":"sources","abstract":false,"location":{"filename":"src/policy.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L10"},"def":{"name":"sources","return_type":"SourceRules","visibility":"Public","body":"@sources"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/policy.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L9"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/Policy/BlockedDep","path":"Shards/Policy/BlockedDep.html","kind":"class","full_name":"Shards::Policy::BlockedDep","name":"BlockedDep","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy.cr","line_number":56,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L56"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Policy","kind":"class","full_name":"Shards::Policy","name":"Policy"},"constructors":[{"html_id":"new(name:String,reason:Nil|String=nil)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"reason","default_value":"nil","external_name":"reason","restriction":"::Nil | ::String"}],"args_string":"(name : String, reason : Nil | String = nil)","args_html":"(name : String, reason : Nil | String = <span class=\"n\">nil</span>)","location":{"filename":"src/policy.cr","line_number":60,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L60"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"reason","default_value":"nil","external_name":"reason","restriction":"::Nil | ::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, reason)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/policy.cr","line_number":57,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L57"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"reason:String|Nil-instance-method","name":"reason","abstract":false,"location":{"filename":"src/policy.cr","line_number":58,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L58"},"def":{"name":"reason","return_type":"String | ::Nil","visibility":"Public","body":"@reason"},"external_var":false}]},{"html_id":"Ashard/Shards/Policy/CustomRule","path":"Shards/Policy/CustomRule.html","kind":"class","full_name":"Shards::Policy::CustomRule","name":"CustomRule","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy.cr","line_number":90,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L90"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Policy","kind":"class","full_name":"Shards::Policy","name":"Policy"},"constructors":[{"html_id":"new(name:String,pattern_str:String,action_str:String,reason:Nil|String=nil)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"pattern_str","external_name":"pattern_str","restriction":"String"},{"name":"action_str","external_name":"action_str","restriction":"String"},{"name":"reason","default_value":"nil","external_name":"reason","restriction":"::Nil | ::String"}],"args_string":"(name : String, pattern_str : String, action_str : String, reason : Nil | String = nil)","args_html":"(name : String, pattern_str : String, action_str : String, reason : Nil | String = <span class=\"n\">nil</span>)","location":{"filename":"src/policy.cr","line_number":96,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L96"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"pattern_str","external_name":"pattern_str","restriction":"String"},{"name":"action_str","external_name":"action_str","restriction":"String"},{"name":"reason","default_value":"nil","external_name":"reason","restriction":"::Nil | ::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, pattern_str, action_str, reason)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"action:Symbol-instance-method","name":"action","abstract":false,"location":{"filename":"src/policy.cr","line_number":93,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L93"},"def":{"name":"action","return_type":"Symbol","visibility":"Public","body":"@action"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/policy.cr","line_number":91,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L91"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"pattern:Regex-instance-method","name":"pattern","abstract":false,"location":{"filename":"src/policy.cr","line_number":92,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L92"},"def":{"name":"pattern","return_type":"Regex","visibility":"Public","body":"@pattern"},"external_var":false},{"html_id":"reason:String|Nil-instance-method","name":"reason","abstract":false,"location":{"filename":"src/policy.cr","line_number":94,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L94"},"def":{"name":"reason","return_type":"String | ::Nil","visibility":"Public","body":"@reason"},"external_var":false}]},{"html_id":"Ashard/Shards/Policy/DependencyRules","path":"Shards/Policy/DependencyRules.html","kind":"class","full_name":"Shards::Policy::DependencyRules","name":"DependencyRules","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy.cr","line_number":45,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L45"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Policy","kind":"class","full_name":"Shards::Policy","name":"Policy"},"constructors":[{"html_id":"new(blocked:Array(Shards::Policy::BlockedDep)=[]ofBlockedDep,minimum_versions:Hash(String,String)={}ofString=>String)-class-method","name":"new","abstract":false,"args":[{"name":"blocked","default_value":"[] of BlockedDep","external_name":"blocked","restriction":"::Array(::Shards::Policy::BlockedDep)"},{"name":"minimum_versions","default_value":"{} of String => String","external_name":"minimum_versions","restriction":"::Hash(::String, ::String)"}],"args_string":"(blocked : Array(Shards::Policy::BlockedDep) = [] of BlockedDep, minimum_versions : Hash(String, String) = {} of String => String)","args_html":"(blocked : Array(<a href=\"../../Shards/Policy/BlockedDep.html\">Shards::Policy::BlockedDep</a>) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">BlockedDep</span>, minimum_versions : Hash(String, String) = {} <span class=\"k\">of</span> <span class=\"t\">String</span> <span class=\"o\">=&gt;</span> <span class=\"t\">String</span>)","location":{"filename":"src/policy.cr","line_number":49,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L49"},"def":{"name":"new","args":[{"name":"blocked","default_value":"[] of BlockedDep","external_name":"blocked","restriction":"::Array(::Shards::Policy::BlockedDep)"},{"name":"minimum_versions","default_value":"{} of String => String","external_name":"minimum_versions","restriction":"::Hash(::String, ::String)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(blocked, minimum_versions)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"blocked:Array(BlockedDep)-instance-method","name":"blocked","abstract":false,"location":{"filename":"src/policy.cr","line_number":46,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L46"},"def":{"name":"blocked","return_type":"Array(BlockedDep)","visibility":"Public","body":"@blocked"},"external_var":false},{"html_id":"minimum_versions:Hash(String,String)-instance-method","name":"minimum_versions","abstract":false,"location":{"filename":"src/policy.cr","line_number":47,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L47"},"def":{"name":"minimum_versions","return_type":"Hash(String, String)","visibility":"Public","body":"@minimum_versions"},"external_var":false}]},{"html_id":"Ashard/Shards/Policy/FreshnessRules","path":"Shards/Policy/FreshnessRules.html","kind":"class","full_name":"Shards::Policy::FreshnessRules","name":"FreshnessRules","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy.cr","line_number":64,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L64"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Policy","kind":"class","full_name":"Shards::Policy","name":"Policy"},"constructors":[{"html_id":"new(max_age_days:Int32|Nil=nil,require_recent_commit:Int32|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"max_age_days","default_value":"nil","external_name":"max_age_days","restriction":"::Int32 | ::Nil"},{"name":"require_recent_commit","default_value":"nil","external_name":"require_recent_commit","restriction":"::Int32 | ::Nil"}],"args_string":"(max_age_days : Int32 | Nil = nil, require_recent_commit : Int32 | Nil = nil)","args_html":"(max_age_days : Int32 | Nil = <span class=\"n\">nil</span>, require_recent_commit : Int32 | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/policy.cr","line_number":68,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L68"},"def":{"name":"new","args":[{"name":"max_age_days","default_value":"nil","external_name":"max_age_days","restriction":"::Int32 | ::Nil"},{"name":"require_recent_commit","default_value":"nil","external_name":"require_recent_commit","restriction":"::Int32 | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(max_age_days, require_recent_commit)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"max_age_days:Int32|Nil-instance-method","name":"max_age_days","abstract":false,"location":{"filename":"src/policy.cr","line_number":65,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L65"},"def":{"name":"max_age_days","return_type":"Int32 | ::Nil","visibility":"Public","body":"@max_age_days"},"external_var":false},{"html_id":"require_recent_commit:Int32|Nil-instance-method","name":"require_recent_commit","abstract":false,"location":{"filename":"src/policy.cr","line_number":66,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L66"},"def":{"name":"require_recent_commit","return_type":"Int32 | ::Nil","visibility":"Public","body":"@require_recent_commit"},"external_var":false}]},{"html_id":"Ashard/Shards/Policy/SecurityRules","path":"Shards/Policy/SecurityRules.html","kind":"class","full_name":"Shards::Policy::SecurityRules","name":"SecurityRules","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy.cr","line_number":75,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L75"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Policy","kind":"class","full_name":"Shards::Policy","name":"Policy"},"constructors":[{"html_id":"new(require_license:Bool=false,require_checksum:Bool=false,block_postinstall:Bool=false,audit_postinstall:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"require_license","default_value":"false","external_name":"require_license","restriction":"::Bool"},{"name":"require_checksum","default_value":"false","external_name":"require_checksum","restriction":"::Bool"},{"name":"block_postinstall","default_value":"false","external_name":"block_postinstall","restriction":"::Bool"},{"name":"audit_postinstall","default_value":"false","external_name":"audit_postinstall","restriction":"::Bool"}],"args_string":"(require_license : Bool = false, require_checksum : Bool = false, block_postinstall : Bool = false, audit_postinstall : Bool = false)","args_html":"(require_license : Bool = <span class=\"n\">false</span>, require_checksum : Bool = <span class=\"n\">false</span>, block_postinstall : Bool = <span class=\"n\">false</span>, audit_postinstall : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/policy.cr","line_number":81,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L81"},"def":{"name":"new","args":[{"name":"require_license","default_value":"false","external_name":"require_license","restriction":"::Bool"},{"name":"require_checksum","default_value":"false","external_name":"require_checksum","restriction":"::Bool"},{"name":"block_postinstall","default_value":"false","external_name":"block_postinstall","restriction":"::Bool"},{"name":"audit_postinstall","default_value":"false","external_name":"audit_postinstall","restriction":"::Bool"}],"visibility":"Public","body":"_ = allocate\n_.initialize(require_license, require_checksum, block_postinstall, audit_postinstall)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"audit_postinstall?:Bool-instance-method","name":"audit_postinstall?","abstract":false,"location":{"filename":"src/policy.cr","line_number":79,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L79"},"def":{"name":"audit_postinstall?","return_type":"Bool","visibility":"Public","body":"@audit_postinstall"},"external_var":false},{"html_id":"block_postinstall?:Bool-instance-method","name":"block_postinstall?","abstract":false,"location":{"filename":"src/policy.cr","line_number":78,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L78"},"def":{"name":"block_postinstall?","return_type":"Bool","visibility":"Public","body":"@block_postinstall"},"external_var":false},{"html_id":"require_checksum?:Bool-instance-method","name":"require_checksum?","abstract":false,"location":{"filename":"src/policy.cr","line_number":77,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L77"},"def":{"name":"require_checksum?","return_type":"Bool","visibility":"Public","body":"@require_checksum"},"external_var":false},{"html_id":"require_license?:Bool-instance-method","name":"require_license?","abstract":false,"location":{"filename":"src/policy.cr","line_number":76,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L76"},"def":{"name":"require_license?","return_type":"Bool","visibility":"Public","body":"@require_license"},"external_var":false}]},{"html_id":"Ashard/Shards/Policy/SourceRules","path":"Shards/Policy/SourceRules.html","kind":"class","full_name":"Shards::Policy::SourceRules","name":"SourceRules","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L28"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Policy","kind":"class","full_name":"Shards::Policy","name":"Policy"},"constructors":[{"html_id":"new(allowed_hosts:Array(String)=[]ofString,allowed_orgs:Hash(String,Array(String))={}ofString=>Array(String),deny_path_dependencies:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"allowed_hosts","default_value":"[] of String","external_name":"allowed_hosts","restriction":"::Array(::String)"},{"name":"allowed_orgs","default_value":"{} of String => Array(String)","external_name":"allowed_orgs","restriction":"::Hash(::String, ::Array(::String))"},{"name":"deny_path_dependencies","default_value":"false","external_name":"deny_path_dependencies","restriction":"::Bool"}],"args_string":"(allowed_hosts : Array(String) = [] of String, allowed_orgs : Hash(String, Array(String)) = {} of String => Array(String), deny_path_dependencies : Bool = false)","args_html":"(allowed_hosts : Array(String) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">String</span>, allowed_orgs : Hash(String, Array(String)) = {} <span class=\"k\">of</span> <span class=\"t\">String</span> <span class=\"o\">=&gt;</span> <span class=\"t\">Array</span>(<span class=\"t\">String</span>), deny_path_dependencies : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/policy.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L33"},"def":{"name":"new","args":[{"name":"allowed_hosts","default_value":"[] of String","external_name":"allowed_hosts","restriction":"::Array(::String)"},{"name":"allowed_orgs","default_value":"{} of String => Array(String)","external_name":"allowed_orgs","restriction":"::Hash(::String, ::Array(::String))"},{"name":"deny_path_dependencies","default_value":"false","external_name":"deny_path_dependencies","restriction":"::Bool"}],"visibility":"Public","body":"_ = allocate\n_.initialize(allowed_hosts, allowed_orgs, deny_path_dependencies)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"allowed_hosts:Array(String)-instance-method","name":"allowed_hosts","abstract":false,"location":{"filename":"src/policy.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L29"},"def":{"name":"allowed_hosts","return_type":"Array(String)","visibility":"Public","body":"@allowed_hosts"},"external_var":false},{"html_id":"allowed_orgs:Hash(String,Array(String))-instance-method","name":"allowed_orgs","abstract":false,"location":{"filename":"src/policy.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L30"},"def":{"name":"allowed_orgs","return_type":"Hash(String, Array(String))","visibility":"Public","body":"@allowed_orgs"},"external_var":false},{"html_id":"deny_path_dependencies?:Bool-instance-method","name":"deny_path_dependencies?","abstract":false,"location":{"filename":"src/policy.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L31"},"def":{"name":"deny_path_dependencies?","return_type":"Bool","visibility":"Public","body":"@deny_path_dependencies"},"external_var":false},{"html_id":"empty?-instance-method","name":"empty?","abstract":false,"location":{"filename":"src/policy.cr","line_number":40,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy.cr#L40"},"def":{"name":"empty?","visibility":"Public","body":"(allowed_hosts.empty? && allowed_orgs.empty?) && (!deny_path_dependencies?)"},"external_var":false}]}]},{"html_id":"Ashard/Shards/PolicyChecker","path":"Shards/PolicyChecker.html","kind":"class","full_name":"Shards::PolicyChecker","name":"PolicyChecker","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy_checker.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_checker.cr#L10"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(policy:Policy)-class-method","name":"new","abstract":false,"args":[{"name":"policy","external_name":"policy","restriction":"Policy"}],"args_string":"(policy : Policy)","args_html":"(policy : <a href=\"../Shards/Policy.html\">Policy</a>)","location":{"filename":"src/policy_checker.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_checker.cr#L14"},"def":{"name":"new","args":[{"name":"policy","external_name":"policy","restriction":"Policy"}],"visibility":"Public","body":"_ = allocate\n_.initialize(policy)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"check(packages:Array(Package)):PolicyReport-instance-method","name":"check","doc":"Main entry point: check all packages against all rules","summary":"<p>Main entry point: check all packages against all rules</p>","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"args_string":"(packages : Array(Package)) : PolicyReport","args_html":"(packages : Array(<a href=\"../Shards/Package.html\">Package</a>)) : <a href=\"../Shards/PolicyReport.html\">PolicyReport</a>","location":{"filename":"src/policy_checker.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_checker.cr#L19"},"def":{"name":"check","args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"return_type":"PolicyReport","visibility":"Public","body":"@report = PolicyReport.new\n\npackages.each do |package|\n  check_blocked(package)\n  check_sources(package)\n  check_minimum_version(package)\n  check_security(package)\n  check_custom(package)\n  check_freshness(package)\nend\n\n@report\n"},"external_var":false},{"html_id":"policy:Policy-instance-method","name":"policy","abstract":false,"location":{"filename":"src/policy_checker.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_checker.cr#L11"},"def":{"name":"policy","return_type":"Policy","visibility":"Public","body":"@policy"},"external_var":false},{"html_id":"report:PolicyReport-instance-method","name":"report","abstract":false,"location":{"filename":"src/policy_checker.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_checker.cr#L12"},"def":{"name":"report","return_type":"PolicyReport","visibility":"Public","body":"@report"},"external_var":false}]},{"html_id":"Ashard/Shards/PolicyReport","path":"Shards/PolicyReport.html","kind":"class","full_name":"Shards::PolicyReport","name":"PolicyReport","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy_report.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L5"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L19"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"add_violation(package:String,rule:String,severity:Severity,message:String)-instance-method","name":"add_violation","abstract":false,"args":[{"name":"package","external_name":"package","restriction":"String"},{"name":"rule","external_name":"rule","restriction":"String"},{"name":"severity","external_name":"severity","restriction":"Severity"},{"name":"message","external_name":"message","restriction":"String"}],"args_string":"(package : String, rule : String, severity : Severity, message : String)","args_html":"(package : String, rule : String, severity : <a href=\"../Shards/PolicyReport/Severity.html\">Severity</a>, message : String)","location":{"filename":"src/policy_report.cr","line_number":23,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L23"},"def":{"name":"add_violation","args":[{"name":"package","external_name":"package","restriction":"String"},{"name":"rule","external_name":"rule","restriction":"String"},{"name":"severity","external_name":"severity","restriction":"Severity"},{"name":"message","external_name":"message","restriction":"String"}],"visibility":"Public","body":"@violations << Violation.new(package: package, rule: rule, severity: severity, message: message)"},"external_var":false},{"html_id":"clean?-instance-method","name":"clean?","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":35,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L35"},"def":{"name":"clean?","visibility":"Public","body":"@violations.empty?"},"external_var":false},{"html_id":"errors-instance-method","name":"errors","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L27"},"def":{"name":"errors","visibility":"Public","body":"@violations.select() do |__arg0| __arg0.severity.error? end"},"external_var":false},{"html_id":"exit_code(strict:Bool=false):Int32-instance-method","name":"exit_code","abstract":false,"args":[{"name":"strict","default_value":"false","external_name":"strict","restriction":"Bool"}],"args_string":"(strict : Bool = false) : Int32","args_html":"(strict : Bool = <span class=\"n\">false</span>) : Int32","location":{"filename":"src/policy_report.cr","line_number":47,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L47"},"def":{"name":"exit_code","args":[{"name":"strict","default_value":"false","external_name":"strict","restriction":"Bool"}],"return_type":"Int32","visibility":"Public","body":"if has_errors?\n  1\nelsif has_warnings? && strict\n  1\nelsif has_warnings?\n  2\nelse\n  0\nend"},"external_var":false},{"html_id":"has_errors?-instance-method","name":"has_errors?","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":39,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L39"},"def":{"name":"has_errors?","visibility":"Public","body":"@violations.any?() do |__arg2| __arg2.severity.error? end"},"external_var":false},{"html_id":"has_warnings?-instance-method","name":"has_warnings?","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":43,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L43"},"def":{"name":"has_warnings?","visibility":"Public","body":"@violations.any?() do |__arg3| __arg3.severity.warning? end"},"external_var":false},{"html_id":"to_json_output(io:IO)-instance-method","name":"to_json_output","abstract":false,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO)","args_html":"(io : IO)","location":{"filename":"src/policy_report.cr","line_number":83,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L83"},"def":{"name":"to_json_output","args":[{"name":"io","external_name":"io","restriction":"IO"}],"visibility":"Public","body":"JSON.build(io, indent: 2) do |json|\n  json.object do\n    json.field(\"violations\") do\n      json.array do\n        @violations.each do |v|\n          json.object do\n            json.field(\"package\", v.package)\n            json.field(\"rule\", v.rule)\n            json.field(\"severity\", v.severity.to_s.downcase)\n            json.field(\"message\", v.message)\n          end\n        end\n      end\n    end\n    json.field(\"summary\") do\n      json.object do\n        json.field(\"errors\", errors.size)\n        json.field(\"warnings\", warnings.size)\n        json.field(\"total\", @violations.size)\n      end\n    end\n  end\nend"},"external_var":false},{"html_id":"to_terminal(io:IO,colors:Bool=Shards.colors?)-instance-method","name":"to_terminal","abstract":false,"args":[{"name":"io","external_name":"io","restriction":"IO"},{"name":"colors","default_value":"Shards.colors?","external_name":"colors","restriction":"Bool"}],"args_string":"(io : IO, colors : Bool = Shards.colors?)","args_html":"(io : IO, colors : Bool = <span class=\"t\">Shards</span>.colors?)","location":{"filename":"src/policy_report.cr","line_number":59,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L59"},"def":{"name":"to_terminal","args":[{"name":"io","external_name":"io","restriction":"IO"},{"name":"colors","default_value":"Shards.colors?","external_name":"colors","restriction":"Bool"}],"visibility":"Public","body":"if clean?\n  msg = \"Policy check passed: no violations found\"\n  io.puts(colors ? msg.colorize(:green) : msg)\n  return\nend\n\nerrors.each do |v|\n  prefix = colors ? (\"ERROR\".colorize(:red)).bold : \"ERROR\"\n  io.puts(\"  #{prefix} [#{v.rule}] #{v.message}\")\nend\n\nwarnings.each do |v|\n  prefix = colors ? \"WARN\".colorize(:yellow) : \"WARN\"\n  io.puts(\"  #{prefix}  [#{v.rule}] #{v.message}\")\nend\n\nsummary_parts = [] of String\nif errors.any?\n  summary_parts << \"#{errors.size} error(s)\"\nend\nif warnings.any?\n  summary_parts << \"#{warnings.size} warning(s)\"\nend\nio.puts\nio.puts(\"Policy check: #{summary_parts.join(\", \")}\")\n"},"external_var":false},{"html_id":"violations:Array(Violation)-instance-method","name":"violations","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L17"},"def":{"name":"violations","return_type":"Array(Violation)","visibility":"Public","body":"@violations"},"external_var":false},{"html_id":"warnings-instance-method","name":"warnings","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L31"},"def":{"name":"warnings","visibility":"Public","body":"@violations.select() do |__arg1| __arg1.severity.warning? end"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/PolicyReport/Severity","path":"Shards/PolicyReport/Severity.html","kind":"enum","full_name":"Shards::PolicyReport::Severity","name":"Severity","abstract":false,"ancestors":[{"html_id":"Ashard/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"Ashard/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy_report.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L6"}],"repository_name":"Ashard","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"Error","name":"Error","value":"0"},{"id":"Warning","name":"Warning","value":"1"}],"namespace":{"html_id":"Ashard/Shards/PolicyReport","kind":"class","full_name":"Shards::PolicyReport","name":"PolicyReport"},"instance_methods":[{"html_id":"error?-instance-method","name":"error?","doc":"Returns `true` if this enum value equals `Error`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/PolicyReport/Severity.html#Error\">Error</a></code></p>","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L7"},"def":{"name":"error?","visibility":"Public","body":"self == Error"},"external_var":false},{"html_id":"warning?-instance-method","name":"warning?","doc":"Returns `true` if this enum value equals `Warning`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/PolicyReport/Severity.html#Warning\">Warning</a></code></p>","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L8"},"def":{"name":"warning?","visibility":"Public","body":"self == Warning"},"external_var":false}]},{"html_id":"Ashard/Shards/PolicyReport/Violation","path":"Shards/PolicyReport/Violation.html","kind":"struct","full_name":"Shards::PolicyReport::Violation","name":"Violation","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/policy_report.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L11"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/PolicyReport","kind":"class","full_name":"Shards::PolicyReport","name":"PolicyReport"},"constructors":[{"html_id":"new(package:String,rule:String,severity:Severity,message:String)-class-method","name":"new","abstract":false,"args":[{"name":"package","external_name":"package","restriction":"String"},{"name":"rule","external_name":"rule","restriction":"String"},{"name":"severity","external_name":"severity","restriction":"Severity"},{"name":"message","external_name":"message","restriction":"String"}],"args_string":"(package : String, rule : String, severity : Severity, message : String)","args_html":"(package : String, rule : String, severity : <a href=\"../../Shards/PolicyReport/Severity.html\">Severity</a>, message : String)","location":{"filename":"src/policy_report.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L11"},"def":{"name":"new","args":[{"name":"package","external_name":"package","restriction":"String"},{"name":"rule","external_name":"rule","restriction":"String"},{"name":"severity","external_name":"severity","restriction":"Severity"},{"name":"message","external_name":"message","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(package, rule, severity, message)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/policy_report.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L11"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@package.clone, @rule.clone, @severity.clone, @message.clone)"},"external_var":false},{"html_id":"copy_with(package_package=@package,rule_rule=@rule,severity_severity=@severity,message_message=@message)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_package","default_value":"@package","external_name":"package","restriction":""},{"name":"_rule","default_value":"@rule","external_name":"rule","restriction":""},{"name":"_severity","default_value":"@severity","external_name":"severity","restriction":""},{"name":"_message","default_value":"@message","external_name":"message","restriction":""}],"args_string":"(package _package = @package, rule _rule = @rule, severity _severity = @severity, message _message = @message)","args_html":"(package _package = @package, rule _rule = @rule, severity _severity = @severity, message _message = @message)","location":{"filename":"src/policy_report.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/policy_report.cr#L11"},"def":{"name":"copy_with","args":[{"name":"_package","default_value":"@package","external_name":"package","restriction":""},{"name":"_rule","default_value":"@rule","external_name":"rule","restriction":""},{"name":"_severity","default_value":"@severity","external_name":"severity","restriction":""},{"name":"_message","default_value":"@message","external_name":"message","restriction":""}],"visibility":"Public","body":"self.class.new(_package, _rule, _severity, _message)"},"external_var":false},{"html_id":"message:String-instance-method","name":"message","abstract":false,"def":{"name":"message","return_type":"String","visibility":"Public","body":"@message"},"external_var":false},{"html_id":"package:String-instance-method","name":"package","abstract":false,"def":{"name":"package","return_type":"String","visibility":"Public","body":"@package"},"external_var":false},{"html_id":"rule:String-instance-method","name":"rule","abstract":false,"def":{"name":"rule","return_type":"String","visibility":"Public","body":"@rule"},"external_var":false},{"html_id":"severity:Severity-instance-method","name":"severity","abstract":false,"def":{"name":"severity","return_type":"Severity","visibility":"Public","body":"@severity"},"external_var":false}]}]},{"html_id":"Ashard/Shards/PostinstallInfo","path":"Shards/PostinstallInfo.html","kind":"class","full_name":"Shards::PostinstallInfo","name":"PostinstallInfo","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/postinstall_info.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L14"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CURRENT_VERSION","name":"CURRENT_VERSION","value":"\"1.0\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Tracks postinstall script execution state across installs.\n\nPersisted at `lib/.shards.postinstall`, this tracker stores a hash of\neach shard's postinstall command and whether it has been executed.\n\nThis enables version-aware postinstall behavior:\n- First install: run the script, record its hash\n- Subsequent installs with same script: skip silently\n- Script changed: warn the user, require explicit `shards run-script`","summary":"<p>Tracks postinstall script execution state across installs.</p>","class_methods":[{"html_id":"hash_script(command:String):String-class-method","name":"hash_script","doc":"Computes a SHA-256 hash of a postinstall command string.","summary":"<p>Computes a SHA-256 hash of a postinstall command string.</p>","abstract":false,"args":[{"name":"command","external_name":"command","restriction":"String"}],"args_string":"(command : String) : String","args_html":"(command : String) : String","location":{"filename":"src/postinstall_info.cr","line_number":102,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L102"},"def":{"name":"hash_script","args":[{"name":"command","external_name":"command","restriction":"String"}],"return_type":"String","visibility":"Public","body":"\"sha256:#{Digest::SHA256.hexdigest(command)}\""},"external_var":false}],"constructors":[{"html_id":"new(path:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"::String"}],"args_string":"(path : String)","args_html":"(path : String)","location":{"filename":"src/postinstall_info.cr","line_number":35,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L35"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"load-instance-method","name":"load","doc":"Loads tracker state from the YAML file at `#path`.","summary":"<p>Loads tracker state from the YAML file at <code><a href=\"../Shards/PostinstallInfo.html#path%3AString-instance-method\">#path</a></code>.</p>","abstract":false,"location":{"filename":"src/postinstall_info.cr","line_number":41,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L41"},"def":{"name":"load","visibility":"Public","body":"begin\n  content = File.read(@path)\n  pull = YAML::PullParser.new(content)\n  pull.read_stream do\n    pull.read_document do\n      pull.each_in_mapping do\n        case pull.read_scalar\n        when \"version\"\n          pull.read_scalar\n        when \"shards\"\n          pull.each_in_mapping do\n            shard_name = pull.read_scalar\n            script_hash = \"\"\n            has_run = false\n\n            pull.each_in_mapping do\n              case pull.read_scalar\n              when \"script_hash\"\n                script_hash = pull.read_scalar\n              when \"has_run\"\n                has_run = pull.read_scalar == \"true\"\n              else\n                pull.skip\n              end\n            end\n\n            @shards[shard_name] = Entry.new(script_hash, has_run)\n          end\n        else\n          pull.skip\n        end\n      end\n    end\n  end\nensure\n  pull.try(&.close)\nend"},"external_var":false},{"html_id":"path:String-instance-method","name":"path","doc":"Absolute path to the `.shards.postinstall` file.","summary":"<p>Absolute path to the <code><a href=\"../Shards/PostinstallInfo.html#shards%3AHash%28String%2CEntry%29-instance-method\">.shards</a>.postinstall</code> file.</p>","abstract":false,"location":{"filename":"src/postinstall_info.cr","line_number":33,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L33"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"@path"},"external_var":false},{"html_id":"save-instance-method","name":"save","doc":"Persists the current tracker state to the YAML file at `#path`.","summary":"<p>Persists the current tracker state to the YAML file at <code><a href=\"../Shards/PostinstallInfo.html#path%3AString-instance-method\">#path</a></code>.</p>","abstract":false,"location":{"filename":"src/postinstall_info.cr","line_number":75,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L75"},"def":{"name":"save","visibility":"Public","body":"Dir.mkdir_p(File.dirname(@path))\n\nFile.open(@path, \"w\") do |file|\n  YAML.build(file) do |yaml|\n    yaml.mapping do\n      yaml.scalar(\"version\")\n      yaml.scalar(CURRENT_VERSION)\n\n      yaml.scalar(\"shards\")\n      yaml.mapping do\n        @shards.each do |name, entry|\n          yaml.scalar(name)\n          yaml.mapping do\n            yaml.scalar(\"script_hash\")\n            yaml.scalar(entry.script_hash)\n            yaml.scalar(\"has_run\")\n            yaml.scalar(entry.has_run.to_s)\n          end\n        end\n      end\n    end\n  end\nend\n"},"external_var":false},{"html_id":"shards:Hash(String,Entry)-instance-method","name":"shards","doc":"Map of shard name to its postinstall entry.","summary":"<p>Map of shard name to its postinstall entry.</p>","abstract":false,"location":{"filename":"src/postinstall_info.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L30"},"def":{"name":"shards","return_type":"Hash(String, Entry)","visibility":"Public","body":"@shards"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/PostinstallInfo/Entry","path":"Shards/PostinstallInfo/Entry.html","kind":"class","full_name":"Shards::PostinstallInfo::Entry","name":"Entry","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/postinstall_info.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L18"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/PostinstallInfo","kind":"class","full_name":"Shards::PostinstallInfo","name":"PostinstallInfo"},"doc":"Tracks the state of a single shard's postinstall script.","summary":"<p>Tracks the state of a single shard's postinstall script.</p>","constructors":[{"html_id":"new(script_hash:String,has_run:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"script_hash","external_name":"script_hash","restriction":"::String"},{"name":"has_run","default_value":"false","external_name":"has_run","restriction":"::Bool"}],"args_string":"(script_hash : String, has_run : Bool = false)","args_html":"(script_hash : String, has_run : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/postinstall_info.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L25"},"def":{"name":"new","args":[{"name":"script_hash","external_name":"script_hash","restriction":"::String"},{"name":"has_run","default_value":"false","external_name":"has_run","restriction":"::Bool"}],"visibility":"Public","body":"_ = allocate\n_.initialize(script_hash, has_run)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"has_run:Bool-instance-method","name":"has_run","doc":"Whether the script has been executed.","summary":"<p>Whether the script has been executed.</p>","abstract":false,"location":{"filename":"src/postinstall_info.cr","line_number":23,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L23"},"def":{"name":"has_run","return_type":"Bool","visibility":"Public","body":"@has_run"},"external_var":false},{"html_id":"has_run=(has_run:Bool)-instance-method","name":"has_run=","doc":"Whether the script has been executed.","summary":"<p>Whether the script has been executed.</p>","abstract":false,"args":[{"name":"has_run","external_name":"has_run","restriction":"Bool"}],"args_string":"(has_run : Bool)","args_html":"(has_run : Bool)","location":{"filename":"src/postinstall_info.cr","line_number":23,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L23"},"def":{"name":"has_run=","args":[{"name":"has_run","external_name":"has_run","restriction":"Bool"}],"visibility":"Public","body":"@has_run = has_run"},"external_var":false},{"html_id":"script_hash:String-instance-method","name":"script_hash","doc":"SHA-256 hash of the postinstall command string.","summary":"<p>SHA-256 hash of the postinstall command string.</p>","abstract":false,"location":{"filename":"src/postinstall_info.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L20"},"def":{"name":"script_hash","return_type":"String","visibility":"Public","body":"@script_hash"},"external_var":false},{"html_id":"script_hash=(script_hash:String)-instance-method","name":"script_hash=","doc":"SHA-256 hash of the postinstall command string.","summary":"<p>SHA-256 hash of the postinstall command string.</p>","abstract":false,"args":[{"name":"script_hash","external_name":"script_hash","restriction":"String"}],"args_string":"(script_hash : String)","args_html":"(script_hash : String)","location":{"filename":"src/postinstall_info.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/postinstall_info.cr#L20"},"def":{"name":"script_hash=","args":[{"name":"script_hash","external_name":"script_hash","restriction":"String"}],"visibility":"Public","body":"@script_hash = script_hash"},"external_var":false}]}]},{"html_id":"Ashard/Shards/PurlGenerator","path":"Shards/PurlGenerator.html","kind":"module","full_name":"Shards::PurlGenerator","name":"PurlGenerator","abstract":false,"locations":[{"filename":"src/purl.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/purl.cr#L4"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"generate(pkg:Package):String|Nil-class-method","name":"generate","doc":"Returns a Package URL (purl) string for the given package, or nil for\npath dependencies that have no meaningful remote identity.","summary":"<p>Returns a Package URL (purl) string for the given package, or nil for path dependencies that have no meaningful remote identity.</p>","abstract":false,"args":[{"name":"pkg","external_name":"pkg","restriction":"Package"}],"args_string":"(pkg : Package) : String | Nil","args_html":"(pkg : <a href=\"../Shards/Package.html\">Package</a>) : String | Nil","location":{"filename":"src/purl.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/purl.cr#L7"},"def":{"name":"generate","args":[{"name":"pkg","external_name":"pkg","restriction":"Package"}],"return_type":"String | ::Nil","visibility":"Public","body":"resolver = pkg.resolver\nsource = resolver.source\nversion = pkg.version.to_s\n\nif resolver.is_a?(PathResolver)\n  return nil\nend\n\nowner, repo = parse_owner_repo(source)\n\nif owner && repo\n  host = (URI.parse(source)).host.try(&.downcase) || \"\"\n  purl_type = case host\n  when .includes?(\"github\")\n    \"github\"\n  when .includes?(\"gitlab\")\n    \"gitlab\"\n  when .includes?(\"bitbucket\")\n    \"bitbucket\"\n  when .includes?(\"codeberg\")\n    \"codeberg\"\n  else\n    nil\n  end\n  if purl_type\n    return \"pkg:#{purl_type}/#{owner}/#{repo}@#{version}\"\n  end\nend\n\n\"pkg:generic/#{URI.encode_path(pkg.name)}@#{version}?download_url=#{URI.encode_www_form(source)}\"\n"},"external_var":false},{"html_id":"parse_owner_repo(source:String):Tuple(String|Nil,String|Nil)-class-method","name":"parse_owner_repo","doc":"Parses \"owner/repo\" from a git source URL.","summary":"<p>Parses &quot;owner/repo&quot; from a git source URL.</p>","abstract":false,"args":[{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(source : String) : Tuple(String | Nil, String | Nil)","args_html":"(source : String) : Tuple(String | Nil, String | Nil)","location":{"filename":"src/purl.cr","line_number":34,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/purl.cr#L34"},"def":{"name":"parse_owner_repo","args":[{"name":"source","external_name":"source","restriction":"String"}],"return_type":"::Tuple(String | ::Nil, String | ::Nil)","visibility":"Public","body":"begin\n  uri = URI.parse(source)\n  path = uri.path\n  if path\n  else\n    return {nil, nil}\n  end\n\n  path = path.lchop('/')\n  if path.ends_with?(\".git\")\n    path = path.rchop(\".git\")\n  end\n\n  parts = path.split('/')\n  if parts.size >= 2\n    {parts[0], parts[1]}\n  else\n    {nil, nil}\n  end\nrescue\n  {nil, nil}\nend"},"external_var":false}]},{"html_id":"Ashard/Shards/Ref","path":"Shards/Ref.html","kind":"struct","full_name":"Shards::Ref","name":"Ref","abstract":true,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/requirement.cr","line_number":49,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L49"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/FossilRef","kind":"struct","full_name":"Shards::FossilRef","name":"FossilRef"},{"html_id":"Ashard/Shards/GitRef","kind":"struct","full_name":"Shards::GitRef","name":"GitRef"},{"html_id":"Ashard/Shards/HgRef","kind":"struct","full_name":"Shards::HgRef","name":"HgRef"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/requirement.cr","line_number":49,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L49"},"def":{"name":"new","visibility":"Public","body":"x = allocate\nif x.responds_to?(:finalize)\n  ::GC.add_finalizer(x)\nend\nx\n"},"external_var":false}],"instance_methods":[{"html_id":"initialize-instance-method","name":"initialize","abstract":false,"location":{"filename":"src/requirement.cr","line_number":49,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L49"},"def":{"name":"initialize","visibility":"Public","body":""},"external_var":false}]},{"html_id":"Ashard/Shards/Requirement","path":"Shards/Requirement.html","kind":"alias","full_name":"Shards::Requirement","name":"Requirement","abstract":false,"locations":[{"filename":"src/requirement.cr","line_number":63,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L63"}],"repository_name":"Ashard","program":false,"enum":false,"alias":true,"aliased":"(Shards::Any | Shards::Ref | Shards::Version | Shards::VersionReq)","aliased_html":"<a href=\"../Shards/Any.html\">Shards::Any</a> | <a href=\"../Shards/Ref.html\">Shards::Ref</a> | <a href=\"../Shards/Version.html\">Shards::Version</a> | <a href=\"../Shards/VersionReq.html\">Shards::VersionReq</a>","const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"}},{"html_id":"Ashard/Shards/Resolver","path":"Shards/Resolver.html","kind":"class","full_name":"Shards::Resolver","name":"Resolver","abstract":true,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/resolvers/resolver.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/CrystalResolver","kind":"class","full_name":"Shards::CrystalResolver","name":"CrystalResolver"},{"html_id":"Ashard/Shards/FossilResolver","kind":"class","full_name":"Shards::FossilResolver","name":"FossilResolver"},{"html_id":"Ashard/Shards/GitResolver","kind":"class","full_name":"Shards::GitResolver","name":"GitResolver"},{"html_id":"Ashard/Shards/HgResolver","kind":"class","full_name":"Shards::HgResolver","name":"HgResolver"},{"html_id":"Ashard/Shards/PathResolver","kind":"class","full_name":"Shards::PathResolver","name":"PathResolver"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"build(key:String,name:String,source:String)-class-method","name":"build","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"name","external_name":"name","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(key : String, name : String, source : String)","args_html":"(key : String, name : String, source : String)","location":{"filename":"src/resolvers/resolver.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L15"},"def":{"name":"build","args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"name","external_name":"name","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"_, source = self.normalize_key_source(key, source)\nself.new(name, source)\n"},"external_var":false},{"html_id":"clear_resolver_cache-class-method","name":"clear_resolver_cache","abstract":false,"location":{"filename":"src/resolvers/resolver.cr","line_number":110,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L110"},"def":{"name":"clear_resolver_cache","visibility":"Public","body":"RESOLVER_CACHE.clear"},"external_var":false},{"html_id":"find_class(key:String):Resolver.class|Nil-class-method","name":"find_class","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"String"}],"args_string":"(key : String) : Resolver.class | Nil","args_html":"(key : String) : <span class=\"t\">Resolver</span>.<span class=\"k\">class</span> | Nil","location":{"filename":"src/resolvers/resolver.cr","line_number":114,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L114"},"def":{"name":"find_class","args":[{"name":"key","external_name":"key","restriction":"String"}],"return_type":"Resolver.class | Nil","visibility":"Public","body":"RESOLVER_CLASSES[key]?"},"external_var":false},{"html_id":"find_resolver(key:String,name:String,source:String)-class-method","name":"find_resolver","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"name","external_name":"name","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(key : String, name : String, source : String)","args_html":"(key : String, name : String, source : String)","location":{"filename":"src/resolvers/resolver.cr","line_number":118,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L118"},"def":{"name":"find_resolver","args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"name","external_name":"name","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"resolver_class = if self == Resolver\n  RESOLVER_CLASSES[key]? ||\n  (raise(Error.new(\"Failed can't resolve dependency #{name} (unsupported resolver)\")))\nelse\n  self\nend\n\nkey, source = resolver_class.normalize_key_source(key, source)\n\n__temp_9046f8df_1 = ResolverCacheKey.new(key, name, source)\n__temp_9046f8df_2 = RESOLVER_CACHE\n__temp_9046f8df_2[__temp_9046f8df_1]? || (\n  __temp_9046f8df_2[__temp_9046f8df_1] = begin\n    resolver_class.build(key, name, source)\n  end\n)\n"},"external_var":false},{"html_id":"normalize_key_source(key:String,source:String)-class-method","name":"normalize_key_source","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(key : String, source : String)","args_html":"(key : String, source : String)","location":{"filename":"src/resolvers/resolver.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L20"},"def":{"name":"normalize_key_source","args":[{"name":"key","external_name":"key","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"{key, source}"},"external_var":false},{"html_id":"register_resolver(key,resolver)-class-method","name":"register_resolver","abstract":false,"args":[{"name":"key","external_name":"key","restriction":""},{"name":"resolver","external_name":"resolver","restriction":""}],"args_string":"(key, resolver)","args_html":"(key, resolver)","location":{"filename":"src/resolvers/resolver.cr","line_number":106,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L106"},"def":{"name":"register_resolver","args":[{"name":"key","external_name":"key","restriction":""},{"name":"resolver","external_name":"resolver","restriction":""}],"visibility":"Public","body":"RESOLVER_CLASSES[key] = resolver"},"external_var":false}],"constructors":[{"html_id":"new(name:String,source:String)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(name : String, source : String)","args_html":"(name : String, source : String)","location":{"filename":"src/resolvers/resolver.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L12"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, source)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"==(other:Resolver)-instance-method","name":"==","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"Resolver"}],"args_string":"(other : Resolver)","args_html":"(other : <a href=\"../Shards/Resolver.html\">Resolver</a>)","location":{"filename":"src/resolvers/resolver.cr","line_number":24,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L24"},"def":{"name":"==","args":[{"name":"other","external_name":"other","restriction":"Resolver"}],"visibility":"Public","body":"if super(other)\n  return true\nend\nif self.class == other.class\nelse\n  return false\nend\n(name == other.name) && (source == other.source)\n"},"external_var":false},{"html_id":"available_releases:Array(Version)-instance-method","name":"available_releases","abstract":true,"location":{"filename":"src/resolvers/resolver.cr","line_number":57,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L57"},"def":{"name":"available_releases","return_type":"Array(Version)","visibility":"Public","body":""},"external_var":false},{"html_id":"install_sources(version:Version,install_path:String)-instance-method","name":"install_sources","abstract":true,"args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"args_string":"(version : Version, install_path : String)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>, install_path : String)","location":{"filename":"src/resolvers/resolver.cr","line_number":88,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L88"},"def":{"name":"install_sources","args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"install_path","external_name":"install_path","restriction":"String"}],"visibility":"Public","body":""},"external_var":false},{"html_id":"latest_version_for_ref(ref:Ref|Nil):Version-instance-method","name":"latest_version_for_ref","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"Ref | ::Nil"}],"args_string":"(ref : Ref | Nil) : Version","args_html":"(ref : <a href=\"../Shards/Ref.html\">Ref</a> | Nil) : <a href=\"../Shards/Version.html\">Version</a>","location":{"filename":"src/resolvers/resolver.cr","line_number":59,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L59"},"def":{"name":"latest_version_for_ref","args":[{"name":"ref","external_name":"ref","restriction":"Ref | ::Nil"}],"return_type":"Version","visibility":"Public","body":"raise(\"Unsupported ref type for this resolver: #{ref}\")"},"external_var":false},{"html_id":"matches_ref?(ref:Ref,version:Version)-instance-method","name":"matches_ref?","abstract":false,"args":[{"name":"ref","external_name":"ref","restriction":"Ref"},{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(ref : Ref, version : Version)","args_html":"(ref : <a href=\"../Shards/Ref.html\">Ref</a>, version : <a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/resolvers/resolver.cr","line_number":63,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L63"},"def":{"name":"matches_ref?","args":[{"name":"ref","external_name":"ref","restriction":"Ref"},{"name":"version","external_name":"version","restriction":"Version"}],"visibility":"Public","body":"false"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/resolvers/resolver.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L9"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"parse_requirement(params:Hash(String,String)):Requirement-instance-method","name":"parse_requirement","abstract":false,"args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"args_string":"(params : Hash(String, String)) : Requirement","args_html":"(params : Hash(String, String)) : <a href=\"../Shards/Requirement.html\">Requirement</a>","location":{"filename":"src/resolvers/resolver.cr","line_number":94,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L94"},"def":{"name":"parse_requirement","args":[{"name":"params","external_name":"params","restriction":"Hash(String, String)"}],"return_type":"Requirement","visibility":"Public","body":"if version = params[\"version\"]?\n  VersionReq.new(version)\nelse\n  Any\nend"},"external_var":false},{"html_id":"read_spec(version:Version):String|Nil-instance-method","name":"read_spec","abstract":true,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String | Nil","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String | Nil","location":{"filename":"src/resolvers/resolver.cr","line_number":87,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L87"},"def":{"name":"read_spec","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String | ::Nil","visibility":"Public","body":""},"external_var":false},{"html_id":"report_version(version:Version):String-instance-method","name":"report_version","abstract":true,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : String","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : String","location":{"filename":"src/resolvers/resolver.cr","line_number":89,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L89"},"def":{"name":"report_version","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"String","visibility":"Public","body":""},"external_var":false},{"html_id":"source:String-instance-method","name":"source","abstract":false,"location":{"filename":"src/resolvers/resolver.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L10"},"def":{"name":"source","return_type":"String","visibility":"Public","body":"@source"},"external_var":false},{"html_id":"spec(version:Version):Spec-instance-method","name":"spec","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version) : Spec","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>) : <a href=\"../Shards/Spec.html\">Spec</a>","location":{"filename":"src/resolvers/resolver.cr","line_number":67,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L67"},"def":{"name":"spec","args":[{"name":"version","external_name":"version","restriction":"Version"}],"return_type":"Spec","visibility":"Public","body":"if spec = load_spec(version)\n  spec.version = version\n  spec\nelse\n  Spec.new(name, version, self)\nend"},"external_var":false},{"html_id":"to_s(io:IO)-instance-method","name":"to_s","doc":"Appends a short String representation of this object\nwhich includes its class name and its object address.\n\n```\nclass Person\n  def initialize(@name : String, @age : Int32)\n  end\nend\n\nPerson.new(\"John\", 32).to_s # => #<Person:0x10a199f20>\n```","summary":"<p>Appends a short String representation of this object which includes its class name and its object address.</p>","abstract":false,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO)","args_html":"(io : IO)","location":{"filename":"src/resolvers/resolver.cr","line_number":34,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L34"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":"IO"}],"visibility":"Public","body":"io << yaml_source_entry"},"external_var":false},{"html_id":"update_local_cache-instance-method","name":"update_local_cache","abstract":false,"location":{"filename":"src/resolvers/resolver.cr","line_number":91,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L91"},"def":{"name":"update_local_cache","visibility":"Public","body":""},"external_var":false},{"html_id":"versions_for(req:Requirement):Array(Version)-instance-method","name":"versions_for","abstract":false,"args":[{"name":"req","external_name":"req","restriction":"Requirement"}],"args_string":"(req : Requirement) : Array(Version)","args_html":"(req : <a href=\"../Shards/Requirement.html\">Requirement</a>) : Array(<a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/resolvers/resolver.cr","line_number":38,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L38"},"def":{"name":"versions_for","args":[{"name":"req","external_name":"req","restriction":"Requirement"}],"return_type":"Array(Version)","visibility":"Public","body":"case req\nwhen Version\n  [req]\nwhen Ref\n  [latest_version_for_ref(req)]\nwhen VersionReq\n  Versions.resolve(available_releases, req)\nwhen Any\n  releases = available_releases\n  if releases.empty?\n    [latest_version_for_ref(nil)]\n  else\n    releases\n  end\nelse\n  raise(Error.new(\"Unexpected requirement type: #{req}\"))\nend"},"external_var":false},{"html_id":"yaml_source_entry-instance-method","name":"yaml_source_entry","abstract":false,"location":{"filename":"src/resolvers/resolver.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/resolvers/resolver.cr#L30"},"def":{"name":"yaml_source_entry","visibility":"Public","body":"\"#{self.class.key}: #{source}\""},"external_var":false}]},{"html_id":"Ashard/Shards/Script","path":"Shards/Script.html","kind":"module","full_name":"Shards::Script","name":"Script","abstract":false,"locations":[{"filename":"src/script.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/script.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"run(path,command,script_name,dependency_name)-class-method","name":"run","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""},{"name":"command","external_name":"command","restriction":""},{"name":"script_name","external_name":"script_name","restriction":""},{"name":"dependency_name","external_name":"dependency_name","restriction":""}],"args_string":"(path, command, script_name, dependency_name)","args_html":"(path, command, script_name, dependency_name)","location":{"filename":"src/script.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/script.cr#L6"},"def":{"name":"run","args":[{"name":"path","external_name":"path","restriction":""},{"name":"command","external_name":"command","restriction":""},{"name":"script_name","external_name":"script_name","restriction":""},{"name":"dependency_name","external_name":"dependency_name","restriction":""}],"visibility":"Public","body":"Dir.cd(path) do\n  output = IO::Memory.new\n  status = Process.run(command, shell: true, output: output, error: output)\n  if status.success?\n  else\n    raise(Error.new(\"Failed #{script_name} of #{dependency_name} on #{command}:\\n#{output.to_s.rstrip}\"))\n  end\nend"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/Script/Error","path":"Shards/Script/Error.html","kind":"class","full_name":"Shards::Script::Error","name":"Error","abstract":false,"superclass":{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},"ancestors":[{"html_id":"Ashard/Shards/Error","kind":"class","full_name":"Shards::Error","name":"Error"},{"html_id":"Ashard/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/script.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/script.cr#L3"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Script","kind":"module","full_name":"Shards::Script","name":"Script"}}]},{"html_id":"Ashard/Shards/Severity","path":"Shards/Severity.html","kind":"enum","full_name":"Shards::Severity","name":"Severity","abstract":false,"ancestors":[{"html_id":"Ashard/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"Ashard/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/vulnerability_scanner.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L27"}],"repository_name":"Ashard","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"Unknown","name":"Unknown","value":"0"},{"id":"Low","name":"Low","value":"1"},{"id":"Medium","name":"Medium","value":"2"},{"id":"High","name":"High","value":"3"},{"id":"Critical","name":"Critical","value":"4"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Severity levels with ordering support.","summary":"<p>Severity levels with ordering support.</p>","constructors":[{"html_id":"parse(str:String):Severity-class-method","name":"parse","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String) : Severity","args_html":"(str : String) : <a href=\"../Shards/Severity.html\">Severity</a>","location":{"filename":"src/vulnerability_scanner.cr","line_number":34,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L34"},"def":{"name":"parse","args":[{"name":"str","external_name":"str","restriction":"String"}],"return_type":"Severity","visibility":"Public","body":"case str.downcase\nwhen \"low\"\n  Low\nwhen \"medium\"\n  Medium\nwhen \"high\"\n  High\nwhen \"critical\"\n  Critical\nelse\n  Unknown\nend"},"external_var":false}],"instance_methods":[{"html_id":"at_or_above?(threshold:Severity):Bool-instance-method","name":"at_or_above?","doc":"Returns true if this severity is at or above the given threshold.","summary":"<p>Returns true if this severity is at or above the given threshold.</p>","abstract":false,"args":[{"name":"threshold","external_name":"threshold","restriction":"Severity"}],"args_string":"(threshold : Severity) : Bool","args_html":"(threshold : <a href=\"../Shards/Severity.html\">Severity</a>) : Bool","location":{"filename":"src/vulnerability_scanner.cr","line_number":45,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L45"},"def":{"name":"at_or_above?","args":[{"name":"threshold","external_name":"threshold","restriction":"Severity"}],"return_type":"Bool","visibility":"Public","body":"self.value >= threshold.value"},"external_var":false},{"html_id":"critical?-instance-method","name":"critical?","doc":"Returns `true` if this enum value equals `Critical`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../Shards/Severity.html#Critical\">Critical</a></code></p>","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":32,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L32"},"def":{"name":"critical?","visibility":"Public","body":"self == Critical"},"external_var":false},{"html_id":"high?-instance-method","name":"high?","doc":"Returns `true` if this enum value equals `High`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../Shards/Severity.html#High\">High</a></code></p>","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L31"},"def":{"name":"high?","visibility":"Public","body":"self == High"},"external_var":false},{"html_id":"low?-instance-method","name":"low?","doc":"Returns `true` if this enum value equals `Low`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../Shards/Severity.html#Low\">Low</a></code></p>","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L29"},"def":{"name":"low?","visibility":"Public","body":"self == Low"},"external_var":false},{"html_id":"medium?-instance-method","name":"medium?","doc":"Returns `true` if this enum value equals `Medium`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../Shards/Severity.html#Medium\">Medium</a></code></p>","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":30,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L30"},"def":{"name":"medium?","visibility":"Public","body":"self == Medium"},"external_var":false},{"html_id":"unknown?-instance-method","name":"unknown?","doc":"Returns `true` if this enum value equals `Unknown`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../Shards/Severity.html#Unknown\">Unknown</a></code></p>","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L28"},"def":{"name":"unknown?","visibility":"Public","body":"self == Unknown"},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX","path":"Shards/SPDX.html","kind":"module","full_name":"Shards::SPDX","name":"SPDX","abstract":false,"locations":[{"filename":"src/spdx.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"LICENSES","name":"LICENSES","value":"{\"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)}"}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"category_for(id:String):Category-class-method","name":"category_for","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String) : Category","args_html":"(id : String) : <a href=\"../Shards/SPDX/Category.html\">Category</a>","location":{"filename":"src/spdx.cr","line_number":298,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L298"},"def":{"name":"category_for","args":[{"name":"id","external_name":"id","restriction":"String"}],"return_type":"Category","visibility":"Public","body":"LICENSES[id]?.try(&.category) || Category::Unknown"},"external_var":false},{"html_id":"lookup(id:String):LicenseInfo|Nil-class-method","name":"lookup","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String) : LicenseInfo | Nil","args_html":"(id : String) : <a href=\"../Shards/SPDX/LicenseInfo.html\">LicenseInfo</a> | Nil","location":{"filename":"src/spdx.cr","line_number":294,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L294"},"def":{"name":"lookup","args":[{"name":"id","external_name":"id","restriction":"String"}],"return_type":"LicenseInfo | ::Nil","visibility":"Public","body":"LICENSES[id]?"},"external_var":false},{"html_id":"parse(expression:String):Expression-class-method","name":"parse","abstract":false,"args":[{"name":"expression","external_name":"expression","restriction":"String"}],"args_string":"(expression : String) : Expression","args_html":"(expression : String) : <a href=\"../Shards/SPDX/Expression.html\">Expression</a>","location":{"filename":"src/spdx.cr","line_number":302,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L302"},"def":{"name":"parse","args":[{"name":"expression","external_name":"expression","restriction":"String"}],"return_type":"Expression","visibility":"Public","body":"Parser.parse(expression)"},"external_var":false},{"html_id":"valid_id?(id:String):Bool-class-method","name":"valid_id?","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String) : Bool","args_html":"(id : String) : Bool","location":{"filename":"src/spdx.cr","line_number":290,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L290"},"def":{"name":"valid_id?","args":[{"name":"id","external_name":"id","restriction":"String"}],"return_type":"Bool","visibility":"Public","body":"(LICENSES.has_key?(id)) || (id.starts_with?(\"LicenseRef-\"))"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/SPDX/AndExpression","path":"Shards/SPDX/AndExpression.html","kind":"class","full_name":"Shards::SPDX::AndExpression","name":"AndExpression","abstract":false,"superclass":{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},"ancestors":[{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":119,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L119"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"constructors":[{"html_id":"new(left:Expression,right:Expression)-class-method","name":"new","abstract":false,"args":[{"name":"left","external_name":"left","restriction":"Expression"},{"name":"right","external_name":"right","restriction":"Expression"}],"args_string":"(left : Expression, right : Expression)","args_html":"(left : <a href=\"../../Shards/SPDX/Expression.html\">Expression</a>, right : <a href=\"../../Shards/SPDX/Expression.html\">Expression</a>)","location":{"filename":"src/spdx.cr","line_number":123,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L123"},"def":{"name":"new","args":[{"name":"left","external_name":"left","restriction":"Expression"},{"name":"right","external_name":"right","restriction":"Expression"}],"visibility":"Public","body":"_ = allocate\n_.initialize(left, right)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"left:Expression-instance-method","name":"left","abstract":false,"location":{"filename":"src/spdx.cr","line_number":120,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L120"},"def":{"name":"left","return_type":"Expression","visibility":"Public","body":"@left"},"external_var":false},{"html_id":"license_ids:Array(String)-instance-method","name":"license_ids","abstract":false,"location":{"filename":"src/spdx.cr","line_number":126,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L126"},"def":{"name":"license_ids","return_type":"Array(String)","visibility":"Public","body":"left.license_ids + right.license_ids"},"external_var":false},{"html_id":"right:Expression-instance-method","name":"right","abstract":false,"location":{"filename":"src/spdx.cr","line_number":121,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L121"},"def":{"name":"right","return_type":"Expression","visibility":"Public","body":"@right"},"external_var":false},{"html_id":"satisfied_by?(allowed:Set(String)):Bool-instance-method","name":"satisfied_by?","abstract":false,"args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"args_string":"(allowed : Set(String)) : Bool","args_html":"(allowed : Set(String)) : Bool","location":{"filename":"src/spdx.cr","line_number":130,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L130"},"def":{"name":"satisfied_by?","args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"return_type":"Bool","visibility":"Public","body":"(left.satisfied_by?(allowed)) && (right.satisfied_by?(allowed))"},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX/Category","path":"Shards/SPDX/Category.html","kind":"enum","full_name":"Shards::SPDX::Category","name":"Category","abstract":false,"ancestors":[{"html_id":"Ashard/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"Ashard/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L3"}],"repository_name":"Ashard","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"Permissive","name":"Permissive","value":"0"},{"id":"WeakCopyleft","name":"WeakCopyleft","value":"1"},{"id":"StrongCopyleft","name":"StrongCopyleft","value":"2"},{"id":"NonCommercial","name":"NonCommercial","value":"3"},{"id":"PublicDomain","name":"PublicDomain","value":"4"},{"id":"Proprietary","name":"Proprietary","value":"5"},{"id":"Unknown","name":"Unknown","value":"6"}],"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"instance_methods":[{"html_id":"non_commercial?-instance-method","name":"non_commercial?","doc":"Returns `true` if this enum value equals `NonCommercial`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/SPDX/Category.html#NonCommercial\">NonCommercial</a></code></p>","abstract":false,"location":{"filename":"src/spdx.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L7"},"def":{"name":"non_commercial?","visibility":"Public","body":"self == NonCommercial"},"external_var":false},{"html_id":"permissive?-instance-method","name":"permissive?","doc":"Returns `true` if this enum value equals `Permissive`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/SPDX/Category.html#Permissive\">Permissive</a></code></p>","abstract":false,"location":{"filename":"src/spdx.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L4"},"def":{"name":"permissive?","visibility":"Public","body":"self == Permissive"},"external_var":false},{"html_id":"proprietary?-instance-method","name":"proprietary?","doc":"Returns `true` if this enum value equals `Proprietary`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/SPDX/Category.html#Proprietary\">Proprietary</a></code></p>","abstract":false,"location":{"filename":"src/spdx.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L9"},"def":{"name":"proprietary?","visibility":"Public","body":"self == Proprietary"},"external_var":false},{"html_id":"public_domain?-instance-method","name":"public_domain?","doc":"Returns `true` if this enum value equals `PublicDomain`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/SPDX/Category.html#PublicDomain\">PublicDomain</a></code></p>","abstract":false,"location":{"filename":"src/spdx.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L8"},"def":{"name":"public_domain?","visibility":"Public","body":"self == PublicDomain"},"external_var":false},{"html_id":"strong_copyleft?-instance-method","name":"strong_copyleft?","doc":"Returns `true` if this enum value equals `StrongCopyleft`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/SPDX/Category.html#StrongCopyleft\">StrongCopyleft</a></code></p>","abstract":false,"location":{"filename":"src/spdx.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L6"},"def":{"name":"strong_copyleft?","visibility":"Public","body":"self == StrongCopyleft"},"external_var":false},{"html_id":"unknown?-instance-method","name":"unknown?","doc":"Returns `true` if this enum value equals `Unknown`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/SPDX/Category.html#Unknown\">Unknown</a></code></p>","abstract":false,"location":{"filename":"src/spdx.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L10"},"def":{"name":"unknown?","visibility":"Public","body":"self == Unknown"},"external_var":false},{"html_id":"weak_copyleft?-instance-method","name":"weak_copyleft?","doc":"Returns `true` if this enum value equals `WeakCopyleft`","summary":"<p>Returns <code>true</code> if this enum value equals <code><a href=\"../../Shards/SPDX/Category.html#WeakCopyleft\">WeakCopyleft</a></code></p>","abstract":false,"location":{"filename":"src/spdx.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L5"},"def":{"name":"weak_copyleft?","visibility":"Public","body":"self == WeakCopyleft"},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX/Expression","path":"Shards/SPDX/Expression.html","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression","abstract":true,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":82,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L82"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"Ashard/Shards/SPDX/AndExpression","kind":"class","full_name":"Shards::SPDX::AndExpression","name":"AndExpression"},{"html_id":"Ashard/Shards/SPDX/OrExpression","kind":"class","full_name":"Shards::SPDX::OrExpression","name":"OrExpression"},{"html_id":"Ashard/Shards/SPDX/SimpleExpression","kind":"class","full_name":"Shards::SPDX::SimpleExpression","name":"SimpleExpression"},{"html_id":"Ashard/Shards/SPDX/WithExpression","kind":"class","full_name":"Shards::SPDX::WithExpression","name":"WithExpression"}],"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"instance_methods":[{"html_id":"license_ids:Array(String)-instance-method","name":"license_ids","abstract":true,"location":{"filename":"src/spdx.cr","line_number":83,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L83"},"def":{"name":"license_ids","return_type":"Array(String)","visibility":"Public","body":""},"external_var":false},{"html_id":"satisfied_by?(allowed:Set(String)):Bool-instance-method","name":"satisfied_by?","abstract":true,"args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"args_string":"(allowed : Set(String)) : Bool","args_html":"(allowed : Set(String)) : Bool","location":{"filename":"src/spdx.cr","line_number":84,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L84"},"def":{"name":"satisfied_by?","args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"return_type":"Bool","visibility":"Public","body":""},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX/LicenseInfo","path":"Shards/SPDX/LicenseInfo.html","kind":"struct","full_name":"Shards::SPDX::LicenseInfo","name":"LicenseInfo","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L13"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"constructors":[{"html_id":"new(id:String,name:String,osi_approved:Bool,category:Category)-class-method","name":"new","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"},{"name":"name","external_name":"name","restriction":"String"},{"name":"osi_approved","external_name":"osi_approved","restriction":"Bool"},{"name":"category","external_name":"category","restriction":"Category"}],"args_string":"(id : String, name : String, osi_approved : Bool, category : Category)","args_html":"(id : String, name : String, osi_approved : Bool, category : <a href=\"../../Shards/SPDX/Category.html\">Category</a>)","location":{"filename":"src/spdx.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L13"},"def":{"name":"new","args":[{"name":"id","external_name":"id","restriction":"String"},{"name":"name","external_name":"name","restriction":"String"},{"name":"osi_approved","external_name":"osi_approved","restriction":"Bool"},{"name":"category","external_name":"category","restriction":"Category"}],"visibility":"Public","body":"_ = allocate\n_.initialize(id, name, osi_approved, category)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"category:Category-instance-method","name":"category","abstract":false,"def":{"name":"category","return_type":"Category","visibility":"Public","body":"@category"},"external_var":false},{"html_id":"clone-instance-method","name":"clone","abstract":false,"location":{"filename":"src/spdx.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L13"},"def":{"name":"clone","visibility":"Public","body":"self.class.new(@id.clone, @name.clone, @osi_approved.clone, @category.clone)"},"external_var":false},{"html_id":"copy_with(id_id=@id,name_name=@name,osi_approved_osi_approved=@osi_approved,category_category=@category)-instance-method","name":"copy_with","abstract":false,"args":[{"name":"_id","default_value":"@id","external_name":"id","restriction":""},{"name":"_name","default_value":"@name","external_name":"name","restriction":""},{"name":"_osi_approved","default_value":"@osi_approved","external_name":"osi_approved","restriction":""},{"name":"_category","default_value":"@category","external_name":"category","restriction":""}],"args_string":"(id _id = @id, name _name = @name, osi_approved _osi_approved = @osi_approved, category _category = @category)","args_html":"(id _id = @id, name _name = @name, osi_approved _osi_approved = @osi_approved, category _category = @category)","location":{"filename":"src/spdx.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L13"},"def":{"name":"copy_with","args":[{"name":"_id","default_value":"@id","external_name":"id","restriction":""},{"name":"_name","default_value":"@name","external_name":"name","restriction":""},{"name":"_osi_approved","default_value":"@osi_approved","external_name":"osi_approved","restriction":""},{"name":"_category","default_value":"@category","external_name":"category","restriction":""}],"visibility":"Public","body":"self.class.new(_id, _name, _osi_approved, _category)"},"external_var":false},{"html_id":"id:String-instance-method","name":"id","abstract":false,"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"osi_approved:Bool-instance-method","name":"osi_approved","abstract":false,"def":{"name":"osi_approved","return_type":"Bool","visibility":"Public","body":"@osi_approved"},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX/OrExpression","path":"Shards/SPDX/OrExpression.html","kind":"class","full_name":"Shards::SPDX::OrExpression","name":"OrExpression","abstract":false,"superclass":{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},"ancestors":[{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":135,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L135"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"constructors":[{"html_id":"new(left:Expression,right:Expression)-class-method","name":"new","abstract":false,"args":[{"name":"left","external_name":"left","restriction":"Expression"},{"name":"right","external_name":"right","restriction":"Expression"}],"args_string":"(left : Expression, right : Expression)","args_html":"(left : <a href=\"../../Shards/SPDX/Expression.html\">Expression</a>, right : <a href=\"../../Shards/SPDX/Expression.html\">Expression</a>)","location":{"filename":"src/spdx.cr","line_number":139,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L139"},"def":{"name":"new","args":[{"name":"left","external_name":"left","restriction":"Expression"},{"name":"right","external_name":"right","restriction":"Expression"}],"visibility":"Public","body":"_ = allocate\n_.initialize(left, right)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"left:Expression-instance-method","name":"left","abstract":false,"location":{"filename":"src/spdx.cr","line_number":136,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L136"},"def":{"name":"left","return_type":"Expression","visibility":"Public","body":"@left"},"external_var":false},{"html_id":"license_ids:Array(String)-instance-method","name":"license_ids","abstract":false,"location":{"filename":"src/spdx.cr","line_number":142,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L142"},"def":{"name":"license_ids","return_type":"Array(String)","visibility":"Public","body":"left.license_ids + right.license_ids"},"external_var":false},{"html_id":"right:Expression-instance-method","name":"right","abstract":false,"location":{"filename":"src/spdx.cr","line_number":137,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L137"},"def":{"name":"right","return_type":"Expression","visibility":"Public","body":"@right"},"external_var":false},{"html_id":"satisfied_by?(allowed:Set(String)):Bool-instance-method","name":"satisfied_by?","abstract":false,"args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"args_string":"(allowed : Set(String)) : Bool","args_html":"(allowed : Set(String)) : Bool","location":{"filename":"src/spdx.cr","line_number":146,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L146"},"def":{"name":"satisfied_by?","args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"return_type":"Bool","visibility":"Public","body":"(left.satisfied_by?(allowed)) || (right.satisfied_by?(allowed))"},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX/Parser","path":"Shards/SPDX/Parser.html","kind":"class","full_name":"Shards::SPDX::Parser","name":"Parser","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":153,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L153"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"class_methods":[{"html_id":"parse(input:String):Expression-class-method","name":"parse","abstract":false,"args":[{"name":"input","external_name":"input","restriction":"String"}],"args_string":"(input : String) : Expression","args_html":"(input : String) : <a href=\"../../Shards/SPDX/Expression.html\">Expression</a>","location":{"filename":"src/spdx.cr","line_number":157,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L157"},"def":{"name":"parse","args":[{"name":"input","external_name":"input","restriction":"String"}],"return_type":"Expression","visibility":"Public","body":"(new(input)).parse"},"external_var":false}],"instance_methods":[{"html_id":"parse:Expression-instance-method","name":"parse","abstract":false,"location":{"filename":"src/spdx.cr","line_number":166,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L166"},"def":{"name":"parse","return_type":"Expression","visibility":"Public","body":"if @tokens.empty?\n  raise(Error.new(\"Empty SPDX expression\"))\nend\nexpr = parse_or\nif @pos >= @tokens.size\nelse\n  raise(Error.new(\"Unexpected token '#{@tokens[@pos]}' at position #{@pos} in SPDX expression\"))\nend\nexpr\n"},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX/SimpleExpression","path":"Shards/SPDX/SimpleExpression.html","kind":"class","full_name":"Shards::SPDX::SimpleExpression","name":"SimpleExpression","abstract":false,"superclass":{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},"ancestors":[{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":87,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L87"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"constructors":[{"html_id":"new(id:String,or_later:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"},{"name":"or_later","default_value":"false","external_name":"or_later","restriction":"Bool"}],"args_string":"(id : String, or_later : Bool = false)","args_html":"(id : String, or_later : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/spdx.cr","line_number":91,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L91"},"def":{"name":"new","args":[{"name":"id","external_name":"id","restriction":"String"},{"name":"or_later","default_value":"false","external_name":"or_later","restriction":"Bool"}],"visibility":"Public","body":"_ = allocate\n_.initialize(id, or_later)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/spdx.cr","line_number":88,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L88"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"},"external_var":false},{"html_id":"license_ids:Array(String)-instance-method","name":"license_ids","abstract":false,"location":{"filename":"src/spdx.cr","line_number":94,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L94"},"def":{"name":"license_ids","return_type":"Array(String)","visibility":"Public","body":"[id]"},"external_var":false},{"html_id":"or_later:Bool-instance-method","name":"or_later","abstract":false,"location":{"filename":"src/spdx.cr","line_number":89,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L89"},"def":{"name":"or_later","return_type":"Bool","visibility":"Public","body":"@or_later"},"external_var":false},{"html_id":"satisfied_by?(allowed:Set(String)):Bool-instance-method","name":"satisfied_by?","abstract":false,"args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"args_string":"(allowed : Set(String)) : Bool","args_html":"(allowed : Set(String)) : Bool","location":{"filename":"src/spdx.cr","line_number":98,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L98"},"def":{"name":"satisfied_by?","args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"return_type":"Bool","visibility":"Public","body":"allowed.includes?(id)"},"external_var":false}]},{"html_id":"Ashard/Shards/SPDX/WithExpression","path":"Shards/SPDX/WithExpression.html","kind":"class","full_name":"Shards::SPDX::WithExpression","name":"WithExpression","abstract":false,"superclass":{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},"ancestors":[{"html_id":"Ashard/Shards/SPDX/Expression","kind":"class","full_name":"Shards::SPDX::Expression","name":"Expression"},{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spdx.cr","line_number":103,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L103"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/SPDX","kind":"module","full_name":"Shards::SPDX","name":"SPDX"},"constructors":[{"html_id":"new(license:SimpleExpression,exception:String)-class-method","name":"new","abstract":false,"args":[{"name":"license","external_name":"license","restriction":"SimpleExpression"},{"name":"exception","external_name":"exception","restriction":"String"}],"args_string":"(license : SimpleExpression, exception : String)","args_html":"(license : <a href=\"../../Shards/SPDX/SimpleExpression.html\">SimpleExpression</a>, exception : String)","location":{"filename":"src/spdx.cr","line_number":107,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L107"},"def":{"name":"new","args":[{"name":"license","external_name":"license","restriction":"SimpleExpression"},{"name":"exception","external_name":"exception","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(license, exception)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"exception:String-instance-method","name":"exception","abstract":false,"location":{"filename":"src/spdx.cr","line_number":105,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L105"},"def":{"name":"exception","return_type":"String","visibility":"Public","body":"@exception"},"external_var":false},{"html_id":"license:SimpleExpression-instance-method","name":"license","abstract":false,"location":{"filename":"src/spdx.cr","line_number":104,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L104"},"def":{"name":"license","return_type":"SimpleExpression","visibility":"Public","body":"@license"},"external_var":false},{"html_id":"license_ids:Array(String)-instance-method","name":"license_ids","abstract":false,"location":{"filename":"src/spdx.cr","line_number":110,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L110"},"def":{"name":"license_ids","return_type":"Array(String)","visibility":"Public","body":"license.license_ids"},"external_var":false},{"html_id":"satisfied_by?(allowed:Set(String)):Bool-instance-method","name":"satisfied_by?","abstract":false,"args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"args_string":"(allowed : Set(String)) : Bool","args_html":"(allowed : Set(String)) : Bool","location":{"filename":"src/spdx.cr","line_number":114,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spdx.cr#L114"},"def":{"name":"satisfied_by?","args":[{"name":"allowed","external_name":"allowed","restriction":"Set(String)"}],"return_type":"Bool","visibility":"Public","body":"license.satisfied_by?(allowed)"},"external_var":false}]}]},{"html_id":"Ashard/Shards/Spec","path":"Shards/Spec.html","kind":"class","full_name":"Shards::Spec","name":"Spec","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spec.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L9"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"from_file(path,validate=false)-class-method","name":"from_file","abstract":false,"args":[{"name":"path","external_name":"path","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"args_string":"(path, validate = false)","args_html":"(path, validate = <span class=\"n\">false</span>)","location":{"filename":"src/spec.cr","line_number":120,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L120"},"def":{"name":"from_file","args":[{"name":"path","external_name":"path","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"visibility":"Public","body":"if File.directory?(path)\n  path = File.join(path, SPEC_FILENAME)\nend\nif File.exists?(path)\nelse\n  raise(Error.new(\"Missing #{File.basename(path)}\"))\nend\nfrom_yaml(File.read(path), path, validate)\n"},"external_var":false},{"html_id":"from_yaml(input,filename=SPEC_FILENAME,validate=false)-class-method","name":"from_yaml","abstract":false,"args":[{"name":"input","external_name":"input","restriction":""},{"name":"filename","default_value":"SPEC_FILENAME","external_name":"filename","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"args_string":"(input, filename = SPEC_FILENAME, validate = false)","args_html":"(input, filename = <span class=\"t\">SPEC_FILENAME</span>, validate = <span class=\"n\">false</span>)","location":{"filename":"src/spec.cr","line_number":126,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L126"},"def":{"name":"from_yaml","args":[{"name":"input","external_name":"input","restriction":""},{"name":"filename","default_value":"SPEC_FILENAME","external_name":"filename","restriction":""},{"name":"validate","default_value":"false","external_name":"validate","restriction":""}],"visibility":"Public","body":"begin\n  parser = YAML::PullParser.new(input)\n  parser.read_stream do\n    parser.read_document do\n      new(parser, validate)\n    end\n  end\nrescue ex : YAML::ParseException\n  raise(ParseError.new(ex.message, input, filename, ex.line_number, ex.column_number))\nensure\n  if parser\n    parser.close\n  end\nend"},"external_var":false}],"constructors":[{"html_id":"new(name:String,version:Version,resolver:Resolver|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"version","external_name":"version","restriction":"Version"},{"name":"resolver","default_value":"nil","external_name":"resolver","restriction":"Resolver | ::Nil"}],"args_string":"(name : String, version : Version, resolver : Resolver | Nil = nil)","args_html":"(name : String, version : <a href=\"../Shards/Version.html\">Version</a>, resolver : <a href=\"../Shards/Resolver.html\">Resolver</a> | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/spec.cr","line_number":139,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L139"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"version","external_name":"version","restriction":"Version"},{"name":"resolver","default_value":"nil","external_name":"resolver","restriction":"Resolver | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, version, resolver)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"ai_assistant:AIAssistant|Nil-instance-method","name":"ai_assistant","abstract":false,"location":{"filename":"src/spec.cr","line_number":153,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L153"},"def":{"name":"ai_assistant","return_type":"AIAssistant | ::Nil","visibility":"Public","body":"@ai_assistant"},"external_var":false},{"html_id":"ai_docs:AIDocs|Nil-instance-method","name":"ai_docs","abstract":false,"location":{"filename":"src/spec.cr","line_number":152,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L152"},"def":{"name":"ai_docs","return_type":"AIDocs | ::Nil","visibility":"Public","body":"@ai_docs"},"external_var":false},{"html_id":"authors-instance-method","name":"authors","abstract":false,"location":{"filename":"src/spec.cr","line_number":268,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L268"},"def":{"name":"authors","visibility":"Public","body":"@authors || (@authors = [] of Author)"},"external_var":false},{"html_id":"crystal:String|Nil-instance-method","name":"crystal","abstract":false,"location":{"filename":"src/spec.cr","line_number":149,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L149"},"def":{"name":"crystal","return_type":"String | ::Nil","visibility":"Public","body":"@crystal"},"external_var":false},{"html_id":"dependencies-instance-method","name":"dependencies","abstract":false,"location":{"filename":"src/spec.cr","line_number":272,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L272"},"def":{"name":"dependencies","visibility":"Public","body":"@dependencies || (@dependencies = [] of Dependency)"},"external_var":false},{"html_id":"description:String|Nil-instance-method","name":"description","abstract":false,"location":{"filename":"src/spec.cr","line_number":147,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L147"},"def":{"name":"description","return_type":"String | ::Nil","visibility":"Public","body":"@description"},"external_var":false},{"html_id":"development_dependencies-instance-method","name":"development_dependencies","abstract":false,"location":{"filename":"src/spec.cr","line_number":276,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L276"},"def":{"name":"development_dependencies","visibility":"Public","body":"@development_dependencies || (@development_dependencies = [] of Dependency)"},"external_var":false},{"html_id":"executables-instance-method","name":"executables","abstract":false,"location":{"filename":"src/spec.cr","line_number":284,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L284"},"def":{"name":"executables","visibility":"Public","body":"@executables || (@executables = [] of String)"},"external_var":false},{"html_id":"libraries-instance-method","name":"libraries","abstract":false,"location":{"filename":"src/spec.cr","line_number":288,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L288"},"def":{"name":"libraries","visibility":"Public","body":"@libraries || (@libraries = [] of Library)"},"external_var":false},{"html_id":"license:String|Nil-instance-method","name":"license","abstract":false,"location":{"filename":"src/spec.cr","line_number":148,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L148"},"def":{"name":"license","return_type":"String | ::Nil","visibility":"Public","body":"@license"},"external_var":false},{"html_id":"license_url-instance-method","name":"license_url","abstract":false,"location":{"filename":"src/spec.cr","line_number":296,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L296"},"def":{"name":"license_url","visibility":"Public","body":"if license = @license\n  if license =~ (/https?:\\/\\//)\n    license\n  else\n    \"https://spdx.org/licenses/#{license}\"\n  end\nend"},"external_var":false},{"html_id":"mismatched_version?-instance-method","name":"mismatched_version?","abstract":false,"location":{"filename":"src/spec.cr","line_number":155,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L155"},"def":{"name":"mismatched_version?","visibility":"Public","body":"(Versions.compare(version, original_version)) != 0"},"external_var":false},{"html_id":"name:String|Nil-instance-method","name":"name","abstract":false,"location":{"filename":"src/spec.cr","line_number":144,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L144"},"def":{"name":"name","return_type":"String | ::Nil","visibility":"Public","body":"if (__temp_99 = @name).nil?\n  ::raise(::NilAssertionError.new(\"Shards::Spec#name cannot be nil\"))\nelse\n  __temp_99\nend"},"external_var":false},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/spec.cr","line_number":262,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L262"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"},"external_var":false},{"html_id":"name?:String|Nil|Nil-instance-method","name":"name?","abstract":false,"location":{"filename":"src/spec.cr","line_number":144,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L144"},"def":{"name":"name?","return_type":"String | ::Nil | ::Nil","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"original_version:Version|Nil-instance-method","name":"original_version","abstract":false,"location":{"filename":"src/spec.cr","line_number":146,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L146"},"def":{"name":"original_version","return_type":"Version | ::Nil","visibility":"Public","body":"if (__temp_101 = @original_version).nil?\n  ::raise(::NilAssertionError.new(\"Shards::Spec#original_version cannot be nil\"))\nelse\n  __temp_101\nend"},"external_var":false},{"html_id":"original_version?:Version|Nil|Nil-instance-method","name":"original_version?","abstract":false,"location":{"filename":"src/spec.cr","line_number":146,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L146"},"def":{"name":"original_version?","return_type":"Version | ::Nil | ::Nil","visibility":"Public","body":"@original_version"},"external_var":false},{"html_id":"read_from_yaml?:Bool-instance-method","name":"read_from_yaml?","abstract":false,"location":{"filename":"src/spec.cr","line_number":151,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L151"},"def":{"name":"read_from_yaml?","return_type":"Bool","visibility":"Public","body":"@read_from_yaml"},"external_var":false},{"html_id":"resolver:Resolver|Nil-instance-method","name":"resolver","abstract":false,"location":{"filename":"src/spec.cr","line_number":150,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L150"},"def":{"name":"resolver","return_type":"Resolver | ::Nil","visibility":"Public","body":"@resolver"},"external_var":false},{"html_id":"resolver=(resolver:Resolver|Nil)-instance-method","name":"resolver=","abstract":false,"args":[{"name":"resolver","external_name":"resolver","restriction":"Resolver | ::Nil"}],"args_string":"(resolver : Resolver | Nil)","args_html":"(resolver : <a href=\"../Shards/Resolver.html\">Resolver</a> | Nil)","location":{"filename":"src/spec.cr","line_number":150,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L150"},"def":{"name":"resolver=","args":[{"name":"resolver","external_name":"resolver","restriction":"Resolver | ::Nil"}],"visibility":"Public","body":"@resolver = resolver"},"external_var":false},{"html_id":"scripts-instance-method","name":"scripts","abstract":false,"location":{"filename":"src/spec.cr","line_number":292,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L292"},"def":{"name":"scripts","visibility":"Public","body":"@scripts || (@scripts = {} of String => String)"},"external_var":false},{"html_id":"targets-instance-method","name":"targets","abstract":false,"location":{"filename":"src/spec.cr","line_number":280,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L280"},"def":{"name":"targets","visibility":"Public","body":"@targets || (@targets = [] of Target)"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/spec.cr","line_number":116,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L116"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"((io << name) << \" \") << version"},"external_var":false},{"html_id":"version:Version|Nil-instance-method","name":"version","abstract":false,"location":{"filename":"src/spec.cr","line_number":145,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L145"},"def":{"name":"version","return_type":"Version | ::Nil","visibility":"Public","body":"if (__temp_100 = @version).nil?\n  ::raise(::NilAssertionError.new(\"Shards::Spec#version cannot be nil\"))\nelse\n  __temp_100\nend"},"external_var":false},{"html_id":"version=(version:Version)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"}],"args_string":"(version : Version)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/spec.cr","line_number":265,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L265"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"Version"}],"visibility":"Public","body":"@version = version"},"external_var":false},{"html_id":"version?:Version|Nil|Nil-instance-method","name":"version?","abstract":false,"location":{"filename":"src/spec.cr","line_number":145,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L145"},"def":{"name":"version?","return_type":"Version | ::Nil | ::Nil","visibility":"Public","body":"@version"},"external_var":false}],"types":[{"html_id":"Ashard/Shards/Spec/AIAssistant","path":"Shards/Spec/AIAssistant.html","kind":"class","full_name":"Shards::Spec::AIAssistant","name":"AIAssistant","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spec.cr","line_number":98,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L98"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Spec","kind":"class","full_name":"Shards::Spec","name":"Spec"},"doc":"Optional `ai_assistant` section in `shard.yml` for enabling automatic\ninstallation/update of AI assistant configuration during `shards install`.\n\n```yaml\nai_assistant:\n  auto_install: true\n```","summary":"<p>Optional <code>ai_assistant</code> section in <code>shard.yml</code> for enabling automatic installation/update of AI assistant configuration during <code>shards install</code>.</p>","constructors":[{"html_id":"new(pull:YAML::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"args_string":"(pull : YAML::PullParser)","args_html":"(pull : <a href=\"../../YAML/PullParser.html\">YAML::PullParser</a>)","location":{"filename":"src/spec.cr","line_number":104,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L104"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"visibility":"Public","body":"auto_install = false\npull.each_in_mapping do\n  case pull.read_scalar\n  when \"auto_install\"\n    auto_install = pull.read_scalar == \"true\"\n  else\n    pull.skip\n  end\nend\nnew(auto_install)\n"},"external_var":false},{"html_id":"new(auto_install:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"auto_install","default_value":"false","external_name":"auto_install","restriction":"::Bool"}],"args_string":"(auto_install : Bool = false)","args_html":"(auto_install : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/spec.cr","line_number":101,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L101"},"def":{"name":"new","args":[{"name":"auto_install","default_value":"false","external_name":"auto_install","restriction":"::Bool"}],"visibility":"Public","body":"_ = allocate\n_.initialize(auto_install)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"auto_install:Bool-instance-method","name":"auto_install","abstract":false,"location":{"filename":"src/spec.cr","line_number":99,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L99"},"def":{"name":"auto_install","return_type":"Bool","visibility":"Public","body":"@auto_install"},"external_var":false}]},{"html_id":"Ashard/Shards/Spec/AIDocs","path":"Shards/Spec/AIDocs.html","kind":"class","full_name":"Shards::Spec::AIDocs","name":"AIDocs","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spec.cr","line_number":58,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L58"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Spec","kind":"class","full_name":"Shards::Spec","name":"Spec"},"doc":"Optional `ai_docs` section in `shard.yml` for customizing AI documentation\ndistribution. When absent, auto-detection handles standard locations.\n\n```yaml\nai_docs:\n  include:\n    - docs/claude/custom_guide.md\n  exclude:\n    - .claude/skills/internal_dev_tool/\n```","summary":"<p>Optional <code>ai_docs</code> section in <code>shard.yml</code> for customizing AI documentation distribution.</p>","constructors":[{"html_id":"new(pull:YAML::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"args_string":"(pull : YAML::PullParser)","args_html":"(pull : <a href=\"../../YAML/PullParser.html\">YAML::PullParser</a>)","location":{"filename":"src/spec.cr","line_number":68,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L68"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"visibility":"Public","body":"include_paths = [] of String\nexclude_paths = [] of String\n\npull.each_in_mapping do\n  case pull.read_scalar\n  when \"include\"\n    pull.read_empty_or do\n      pull.each_in_sequence do include_paths << pull.read_scalar end\n    end\n  when \"exclude\"\n    pull.read_empty_or do\n      pull.each_in_sequence do exclude_paths << pull.read_scalar end\n    end\n  else\n    pull.skip\n  end\nend\n\nnew(include_paths, exclude_paths)\n"},"external_var":false},{"html_id":"new(include__arg1:Array(String)=[]ofString,exclude:Array(String)=[]ofString)-class-method","name":"new","abstract":false,"args":[{"name":"__arg1","default_value":"[] of String","external_name":"include","restriction":"::Array(::String)"},{"name":"exclude","default_value":"[] of String","external_name":"exclude","restriction":"::Array(::String)"}],"args_string":"(include __arg1 : Array(String) = [] of String, exclude : Array(String) = [] of String)","args_html":"(include __arg1 : Array(String) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">String</span>, exclude : Array(String) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">String</span>)","location":{"filename":"src/spec.cr","line_number":65,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L65"},"def":{"name":"new","args":[{"name":"__arg1","default_value":"[] of String","external_name":"include","restriction":"::Array(::String)"},{"name":"exclude","default_value":"[] of String","external_name":"exclude","restriction":"::Array(::String)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(__arg1, exclude)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"exclude:Array(String)-instance-method","name":"exclude","doc":"Paths to exclude from auto-detected AI docs.","summary":"<p>Paths to exclude from auto-detected AI docs.</p>","abstract":false,"location":{"filename":"src/spec.cr","line_number":63,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L63"},"def":{"name":"exclude","return_type":"Array(String)","visibility":"Public","body":"@exclude"},"external_var":false},{"html_id":"include:Array(String)-instance-method","name":"include","doc":"Extra files to include beyond auto-detected locations.","summary":"<p>Extra files to include beyond auto-detected locations.</p>","abstract":false,"location":{"filename":"src/spec.cr","line_number":60,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L60"},"def":{"name":"include","return_type":"Array(String)","visibility":"Public","body":"@include"},"external_var":false}]},{"html_id":"Ashard/Shards/Spec/Author","path":"Shards/Spec/Author.html","kind":"class","full_name":"Shards::Spec::Author","name":"Author","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spec.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L10"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Spec","kind":"class","full_name":"Shards::Spec","name":"Spec"},"constructors":[{"html_id":"new(pull:YAML::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"args_string":"(pull : YAML::PullParser)","args_html":"(pull : <a href=\"../../YAML/PullParser.html\">YAML::PullParser</a>)","location":{"filename":"src/spec.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L14"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"visibility":"Public","body":"new(pull.read_scalar)"},"external_var":false},{"html_id":"new(name)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""}],"args_string":"(name)","args_html":"(name)","location":{"filename":"src/spec.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L18"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(name)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"email:String|Nil-instance-method","name":"email","abstract":false,"location":{"filename":"src/spec.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L12"},"def":{"name":"email","return_type":"String | ::Nil","visibility":"Public","body":"@email"},"external_var":false},{"html_id":"email=(email:String|Nil)-instance-method","name":"email=","abstract":false,"args":[{"name":"email","external_name":"email","restriction":"String | ::Nil"}],"args_string":"(email : String | Nil)","args_html":"(email : String | Nil)","location":{"filename":"src/spec.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L12"},"def":{"name":"email=","args":[{"name":"email","external_name":"email","restriction":"String | ::Nil"}],"visibility":"Public","body":"@email = email"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/spec.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L11"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/spec.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L11"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"},"external_var":false}]},{"html_id":"Ashard/Shards/Spec/Library","path":"Shards/Spec/Library.html","kind":"class","full_name":"Shards::Spec::Library","name":"Library","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/spec.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L27"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards/Spec","kind":"class","full_name":"Shards::Spec","name":"Spec"},"constructors":[{"html_id":"new(soname:String,version:String)-class-method","name":"new","abstract":false,"args":[{"name":"soname","external_name":"soname","restriction":"::String"},{"name":"version","external_name":"version","restriction":"::String"}],"args_string":"(soname : String, version : String)","args_html":"(soname : String, version : String)","location":{"filename":"src/spec.cr","line_number":44,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L44"},"def":{"name":"new","args":[{"name":"soname","external_name":"soname","restriction":"::String"},{"name":"version","external_name":"version","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(soname, version)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false},{"html_id":"new(pull:YAML::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"args_string":"(pull : YAML::PullParser)","args_html":"(pull : <a href=\"../../YAML/PullParser.html\">YAML::PullParser</a>)","location":{"filename":"src/spec.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L31"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"visibility":"Public","body":"name = pull.read_scalar\n\nline, column = pull.location\nif pull.kind.scalar?\n  version = pull.read_scalar.strip\nend\n\nif (!version) || version.try(&.empty?)\n  pull.raise(\"library version for #{name} can't be empty, use * for any version\", line, column)\nend\n\nnew(name, version)\n"},"external_var":false}],"instance_methods":[{"html_id":"soname:String-instance-method","name":"soname","abstract":false,"location":{"filename":"src/spec.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L28"},"def":{"name":"soname","return_type":"String","visibility":"Public","body":"@soname"},"external_var":false},{"html_id":"soname=(soname:String)-instance-method","name":"soname=","abstract":false,"args":[{"name":"soname","external_name":"soname","restriction":"String"}],"args_string":"(soname : String)","args_html":"(soname : String)","location":{"filename":"src/spec.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L28"},"def":{"name":"soname=","args":[{"name":"soname","external_name":"soname","restriction":"String"}],"visibility":"Public","body":"@soname = soname"},"external_var":false},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/spec.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L29"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"},"external_var":false},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/spec.cr","line_number":29,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/spec.cr#L29"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"},"external_var":false}]}]},{"html_id":"Ashard/Shards/Target","path":"Shards/Target.html","kind":"class","full_name":"Shards::Target","name":"Target","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/target.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(name:String,main:String)-class-method","name":"new","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"main","external_name":"main","restriction":"::String"}],"args_string":"(name : String, main : String)","args_html":"(name : String, main : String)","location":{"filename":"src/target.cr","line_number":27,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L27"},"def":{"name":"new","args":[{"name":"name","external_name":"name","restriction":"::String"},{"name":"main","external_name":"main","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(name, main)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false},{"html_id":"new(pull:YAML::PullParser):self-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"args_string":"(pull : YAML::PullParser) : self","args_html":"(pull : <a href=\"../YAML/PullParser.html\">YAML::PullParser</a>) : <span class=\"k\">self</span>","location":{"filename":"src/target.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L6"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"YAML::PullParser"}],"return_type":"self","visibility":"Public","body":"start_pos = pull.location\nname = pull.read_scalar\nmain = nil\n\npull.each_in_mapping do\n  case key = pull.read_scalar\n  when \"main\"\n    main = pull.read_scalar\n  else\n  end\nend\n\nif main\nelse\n  raise(YAML::ParseException.new(\"Missing property \\\"main\\\" for target #{name.inspect}\", *start_pos))\nend\n\nTarget.new(name, main)\n"},"external_var":false}],"instance_methods":[{"html_id":"main:String-instance-method","name":"main","abstract":false,"location":{"filename":"src/target.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L4"},"def":{"name":"main","return_type":"String","visibility":"Public","body":"@main"},"external_var":false},{"html_id":"main=(main:String)-instance-method","name":"main=","abstract":false,"args":[{"name":"main","external_name":"main","restriction":"String"}],"args_string":"(main : String)","args_html":"(main : String)","location":{"filename":"src/target.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L4"},"def":{"name":"main=","args":[{"name":"main","external_name":"main","restriction":"String"}],"visibility":"Public","body":"@main = main"},"external_var":false},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/target.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L3"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"},"external_var":false},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/target.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/target.cr#L3"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"},"external_var":false}]},{"html_id":"Ashard/Shards/Version","path":"Shards/Version.html","kind":"struct","full_name":"Shards::Version","name":"Version","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/requirement.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L25"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(value:String)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"::String"}],"args_string":"(value : String)","args_html":"(value : String)","location":{"filename":"src/requirement.cr","line_number":28,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L28"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"::String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"has_metadata?-instance-method","name":"has_metadata?","abstract":false,"location":{"filename":"src/requirement.cr","line_number":31,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L31"},"def":{"name":"has_metadata?","visibility":"Public","body":"Versions.has_metadata?(@value)"},"external_var":false},{"html_id":"prerelease?-instance-method","name":"prerelease?","abstract":false,"location":{"filename":"src/requirement.cr","line_number":35,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L35"},"def":{"name":"prerelease?","visibility":"Public","body":"Versions.prerelease?(@value)"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/requirement.cr","line_number":39,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L39"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"io << value"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/requirement.cr","line_number":43,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L43"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"version\")\nyaml.scalar(value)\n"},"external_var":false},{"html_id":"value:String-instance-method","name":"value","abstract":false,"location":{"filename":"src/requirement.cr","line_number":26,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L26"},"def":{"name":"value","return_type":"String","visibility":"Public","body":"@value"},"external_var":false}]},{"html_id":"Ashard/Shards/VersionReq","path":"Shards/VersionReq.html","kind":"struct","full_name":"Shards::VersionReq","name":"VersionReq","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/requirement.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(patterns)-class-method","name":"new","abstract":false,"args":[{"name":"patterns","external_name":"patterns","restriction":""}],"args_string":"(patterns)","args_html":"(patterns)","location":{"filename":"src/requirement.cr","line_number":5,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L5"},"def":{"name":"new","args":[{"name":"patterns","external_name":"patterns","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(patterns)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"patterns:Array(String)-instance-method","name":"patterns","abstract":false,"location":{"filename":"src/requirement.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L3"},"def":{"name":"patterns","return_type":"Array(String)","visibility":"Public","body":"@patterns"},"external_var":false},{"html_id":"prerelease?-instance-method","name":"prerelease?","abstract":false,"location":{"filename":"src/requirement.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L9"},"def":{"name":"prerelease?","visibility":"Public","body":"patterns.any? do |pattern|\n  Versions.prerelease?(pattern)\nend"},"external_var":false},{"html_id":"to_s(io)-instance-method","name":"to_s","abstract":false,"args":[{"name":"io","external_name":"io","restriction":""}],"args_string":"(io)","args_html":"(io)","location":{"filename":"src/requirement.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L15"},"def":{"name":"to_s","args":[{"name":"io","external_name":"io","restriction":""}],"visibility":"Public","body":"patterns.join(io, \", \")"},"external_var":false},{"html_id":"to_yaml(yaml)-instance-method","name":"to_yaml","abstract":false,"args":[{"name":"yaml","external_name":"yaml","restriction":""}],"args_string":"(yaml)","args_html":"(yaml)","location":{"filename":"src/requirement.cr","line_number":19,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/requirement.cr#L19"},"def":{"name":"to_yaml","args":[{"name":"yaml","external_name":"yaml","restriction":""}],"visibility":"Public","body":"yaml.scalar(\"version\")\nyaml.scalar(to_s)\n"},"external_var":false}]},{"html_id":"Ashard/Shards/Versions","path":"Shards/Versions.html","kind":"module","full_name":"Shards::Versions","name":"Versions","abstract":false,"locations":[{"filename":"src/versions.cr","line_number":2,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L2"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"compare(a:Version,b:Version)-class-method","name":"compare","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"Version"},{"name":"b","external_name":"b","restriction":"Version"}],"args_string":"(a : Version, b : Version)","args_html":"(a : <a href=\"../Shards/Version.html\">Version</a>, b : <a href=\"../Shards/Version.html\">Version</a>)","location":{"filename":"src/versions.cr","line_number":91,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L91"},"def":{"name":"compare","args":[{"name":"a","external_name":"a","restriction":"Version"},{"name":"b","external_name":"b","restriction":"Version"}],"visibility":"Public","body":"compare(a.value, b.value)"},"external_var":false},{"html_id":"compare(a:String,b:String)-class-method","name":"compare","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"String"},{"name":"b","external_name":"b","restriction":"String"}],"args_string":"(a : String, b : String)","args_html":"(a : String, b : String)","location":{"filename":"src/versions.cr","line_number":95,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L95"},"def":{"name":"compare","args":[{"name":"a","external_name":"a","restriction":"String"},{"name":"b","external_name":"b","restriction":"String"}],"visibility":"Public","body":"if a == b\n  return 0\nend\n\na_segment = Segment.new(a)\nb_segment = Segment.new(b)\n\nloop do\n\n  a_segment.next\n  b_segment.next\n\n\n  if a_segment.empty?\n    b_segment.only_zeroes? do return b_segment.prerelease? ? -1 : 1 end\n    return 0\n  end\n\n\n  if b_segment.empty?\n    a_segment.only_zeroes? do return a_segment.prerelease? ? 1 : -1 end\n    return 0\n  end\n\n\n  a_num = a_segment.to_i?\n  b_num = b_segment.to_i?\n\n  ret = if a_num && b_num\n    b_num <=> a_num\n  elsif a_num\n    a_segment.only_zeroes? do\n      if a_segment.prerelease?\n        return b_segment <=> a_segment\n      end\n      return -1\n    end\n    return -1\n  elsif b_num\n    b_segment.only_zeroes? do\n      if b_segment.prerelease?\n        return b_segment <=> a_segment\n      end\n      return 1\n    end\n    return 1\n  else\n    b_segment <=> a_segment\n  end\n\n\n\n  if ret == 0\n  else\n    return ret\n  end\nend\n"},"external_var":false},{"html_id":"has_metadata?(str:String)-class-method","name":"has_metadata?","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/versions.cr","line_number":161,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L161"},"def":{"name":"has_metadata?","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"str.includes?('+')"},"external_var":false},{"html_id":"matches?(version:Version,requirement:VersionReq)-class-method","name":"matches?","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"requirement","external_name":"requirement","restriction":"VersionReq"}],"args_string":"(version : Version, requirement : VersionReq)","args_html":"(version : <a href=\"../Shards/Version.html\">Version</a>, requirement : <a href=\"../Shards/VersionReq.html\">VersionReq</a>)","location":{"filename":"src/versions.cr","line_number":173,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L173"},"def":{"name":"matches?","args":[{"name":"version","external_name":"version","restriction":"Version"},{"name":"requirement","external_name":"requirement","restriction":"VersionReq"}],"visibility":"Public","body":"requirement.patterns.all? do |pattern|\n  matches_single_pattern?(version, pattern)\nend"},"external_var":false},{"html_id":"prerelease?(str:String)-class-method","name":"prerelease?","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/versions.cr","line_number":153,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L153"},"def":{"name":"prerelease?","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"str.each_char do |char|\n  if char.ascii_letter?\n    return true\n  end\n  if char == '+'\n    break\n  end\nend\nfalse\n"},"external_var":false},{"html_id":"resolve(versions:Array(Version),requirement:VersionReq)-class-method","name":"resolve","abstract":false,"args":[{"name":"versions","external_name":"versions","restriction":"Array(Version)"},{"name":"requirement","external_name":"requirement","restriction":"VersionReq"}],"args_string":"(versions : Array(Version), requirement : VersionReq)","args_html":"(versions : Array(<a href=\"../Shards/Version.html\">Version</a>), requirement : <a href=\"../Shards/VersionReq.html\">VersionReq</a>)","location":{"filename":"src/versions.cr","line_number":169,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L169"},"def":{"name":"resolve","args":[{"name":"versions","external_name":"versions","restriction":"Array(Version)"},{"name":"requirement","external_name":"requirement","restriction":"VersionReq"}],"visibility":"Public","body":"versions.select do |version| matches?(version, requirement) end"},"external_var":false},{"html_id":"sort(versions)-class-method","name":"sort","abstract":false,"args":[{"name":"versions","external_name":"versions","restriction":""}],"args_string":"(versions)","args_html":"(versions)","location":{"filename":"src/versions.cr","line_number":87,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/versions.cr#L87"},"def":{"name":"sort","args":[{"name":"versions","external_name":"versions","restriction":""}],"visibility":"Public","body":"versions.sort do |a, b| compare(a, b) end"},"external_var":false}]},{"html_id":"Ashard/Shards/Vulnerability","path":"Shards/Vulnerability.html","kind":"struct","full_name":"Shards::Vulnerability","name":"Vulnerability","abstract":false,"superclass":{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},"ancestors":[{"html_id":"Ashard/Struct","kind":"struct","full_name":"Struct","name":"Struct"},{"html_id":"Ashard/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/vulnerability_scanner.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L8"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"doc":"Represents a single vulnerability found by OSV.","summary":"<p>Represents a single vulnerability found by OSV.</p>","constructors":[{"html_id":"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)-class-method","name":"new","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"::String"},{"name":"summary","external_name":"summary","restriction":"::String"},{"name":"details","external_name":"details","restriction":"::String"},{"name":"severity","external_name":"severity","restriction":"::Shards::Severity"},{"name":"cvss_score","external_name":"cvss_score","restriction":"::Float64 | ::Nil"},{"name":"affected_versions","external_name":"affected_versions","restriction":"::Array(::String)"},{"name":"references","external_name":"references","restriction":"::Array(::String)"},{"name":"aliases","external_name":"aliases","restriction":"::Array(::String)"},{"name":"published","external_name":"published","restriction":"::Time | ::Nil"},{"name":"modified","external_name":"modified","restriction":"::Time | ::Nil"}],"args_string":"(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)","args_html":"(id : String, summary : String, details : String, severity : <a href=\"../Shards/Severity.html\">Shards::Severity</a>, cvss_score : Float64 | Nil, affected_versions : Array(String), references : Array(String), aliases : Array(String), published : Time | Nil, modified : Time | Nil)","location":{"filename":"src/vulnerability_scanner.cr","line_number":20,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L20"},"def":{"name":"new","args":[{"name":"id","external_name":"id","restriction":"::String"},{"name":"summary","external_name":"summary","restriction":"::String"},{"name":"details","external_name":"details","restriction":"::String"},{"name":"severity","external_name":"severity","restriction":"::Shards::Severity"},{"name":"cvss_score","external_name":"cvss_score","restriction":"::Float64 | ::Nil"},{"name":"affected_versions","external_name":"affected_versions","restriction":"::Array(::String)"},{"name":"references","external_name":"references","restriction":"::Array(::String)"},{"name":"aliases","external_name":"aliases","restriction":"::Array(::String)"},{"name":"published","external_name":"published","restriction":"::Time | ::Nil"},{"name":"modified","external_name":"modified","restriction":"::Time | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(id, summary, details, severity, cvss_score, affected_versions, references, aliases, published, modified)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"affected_versions:Array(String)-instance-method","name":"affected_versions","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":14,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L14"},"def":{"name":"affected_versions","return_type":"Array(String)","visibility":"Public","body":"@affected_versions"},"external_var":false},{"html_id":"aliases:Array(String)-instance-method","name":"aliases","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":16,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L16"},"def":{"name":"aliases","return_type":"Array(String)","visibility":"Public","body":"@aliases"},"external_var":false},{"html_id":"cvss_score:Float64|Nil-instance-method","name":"cvss_score","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":13,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L13"},"def":{"name":"cvss_score","return_type":"Float64 | ::Nil","visibility":"Public","body":"@cvss_score"},"external_var":false},{"html_id":"details:String-instance-method","name":"details","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":11,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L11"},"def":{"name":"details","return_type":"String","visibility":"Public","body":"@details"},"external_var":false},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L9"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"},"external_var":false},{"html_id":"modified:Time|Nil-instance-method","name":"modified","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":18,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L18"},"def":{"name":"modified","return_type":"Time | ::Nil","visibility":"Public","body":"@modified"},"external_var":false},{"html_id":"published:Time|Nil-instance-method","name":"published","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L17"},"def":{"name":"published","return_type":"Time | ::Nil","visibility":"Public","body":"@published"},"external_var":false},{"html_id":"references:Array(String)-instance-method","name":"references","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L15"},"def":{"name":"references","return_type":"Array(String)","visibility":"Public","body":"@references"},"external_var":false},{"html_id":"severity:Severity-instance-method","name":"severity","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":12,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L12"},"def":{"name":"severity","return_type":"Severity","visibility":"Public","body":"@severity"},"external_var":false},{"html_id":"summary:String-instance-method","name":"summary","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L10"},"def":{"name":"summary","return_type":"String","visibility":"Public","body":"@summary"},"external_var":false}]},{"html_id":"Ashard/Shards/VulnerabilityReport","path":"Shards/VulnerabilityReport.html","kind":"class","full_name":"Shards::VulnerabilityReport","name":"VulnerabilityReport","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/vulnerability_report.cr","line_number":6,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L6"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"constructors":[{"html_id":"new(results:Array(Shards::PackageScanResult),ignore_rules:Array(Shards::IgnoreRule)=[]ofIgnoreRule,min_severity:Shards::Severity=Severity::Unknown,fail_above:Severity|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"results","external_name":"results","restriction":"::Array(::Shards::PackageScanResult)"},{"name":"ignore_rules","default_value":"[] of IgnoreRule","external_name":"ignore_rules","restriction":"::Array(::Shards::IgnoreRule)"},{"name":"min_severity","default_value":"Severity::Unknown","external_name":"min_severity","restriction":"::Shards::Severity"},{"name":"fail_above","default_value":"nil","external_name":"fail_above","restriction":"Severity | ::Nil"}],"args_string":"(results : Array(Shards::PackageScanResult), ignore_rules : Array(Shards::IgnoreRule) = [] of IgnoreRule, min_severity : Shards::Severity = Severity::Unknown, fail_above : Severity | Nil = nil)","args_html":"(results : Array(<a href=\"../Shards/PackageScanResult.html\">Shards::PackageScanResult</a>), ignore_rules : Array(<a href=\"../Shards/IgnoreRule.html\">Shards::IgnoreRule</a>) = <span class=\"o\">[]</span> <span class=\"k\">of</span> <span class=\"t\">IgnoreRule</span>, min_severity : <a href=\"../Shards/Severity.html\">Shards::Severity</a> = <span class=\"t\">Severity</span><span class=\"t\">::</span><span class=\"t\">Unknown</span>, fail_above : <a href=\"../Shards/Severity.html\">Severity</a> | Nil = <span class=\"n\">nil</span>)","location":{"filename":"src/vulnerability_report.cr","line_number":15,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L15"},"def":{"name":"new","args":[{"name":"results","external_name":"results","restriction":"::Array(::Shards::PackageScanResult)"},{"name":"ignore_rules","default_value":"[] of IgnoreRule","external_name":"ignore_rules","restriction":"::Array(::Shards::IgnoreRule)"},{"name":"min_severity","default_value":"Severity::Unknown","external_name":"min_severity","restriction":"::Shards::Severity"},{"name":"fail_above","default_value":"nil","external_name":"fail_above","restriction":"Severity | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(results, ignore_rules, min_severity, fail_above)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"exit_code:Int32-instance-method","name":"exit_code","doc":"Returns appropriate exit code.\n0 = no vulnerabilities above threshold\n1 = vulnerabilities found above threshold","summary":"<p>Returns appropriate exit code.</p>","abstract":false,"location":{"filename":"src/vulnerability_report.cr","line_number":55,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L55"},"def":{"name":"exit_code","return_type":"Int32","visibility":"Public","body":"threshold = @fail_above || Severity::Low\nfiltered = filtered_results\nhas_vulns = filtered.any? do |r| r.vulnerabilities.any? do |v| v.severity.at_or_above?(threshold) end end\nhas_vulns ? 1 : 0\n"},"external_var":false},{"html_id":"fail_above:Severity|Nil-instance-method","name":"fail_above","abstract":false,"location":{"filename":"src/vulnerability_report.cr","line_number":10,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L10"},"def":{"name":"fail_above","return_type":"Severity | ::Nil","visibility":"Public","body":"@fail_above"},"external_var":false},{"html_id":"filtered_results:Array(PackageScanResult)-instance-method","name":"filtered_results","doc":"Returns filtered results (after applying ignore rules and severity filter).","summary":"<p>Returns filtered results (after applying ignore rules and severity filter).</p>","abstract":false,"location":{"filename":"src/vulnerability_report.cr","line_number":21,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L21"},"def":{"name":"filtered_results","return_type":"Array(PackageScanResult)","visibility":"Public","body":"@ignored_count = 0\n@filtered_count = 0\n\n@results.map do |result|\n  filtered_vulns = result.vulnerabilities.select do |vuln|\n    active_ignore = @ignore_rules.find do |rule| (rule.id == vuln.id) && rule.active? end\n    if active_ignore\n      @ignored_count = @ignored_count + 1\n      next false\n    end\n\n\n    alias_ignored = vuln.aliases.any? do |a| @ignore_rules.any? do |rule| (rule.id == a) && rule.active? end end\n    if alias_ignored\n      @ignored_count = @ignored_count + 1\n      next false\n    end\n\n    if vuln.severity.at_or_above?(@min_severity)\n      true\n    else\n      @filtered_count = @filtered_count + 1\n      false\n    end\n  end\n\n  PackageScanResult.new(result.package, result.purl, filtered_vulns)\nend\n"},"external_var":false},{"html_id":"ignore_rules:Array(IgnoreRule)-instance-method","name":"ignore_rules","abstract":false,"location":{"filename":"src/vulnerability_report.cr","line_number":8,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L8"},"def":{"name":"ignore_rules","return_type":"Array(IgnoreRule)","visibility":"Public","body":"@ignore_rules"},"external_var":false},{"html_id":"min_severity:Severity-instance-method","name":"min_severity","abstract":false,"location":{"filename":"src/vulnerability_report.cr","line_number":9,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L9"},"def":{"name":"min_severity","return_type":"Severity","visibility":"Public","body":"@min_severity"},"external_var":false},{"html_id":"results:Array(PackageScanResult)-instance-method","name":"results","abstract":false,"location":{"filename":"src/vulnerability_report.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L7"},"def":{"name":"results","return_type":"Array(PackageScanResult)","visibility":"Public","body":"@results"},"external_var":false},{"html_id":"to_json(io:IO)-instance-method","name":"to_json","abstract":false,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO)","args_html":"(io : IO)","location":{"filename":"src/vulnerability_report.cr","line_number":130,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L130"},"def":{"name":"to_json","args":[{"name":"io","external_name":"io","restriction":"IO"}],"visibility":"Public","body":"filtered = filtered_results\n\nJSON.build(io, indent: 2) do |json|\n  json.object do\n    json.field(\"schema_version\", \"1.0.0\")\n    json.field(\"tool\", \"shards-alpha\")\n    json.field(\"tool_version\", VERSION)\n    json.field(\"timestamp\", Time.utc.to_rfc3339)\n\n    json.field(\"summary\") do\n      json.object do\n        json.field(\"total_packages\", @results.size)\n        json.field(\"vulnerable_packages\", filtered.count(&.vulnerable?))\n        json.field(\"total_vulnerabilities\", filtered.sum() do |__arg4| __arg4.vulnerabilities.size end)\n        json.field(\"ignored\", @ignored_count)\n        json.field(\"filtered_by_severity\", @filtered_count)\n      end\n    end\n\n    json.field(\"packages\") do\n      json.array do\n        filtered.select(&.vulnerable?).each do |result|\n          json.object do\n            json.field(\"name\", result.package.name)\n            json.field(\"version\", result.package.version.to_s)\n            json.field(\"purl\", result.purl)\n\n            json.field(\"vulnerabilities\") do\n              json.array do\n                result.vulnerabilities.each do |vuln|\n                  json.object do\n                    json.field(\"id\", vuln.id)\n                    json.field(\"summary\", vuln.summary)\n                    json.field(\"severity\", vuln.severity.to_s.downcase)\n                    json.field(\"cvss_score\", vuln.cvss_score)\n                    json.field(\"aliases\") do\n                      json.array do vuln.aliases.each do |a| json.string(a) end end\n                    end\n                    json.field(\"references\") do\n                      json.array do vuln.references.each do |r| json.string(r) end end\n                    end\n                    json.field(\"published\", vuln.published.try(&.to_rfc3339))\n                    json.field(\"modified\", vuln.modified.try(&.to_rfc3339))\n                  end\n                end\n              end\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"},"external_var":false},{"html_id":"to_sarif(io:IO)-instance-method","name":"to_sarif","abstract":false,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO)","args_html":"(io : IO)","location":{"filename":"src/vulnerability_report.cr","line_number":189,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L189"},"def":{"name":"to_sarif","args":[{"name":"io","external_name":"io","restriction":"IO"}],"visibility":"Public","body":"filtered = filtered_results\n\nJSON.build(io, indent: 2) do |json|\n  json.object do\n    json.field(\"$schema\", \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json\")\n    json.field(\"version\", \"2.1.0\")\n\n    json.field(\"runs\") do\n      json.array do\n        json.object do\n          json.field(\"tool\") do\n            json.object do\n              json.field(\"driver\") do\n                json.object do\n                  json.field(\"name\", \"shards-alpha audit\")\n                  json.field(\"version\", VERSION)\n                  json.field(\"informationUri\", \"https://github.com/crimson-knight/shards\")\n\n\n                  json.field(\"rules\") do\n                    json.array do\n                      unique_vulns = filtered.flat_map(&.vulnerabilities).uniq(&.id)\n                      unique_vulns.each do |vuln|\n                        json.object do\n                          json.field(\"id\", vuln.id)\n                          json.field(\"shortDescription\") do\n                            json.object do\n                              json.field(\"text\", vuln.summary.empty? ? vuln.id : vuln.summary)\n                            end\n                          end\n                          json.field(\"fullDescription\") do\n                            json.object do\n                              json.field(\"text\", vuln.details.empty? ? vuln.summary : vuln.details)\n                            end\n                          end\n                          json.field(\"defaultConfiguration\") do\n                            json.object do\n                              json.field(\"level\", sarif_level(vuln.severity))\n                            end\n                          end\n                          if vuln.references.empty?\n                          else\n                            json.field(\"helpUri\", vuln.references.first)\n                          end\n                        end\n                      end\n                    end\n                  end\n                end\n              end\n            end\n          end\n\n\n          json.field(\"results\") do\n            json.array do\n              filtered.select(&.vulnerable?).each do |result|\n                result.vulnerabilities.each do |vuln|\n                  json.object do\n                    json.field(\"ruleId\", vuln.id)\n                    json.field(\"level\", sarif_level(vuln.severity))\n                    json.field(\"message\") do\n                      json.object do\n                        json.field(\"text\", \"#{result.package.name}@#{result.package.version} is affected by #{vuln.id}: #{vuln.summary}\")\n                      end\n                    end\n                    json.field(\"locations\") do\n                      json.array do\n                        json.object do\n                          json.field(\"physicalLocation\") do\n                            json.object do\n                              json.field(\"artifactLocation\") do\n                                json.object do\n                                  json.field(\"uri\", \"shard.lock\")\n                                end\n                              end\n                            end\n                          end\n                        end\n                      end\n                    end\n                  end\n                end\n              end\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"},"external_var":false},{"html_id":"to_terminal(io:IO=STDOUT)-instance-method","name":"to_terminal","abstract":false,"args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"args_string":"(io : IO = STDOUT)","args_html":"(io : IO = <span class=\"t\">STDOUT</span>)","location":{"filename":"src/vulnerability_report.cr","line_number":69,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L69"},"def":{"name":"to_terminal","args":[{"name":"io","default_value":"STDOUT","external_name":"io","restriction":"IO"}],"visibility":"Public","body":"filtered = filtered_results\nvulnerable_packages = filtered.select(&.vulnerable?)\ntotal_vulns = filtered.sum() do |__arg2| __arg2.vulnerabilities.size end\ntotal_packages = @results.size\n\nif vulnerable_packages.empty?\n  io.puts(\"No known vulnerabilities found in #{total_packages} package(s).\".colorize(:green))\n  print_stats(io)\n  return\nend\n\nio.puts((\"Found #{total_vulns} vulnerability(ies) in #{vulnerable_packages.size} package(s):\".colorize(:red)).bold)\nio.puts\n\nvulnerable_packages.each do |result|\n  io.puts((\"  #{result.package.name} (#{result.package.version})\".colorize(:yellow)).bold)\n  if purl = result.purl\n    io.puts(\"    purl: #{purl}\".colorize(:light_gray))\n  end\n\n  result.vulnerabilities.sort_by do |v| -v.severity.value end.each do |vuln|\n    severity_str = severity_badge(vuln.severity)\n    io.puts(\"    #{severity_str} #{vuln.id}\")\n    if vuln.summary.empty?\n    else\n      io.puts(\"      #{vuln.summary}\")\n    end\n\n    if vuln.aliases.empty?\n    else\n      io.puts(\"      Aliases: #{vuln.aliases.join(\", \")}\".colorize(:light_gray))\n    end\n\n    if ref = vuln.references.first?\n      io.puts(\"      More info: #{ref}\".colorize(:light_gray))\n    end\n    io.puts\n  end\nend\n\nprint_stats(io)\n"},"external_var":false},{"html_id":"vulnerability_count:Int32-instance-method","name":"vulnerability_count","doc":"Total vulnerability count after filtering.","summary":"<p>Total vulnerability count after filtering.</p>","abstract":false,"location":{"filename":"src/vulnerability_report.cr","line_number":63,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_report.cr#L63"},"def":{"name":"vulnerability_count","return_type":"Int32","visibility":"Public","body":"filtered_results.sum() do |__arg0| __arg0.vulnerabilities.size end"},"external_var":false}]},{"html_id":"Ashard/Shards/VulnerabilityScanner","path":"Shards/VulnerabilityScanner.html","kind":"class","full_name":"Shards::VulnerabilityScanner","name":"VulnerabilityScanner","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/vulnerability_scanner.cr","line_number":86,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L86"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"CACHE_DIR","name":"CACHE_DIR","value":"\".shards/audit/cache\""},{"id":"CACHE_TTL","name":"CACHE_TTL","value":"1.hour"},{"id":"OSV_BATCH_URL","name":"OSV_BATCH_URL","value":"\"https://api.osv.dev/v1/querybatch\""},{"id":"OSV_QUERY_URL","name":"OSV_QUERY_URL","value":"\"https://api.osv.dev/v1/query\""}],"namespace":{"html_id":"Ashard/Shards","kind":"module","full_name":"Shards","name":"Shards"},"class_methods":[{"html_id":"load_ignore_rules(path:String):Array(IgnoreRule)-class-method","name":"load_ignore_rules","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"}],"args_string":"(path : String) : Array(IgnoreRule)","args_html":"(path : String) : Array(<a href=\"../Shards/IgnoreRule.html\">IgnoreRule</a>)","location":{"filename":"src/vulnerability_scanner.cr","line_number":426,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L426"},"def":{"name":"load_ignore_rules","args":[{"name":"path","external_name":"path","restriction":"String"}],"return_type":"Array(IgnoreRule)","visibility":"Public","body":"rules = [] of IgnoreRule\nif File.exists?(path)\nelse\n  return rules\nend\n\nyaml = YAML.parse(File.read(path))\nif ignores = yaml[\"ignores\"]?.try(&.as_a)\n  ignores.each do |entry|\n    id = entry[\"id\"].as_s\n    reason = entry[\"reason\"]?.try(&.as_s)\n    expires = entry[\"expires\"]?.try do |e| begin\n      Time.parse(e.as_s, \"%Y-%m-%d\", Time::Location::UTC)\n    rescue\n      nil\n    end end\n    rules << (IgnoreRule.new(id, reason, expires))\n  end\nend\n\nrules\n"},"external_var":false}],"constructors":[{"html_id":"new(path:String,offline:Bool=false)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"offline","default_value":"false","external_name":"offline","restriction":"Bool"}],"args_string":"(path : String, offline : Bool = false)","args_html":"(path : String, offline : Bool = <span class=\"n\">false</span>)","location":{"filename":"src/vulnerability_scanner.cr","line_number":97,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L97"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"offline","default_value":"false","external_name":"offline","restriction":"Bool"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, offline)\nif _.responds_to?(:finalize)\n  ::GC.add_finalizer(_)\nend\n_\n"},"external_var":false}],"instance_methods":[{"html_id":"results:Array(PackageScanResult)-instance-method","name":"results","abstract":false,"location":{"filename":"src/vulnerability_scanner.cr","line_number":92,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L92"},"def":{"name":"results","return_type":"Array(PackageScanResult)","visibility":"Public","body":"@results"},"external_var":false},{"html_id":"scan(packages:Array(Package)):Array(PackageScanResult)-instance-method","name":"scan","doc":"Main entry point: scans all packages for vulnerabilities.\nReturns an array of PackageScanResult, one per package.","summary":"<p>Main entry point: scans all packages for vulnerabilities.</p>","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"args_string":"(packages : Array(Package)) : Array(PackageScanResult)","args_html":"(packages : Array(<a href=\"../Shards/Package.html\">Package</a>)) : Array(<a href=\"../Shards/PackageScanResult.html\">PackageScanResult</a>)","location":{"filename":"src/vulnerability_scanner.cr","line_number":104,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L104"},"def":{"name":"scan","args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"return_type":"Array(PackageScanResult)","visibility":"Public","body":"purl_map = {} of String => Package\nno_purl_packages = [] of Package\n\npackages.each do |pkg|\n  if purl = PurlGenerator.generate(pkg)\n    purl_map[purl] = pkg\n  else\n    no_purl_packages << pkg\n  end\nend\n\n\nvuln_map = query_batch(purl_map.keys)\n\n\n@results = [] of PackageScanResult\n\npurl_map.each do |purl, pkg|\n  vulns = vuln_map[purl]? || ([] of Vulnerability)\n  @results << (PackageScanResult.new(pkg, purl, vulns))\nend\n\n\nno_purl_packages.each do |pkg|\n  @results << (PackageScanResult.new(pkg, nil, [] of Vulnerability))\nend\n\n@results.sort_by!() do |__arg0| __arg0.package.name end\n"},"external_var":false},{"html_id":"update_cache(packages:Array(Package))-instance-method","name":"update_cache","doc":"Force refresh all cached data.","summary":"<p>Force refresh all cached data.</p>","abstract":false,"args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"args_string":"(packages : Array(Package))","args_html":"(packages : Array(<a href=\"../Shards/Package.html\">Package</a>))","location":{"filename":"src/vulnerability_scanner.cr","line_number":339,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/vulnerability_scanner.cr#L339"},"def":{"name":"update_cache","args":[{"name":"packages","external_name":"packages","restriction":"Array(Package)"}],"visibility":"Public","body":"clear_cache\nscan(packages)\n"},"external_var":false}]}]},{"html_id":"Ashard/YAML","path":"YAML.html","kind":"module","full_name":"YAML","name":"YAML","abstract":false,"locations":[{"filename":"src/ext/yaml.cr","line_number":3,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ext/yaml.cr#L3"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"doc":"The YAML module provides serialization and deserialization of YAML\nversion 1.1 to/from native Crystal data structures, with the additional\nindependent types specified in http://yaml.org/type/\n\nNOTE: To use `YAML`, you must explicitly import it with `require \"yaml\"`\n\n### Parsing with `#parse` and `#parse_all`\n\n`YAML.parse` will return an `Any`, which is a convenient wrapper around all possible\nYAML core types, making it easy to traverse a complex YAML structure but requires\nsome casts from time to time, mostly via some method invocations.\n\n```\nrequire \"yaml\"\n\ndata = YAML.parse <<-YAML\n         ---\n         foo:\n           bar:\n             baz:\n               - qux\n               - fox\n         YAML\ndata[\"foo\"][\"bar\"][\"baz\"][1].as_s # => \"fox\"\n```\n\n`YAML.parse` can read from an `IO` directly (such as a file) which saves\nallocating a string:\n\n```\nrequire \"yaml\"\n\nyaml = File.open(\"path/to/file.yml\") do |file|\n  YAML.parse(file)\nend\n```\n\n### Parsing with `from_yaml`\n\nA type `T` can be deserialized from YAML by invoking `T.from_yaml(string_or_io)`.\nFor this to work, `T` must implement\n`new(ctx : YAML::PullParser, node : YAML::Nodes::Node)` and decode\na value from the given *node*, using *ctx* to store and retrieve\nanchored values (see `YAML::PullParser` for an explanation of this).\n\nCrystal primitive types, `Time`, `Bytes` and `Union` implement\nthis method. `YAML::Serializable` can be used to implement this method\nfor user types.\n\n### Dumping with `YAML.dump` or `#to_yaml`\n\n`YAML.dump` generates the YAML representation for an object.\nAn `IO` can be passed and it will be written there,\notherwise it will be returned as a string. Similarly, `#to_yaml`\n(with or without an `IO`) on any object does the same.\n\nFor this to work, the type given to `YAML.dump` must implement\n`to_yaml(builder : YAML::Nodes::Builder`).\n\nCrystal primitive types, `Time` and `Bytes` implement\nthis method. `YAML::Serializable` can be used to implement this method\nfor user types.\n\n```\nyaml = YAML.dump({hello: \"world\"})                               # => \"---\\nhello: world\\n\"\nFile.open(\"foo.yml\", \"w\") { |f| YAML.dump({hello: \"world\"}, f) } # writes it to the file\n# or:\nyaml = {hello: \"world\"}.to_yaml                               # => \"---\\nhello: world\\n\"\nFile.open(\"foo.yml\", \"w\") { |f| {hello: \"world\"}.to_yaml(f) } # writes it to the file\n```","summary":"<p>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/</p>","types":[{"html_id":"Ashard/YAML/PullParser","path":"YAML/PullParser.html","kind":"class","full_name":"YAML::PullParser","name":"PullParser","abstract":false,"superclass":{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"Ashard/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"Ashard/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/ext/yaml.cr","line_number":4,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ext/yaml.cr#L4"}],"repository_name":"Ashard","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"Ashard/YAML","kind":"module","full_name":"YAML","name":"YAML"},"doc":"A pull parser allows parsing a YAML document by events.\n\nWhen creating an instance, the parser is positioned in\nthe first event. To get the event kind invoke `kind`.\nIf the event is a scalar you can invoke `value` to get\nits **string** value. Other methods like `tag`, `anchor`\nand `scalar_style` let you inspect other information from events.\n\nInvoking `read_next` reads the next event.","summary":"<p>A pull parser allows parsing a YAML document by events.</p>","instance_methods":[{"html_id":"each_in_mapping(&):Nil-instance-method","name":"each_in_mapping","doc":"Iterates a mapping, yielding on each new entry until the mapping is\nterminated.","summary":"<p>Iterates a mapping, yielding on each new entry until the mapping is terminated.</p>","abstract":false,"location":{"filename":"src/ext/yaml.cr","line_number":17,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ext/yaml.cr#L17"},"def":{"name":"each_in_mapping","yields":0,"block_arity":0,"return_type":"Nil","visibility":"Public","body":"read_mapping_start\nwhile !(kind == YAML::EventKind::MAPPING_END)\n  yield\nend\nread_mapping_end\n"},"external_var":false},{"html_id":"each_in_sequence(&):Nil-instance-method","name":"each_in_sequence","doc":"Iterates a sequence, yielding on each new entry until the sequence is\nterminated.","summary":"<p>Iterates a sequence, yielding on each new entry until the sequence is terminated.</p>","abstract":false,"location":{"filename":"src/ext/yaml.cr","line_number":7,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ext/yaml.cr#L7"},"def":{"name":"each_in_sequence","yields":0,"block_arity":0,"return_type":"Nil","visibility":"Public","body":"read_sequence_start\nwhile !(kind == YAML::EventKind::SEQUENCE_END)\n  yield\nend\nread_sequence_end\n"},"external_var":false},{"html_id":"read_empty_or(&)-instance-method","name":"read_empty_or","abstract":false,"location":{"filename":"src/ext/yaml.cr","line_number":25,"url":"https://github.com/crimson-knight/shards/blob/codex/upstream-compatibility-guardrails/src/ext/yaml.cr#L25"},"def":{"name":"read_empty_or","yields":0,"block_arity":0,"visibility":"Public","body":"if kind.scalar?\n  case value\n  when \"\", \"~\"\n    read_next\n    return\n  end\nend\n\nyield\n"},"external_var":false}]}]}]}}