Claude skill · cast

discover-shed-tool

Search the Tool Shed for an existing wrapper, drill from hit to a pinnable changeset, classify candidates, and recommend or fall through.

← All cast skills · Source mold →

Install

/plugin marketplace add jmchilton/foundry
/plugin install foundry-skills@galaxy-workflow-foundry

Then invoke as:

/foundry-skills:discover-shed-tool

Skill Bundle

/ packaged cast
attached files
5
upfront
1
on demand
4
cast rev
5
validated
0

Produces: 1 artifact.

Artifact Contract

/ skill handoff

Produces

galaxy-tool-pin

(owner, repo, tool_id, version, changeset_revision) pin for a Tool Shed wrapper plus discovery classification.

jsongalaxy-tool-pin.json[[galaxy-tool-discovery]]
Raw artifact contract
{
  "id": "galaxy-tool-pin",
  "kind": "json",
  "default_filename": "galaxy-tool-pin.json",
  "schema": "[[galaxy-tool-discovery]]",
  "description": "(owner, repo, tool_id, version, changeset_revision) pin for a Tool Shed wrapper plus discovery classification."
}

Attached Files

/ runtime references

Load upfront

schema

galaxy-tool-discovery

packaged

Validate the hit, weak, or miss recommendation emitted by Tool Shed discovery.

upfront runtime verbatim cast-validated deterministic 7.5 KB
bundle
references/schemas/galaxy-tool-discovery.schema.json
source
package://@galaxy-foundry/foundry#galaxyToolDiscoverySchema
Preview json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://galaxyproject.org/foundry/schemas/galaxy-tool-discovery.schema.json",
  "$comment": "Canonical source: packages/foundry/src/schemas/galaxy-tool-discovery/galaxy-tool-discovery.schema.json in jmchilton/foundry. Mold frontmatter cites this schema via [[galaxy-tool-discovery]] wiki-links; the cast pipeline imports the `galaxyToolDiscoverySchema` runtime export and serializes it into cast bundles.",
  "title": "Galaxy Tool Discovery Recommendation",
  "description": "Structured recommendation emitted by the discover-shed-tool Mold after searching the Galaxy Tool Shed and resolving any selected candidate to a pinnable Tool Shed version and changeset revision.",
  "$ref": "#/$defs/DiscoveryRecommendation",
  "$defs": {
    "DiscoveryRecommendation": {
      "title": "DiscoveryRecommendation",
      "description": "Top-level output from discover-shed-tool. A hit or weak result carries a selected candidate; a miss carries null candidate plus fallthrough rationale.",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "status",
        "candidate",
        "alternates",
        "rationale",
        "warnings"
      ],
      "properties": {
        "status": {
          "type": "string",
          "enum": [
            "hit",
            "weak",
            "miss"
          ],
          "description": "Recommendation class. hit means proceed with the selected Tool Shed pin; weak means candidate exists but needs confirmation or may fall through; miss means no usable wrapper was found."
        },
        "candidate": {
          "anyOf": [
            {
              "$ref": "#/$defs/ToolCandidate"
            },
            {
              "type": "null"
            }
          ],
          "description": "Selected candidate for hit/weak results. Null for miss."
        },
        "alternates": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/ToolCandidate"
          },
          "description": "Runner-up candidates worth surfacing to the user or harness. Empty when no plausible alternates were found."
        },
        "rationale": {
          "type": "string",
          "minLength": 1,
          "description": "Short explanation of why this status and candidate were selected, including ambiguity or fallthrough reasoning."
  
...

Load on demand

cli-command

tool-revisions

packaged

Resolve a Tool Shed tool version to an installable changeset revision.

Trigger: After selecting a candidate version that needs a reproducible changeset pin.

on-demand runtime sidecar corpus-observed deterministic 3.0 KB
bundle
references/cli/tool-revisions.json
source
content/cli/gxwf/tool-revisions.md
Preview json
{
  "type": "cli-command",
  "tool": "gxwf",
  "command": "tool-revisions",
  "summary": "Resolve a Tool Shed tool to changeset revisions for reproducible workflow pinning. Final step in discover-and-pin.",
  "source_path": "content/cli/gxwf/tool-revisions.md",
  "source_revision": 2,
  "body": "# `gxwf tool-revisions`\n\nResolve a Tool Shed tool to the changeset revisions that publish it, ordered oldest→newest by `get_ordered_installable_revisions`. Needed when emitting a workflow that pins `(name, owner, changeset_revision)` for reproducible reinstall — TRS version strings alone are insufficient because the Tool Shed dedupes versions across changesets.\n\n`<tool-id>` accepts both TRS form (`owner~repo~tool_id`) and pretty form (`owner/repo/tool_id`).\n\n## Output\n\nDefault: lines of `<changesetRevision>\\t<toolVersion>`.\n\n`--json`:\n\n```json\n{\n  \"trsToolId\": \"devteam~fastqc~fastqc\",\n  \"version\": \"0.74+galaxy0\",\n  \"revisions\": [\n    { \"changesetRevision\": \"5ec9f6bceaee\", \"toolVersion\": \"0.74+galaxy0\" }\n  ]\n}\n```\n\n`--json` without `--tool-version` returns every installable revision for the tool, each tagged with whatever XML `version` it publishes.\n\n## Examples\n\n```bash\ngxwf tool-revisions devteam/fastqc/fastqc --json\ngxwf tool-revisions devteam/fastqc/fastqc --tool-version 0.74+galaxy0 --latest\ngxwf tool-revisions devteam~fastqc~fastqc --json | jq '.revisions[-1]'\n```\n\nPin the latest changeset for a known version:\n\n```bash\nREV=$(gxwf tool-revisions devteam/fastqc/fastqc \\\n        --tool-version 0.74+galaxy0 --latest --json \\\n        | jq -r '.revisions[0].changesetRevision')\necho \"$REV\"\n```\n\n## Gotchas\n\n- **Tool versions are not monotonic.** Two changesets can legally publish the same XML `version` with different content. When pinning for reproducibility, prefer the **newest matching revision** (`--latest`) or be explicit about which changeset you want — the version string alone is ambiguous. See [[component-tool-shed-search]] §5.\n- **Source of truth for installability.** Only changesets with a `RepositoryMetadata` row marked `downloadable=True` are returned. A repository may have many additional changesets in its Mercurial history that are not installable; those are correctly excluded here.\n- **Pin shape is `(name, owner, changeset_revision)`**, not the TRS id. Workflows ultimately reference repos 
...
cli-command

tool-search

packaged

Search the Tool Shed for candidate wrappers matching a step's tool need.

Trigger: When resolving a workflow step to an installable Galaxy tool wrapper.

on-demand runtime sidecar corpus-observed deterministic 3.4 KB
bundle
references/cli/tool-search.json
source
content/cli/gxwf/tool-search.md
Preview json
{
  "type": "cli-command",
  "tool": "gxwf",
  "command": "tool-search",
  "summary": "Free-text Tool Shed search returning candidate tools as JSON; first step in the discover-and-pin sequence.",
  "source_path": "content/cli/gxwf/tool-search.md",
  "source_revision": 2,
  "body": "# `gxwf tool-search`\n\nFree-text search over the Galaxy Tool Shed's tool index. Designed to feed `galaxy-tool-cache add` (and the rest of the `tool-versions` / `tool-revisions` chain) so a workflow author can go from a query string to a cached `ParsedTool` in a small number of commands.\n\nInstance-agnostic; targets `https://toolshed.g2.bx.psu.edu` by default.\n\n`<query>` is free text; whitespace separates terms. The Tool Shed wraps the term as `*term*` server-side, so noisy queries can match description and help text.\n\n## Output\n\nDefault: human-readable list.\n\n`--json`:\n\n```json\n{\n  \"query\": \"fastqc\",\n  \"hits\": [\n    {\n      \"toolId\": \"fastqc\",\n      \"name\": \"FastQC\",\n      \"description\": \"Read Quality reports\",\n      \"owner\": \"devteam\",\n      \"repoName\": \"fastqc\",\n      \"trsToolId\": \"devteam~fastqc~fastqc\",\n      \"score\": 12.3\n    }\n  ]\n}\n```\n\nA hit identifies `(owner, repoName, toolId)` plus a `trsToolId` (`owner~repo~toolId`). It does **not** include a changeset revision or specific tool version — those come from [[tool-versions]] and [[tool-revisions]].\n\n## Examples\n\n```bash\ngxwf tool-search fastqc\ngxwf tool-search \"quality control\" --json --max-results 10\ngxwf tool-search bwa --owner devteam --match-name --json\n```\n\nPipe the top hit into the rest of the pin chain:\n\n```bash\ngxwf tool-search fastqc --json --max-results 5 \\\n  | jq -r '.hits[0].trsToolId' \\\n  | xargs gxwf tool-versions --latest --json\n```\n\n## Gotchas\n\n- **No EDAM**, no stem analyzer, no panel context — the Tool Shed tool index is much poorer than Galaxy's installed-toolbox index. Queries match only `name`, `description`, `help`, and `repo_owner_username`. See [[component-tool-shed-search]] §2b.\n- **Case-sensitivity asymmetry**. The tool search does not lowercase the query (unlike repo search). Mixed-case queries can miss; lowercase if uncertain.\n- **Stale indexes**. Tool Shed Whoosh indexes are rebuilt by cron / admin action, never automatically on upload. A freshly published tool may not show up for some time. Deprecated repos 
...
cli-command

tool-versions

packaged

List available Tool Shed versions for a selected candidate.

Trigger: After a Tool Shed search candidate is selected and before pinning a version.

on-demand runtime sidecar corpus-observed deterministic 2.8 KB
bundle
references/cli/tool-versions.json
source
content/cli/gxwf/tool-versions.md
Preview json
{
  "type": "cli-command",
  "tool": "gxwf",
  "command": "tool-versions",
  "summary": "List TRS-published versions of a Tool Shed tool, oldest→newest. Second step in the discover-and-pin sequence.",
  "source_path": "content/cli/gxwf/tool-versions.md",
  "source_revision": 2,
  "body": "# `gxwf tool-versions`\n\nList the TRS-published versions of a Tool Shed tool, ordered oldest→newest (newest last). Used after [[tool-search]] has surfaced a candidate `trsToolId` and the caller needs to pick a version to cache.\n\n`<tool-id>` accepts both forms:\n- TRS form: `owner~repo~tool_id` (e.g. `devteam~fastqc~fastqc`).\n- Pretty form: `owner/repo/tool_id` (e.g. `devteam/fastqc/fastqc`).\n\nThe `~` form is the Tool Shed's TRS encoding (slashes break FastAPI path-param decoding); the CLI accepts both and normalizes.\n\n## Output\n\nDefault: one version string per line, oldest first.\n\n`--json`:\n\n```json\n{\n  \"trsToolId\": \"devteam~fastqc~fastqc\",\n  \"versions\": [\"0.72+galaxy1\", \"0.73+galaxy0\", \"0.74+galaxy0\"]\n}\n```\n\n`--latest --json`:\n\n```json\n{\n  \"trsToolId\": \"devteam~fastqc~fastqc\",\n  \"versions\": [\"0.74+galaxy0\"]\n}\n```\n\n## Examples\n\n```bash\ngxwf tool-versions devteam/fastqc/fastqc\ngxwf tool-versions devteam~fastqc~fastqc --latest\ngxwf tool-versions devteam/fastqc/fastqc --json\n```\n\n## Gotchas\n\n- **TRS dedupes by version string.** If multiple changesets publish the same `version` (which is legal — the XML version field is not monotonic and not enforced unique), only the last-seen one appears. The other changesets are invisible at this layer. To see the full set of changesets that publish a given version, use [[tool-revisions]]. See [[component-tool-shed-search]] §3 and §5.\n- **`--latest` returns the lexicographically/iteration-order last item, not a semver-parsed maximum.** In practice the TRS list is ordered consistent with the Tool Shed's installable-revisions ordering, so \"newest\" is normally what you want — but do not assume strict semver semantics.\n- **Versions ≠ changesets.** A single TRS version can correspond to multiple changesets in the underlying Mercurial repo. Pinning a workflow for reproducible reinstall requires a `(name, owner, changeset_revision)` triple, not just a version — that is what [[tool-revisions]] produces.\n- **Stub list endpoint.** The Tool Shed's TRS `/tools` enumerator is unimplemented 
...
research

component-tool-shed-search

packaged

Explain Tool Shed search/indexing limitations that affect hit scoring and fallthrough decisions.

Trigger: When results are missing, weak, duplicated across owners, stale, or ambiguous.

on-demand runtime verbatim corpus-observed deterministic 27.1 KB
bundle
references/notes/component-tool-shed-search.md
source
content/research/component-tool-shed-search.md
Preview md
---
type: research
subtype: component
tags:
  - research/component
component: "Tool Shed Search and Indexing"
status: draft
created: 2026-04-30
revised: 2026-05-03
revision: 2
ai_generated: true
summary: "Tool Shed's Whoosh repo/tool search and partial GA4GH TRS v2, indexed from hg-walked metadata with no auto-refresh on upload"
related_notes:
  - "[[galaxy-tool-summary-input-source]]"
  - "[[tool-search]]"
  - "[[tool-versions]]"
  - "[[tool-revisions]]"
  - "[[discover-shed-tool]]"
---

# Galaxy Tool Shed — Search, Indexing, and TRS APIs: Current State

## 1. Architecture primer

The Galaxy Tool Shed is a standalone web application that hosts and serves Galaxy tool wrappers (XML tool definitions plus helper files) to Galaxy servers for installation. Its server code lives under `lib/tool_shed/` in the Galaxy monorepo, sharing model/security/tool-parsing libraries with Galaxy itself but running as its own FastAPI application (`lib/tool_shed/webapp/fast_app.py`, with route modules under `lib/tool_shed/webapp/api2/`). The legacy web framework is almost gone — only `lib/tool_shed/webapp/controllers/hg.py` survives, because the Tool Shed also serves each repository's Mercurial working copy over HTTP for `hg clone`.

A **repository** is the unit of distribution in the Tool Shed: it is a named, owned Mercurial repository (the Tool Shed still runs on `hg`, not `git` — see `mercurial` imports in `lib/tool_shed/util/shed_index.py:4` and `lib/tool_shed/managers/repositories.py:471` onward). A repository has a `name`, an owner (`User.username`), a `type` (e.g. `unrestricted`, `repository_suite_definition`, `tool_dependency_definition` — see `lib/tool_shed/repository_types/`), optional `description`/`long_description`/`homepage_url`/`remote_repository_url`, and a set of categories 
...

SKILL.md


# discover-shed-tool

Follow the procedure below and use the artifact/reference sections as the runtime contract.

## When To Use

- Search the Tool Shed for an existing wrapper, drill from hit to a pinnable changeset, classify candidates, and recommend or fall through.

## Inputs

- No upstream artifact inputs declared. See the procedure for user-supplied runtime inputs.

## Outputs

- Write artifact `galaxy-tool-pin` as `galaxy-tool-pin.json`. Format: `json`. Schema: galaxy-tool-discovery. (owner, repo, tool_id, version, changeset_revision) pin for a Tool Shed wrapper plus discovery classification.

## Required Tools

- **`gxwf`** (gxwf). `npm install -g @galaxy-tool-util/cli`.
  Ephemeral run: `npx --package @galaxy-tool-util/cli gxwf`.
  Check: `gxwf --version`.
  Docs: https://github.com/jmchilton/galaxy-tool-util-ts/tree/main/packages/cli

## Load Upfront

- `references/schemas/galaxy-tool-discovery.schema.json`: Schema file copied verbatim into the bundle. Validate the hit, weak, or miss recommendation emitted by Tool Shed discovery.

## Load On Demand

- `references/cli/tool-revisions.json`: CLI command reference packaged as a sidecar. Resolve a Tool Shed tool version to an installable changeset revision. Use when: after selecting a candidate version that needs a reproducible changeset pin.
- `references/cli/tool-search.json`: CLI command reference packaged as a sidecar. Search the Tool Shed for candidate wrappers matching a step's tool need. Use when: resolving a workflow step to an installable Galaxy tool wrapper.
- `references/cli/tool-versions.json`: CLI command reference packaged as a sidecar. List available Tool Shed versions for a selected candidate. Use when: after a Tool Shed search candidate is selected and before pinning a version.
- `references/notes/component-tool-shed-search.md`: Research note copied verbatim into the bundle. Explain Tool Shed search/indexing limitations that affect hit scoring and fallthrough decisions. Use when: results are missing, weak, duplicated across owners, stale, or ambiguous.

## Validation

- Validate `galaxy-tool-pin.json` before returning it: run `foundry galaxy-tool-pin.json` from `@galaxy-foundry/foundry`. If the command is not on PATH, run `npx --package @galaxy-foundry/foundry foundry galaxy-tool-pin.json`. This checks artifact `galaxy-tool-pin` against the galaxy-tool-discovery schema.

## Procedure

Discover whether the Galaxy Tool Shed already publishes a wrapper for the tool a workflow step needs, and resolve the discovery to a `(owner, repo, tool_id, version, changeset_revision)` quintuple that downstream steps can pin and cache.

This skill is the **Tool Shed leg** of the `discover-or-author` branch in Galaxy-targeting per-step pipelines. On a hit, the skill recommends a pin and exits successfully. On a miss (or a low-quality hit), it falls through to author-galaxy-tool-wrapper. The branch itself is harness logic; this skill owns only the discovery half.

### Inputs

The skill expects, per step:

- A free-text **need** describing what the step should do (typically a one-line description of the tool, plus any constraints — file format in/out, container language, license preferences).
- Optional **owner hint** (e.g. `devteam`, `iuc`) when the caller has a strong prior.
- Optional **exact-name hint** when the caller knows the canonical XML id.

### Outputs

A structured recommendation object, JSON-shaped:

```json
{
  "status": "hit",
  "candidate": {
    "tool_shed_url": "https://toolshed.g2.bx.psu.edu",
    "owner": "devteam",
    "repo": "fastqc",
    "tool_id": "fastqc",
    "trs_tool_id": "devteam~fastqc~fastqc",
    "version": "0.74+galaxy0",
    "changeset_revision": "5ec9f6bceaee",
    "score": 12.3,
    "matched_terms": ["fastqc"],
    "match_fields": ["name", "description"],
    "rationale": "single dominant hit on tool name"
  },
  "alternates": [],
  "rationale": "single dominant hit on tool name; latest version pinned to newest changeset",
  "warnings": []
}
```

`status` semantics:
- `hit` — recommend pinning. Caller should cache and proceed.
- `weak` — candidate exists but the skill is not confident (e.g. only help-text matched, multiple owners with similar tools, deprecated repo, stale-index suspicion). Caller should confirm or fall through.
- `miss` — no usable hit. Caller falls through to author-galaxy-tool-wrapper.

### Procedure

The skill follows the gxwf-shaped discover-and-pin chain. **It does not call the Tool Shed HTTP API directly** — the TS CLI wraps the call sequence and gotchas covered in component-tool-shed-search.

#### 1. Search

Issue tool-search with the need's keywords. Start narrow:

```
gxwf tool-search "<keywords>" --json --max-results 10
```

If an owner hint is present, add `--owner <owner>`. If an exact-name hint is present, add `--match-name`. Lowercase the query (the tool index does not lowercase, see component-tool-shed-search §6).

#### 2. Triage hits

For each hit, score on:
- **Name match.** Exact match on `toolId` or `name` is a strong signal; help-only matches are weak.
- **Owner reputation.** `iuc` and `devteam` repos are typically maintained; an unfamiliar owner with a single-tool repo is a weaker prior. (No machine-readable approval flag exists — the Tool Shed's `approved` field is dead code.)
- **Recency.** Recent `last_updated` strengthens a hit; very old wrappers can still be valid but warrant the `weak` classification.
- **Duplicates across repos.** Two owners can publish wrappers with the same XML id. Either pick the maintained one or downgrade to `weak` and surface the choice.

Drop hits from deprecated repos when detectable. Note: deprecated repos can still appear in shed search results until the next index rebuild — see component-tool-shed-search §6.

#### 3. Resolve to a pinnable version

For the top candidate, list versions:

```
gxwf tool-versions <trsToolId> --json
```

Pick the newest installable version unless the need specifies otherwise (rare: a workflow may pin to a specific historical version for reproducibility). Be aware that **TRS dedupes by version string** — multiple changesets may publish the same version, and only one is visible at this layer.

#### 4. Resolve to a changeset

Drill from `(trsToolId, version)` to a concrete changeset:

```
gxwf tool-revisions <trsToolId> --tool-version <v> --latest --json
```

Prefer `--latest` so the newest changeset publishing that version wins (tool versions are not monotonic; two changesets can legally publish the same version with different content). The output's `changesetRevision` is what lands in the workflow's `tool_shed_repository.changeset_revision` for reproducible reinstall.

#### 5. Classify and emit

Combine the scored hit and the resolved pin into the recommendation object above:
- One dominant hit + clean version+changeset resolution → `hit`.
- Multiple plausible hits, ambiguous owner, deprecated suspicion, or only-help-text match → `weak` with the leading candidate plus alternates.
- No usable hit → `miss`.

Validate the recommendation with `validate-galaxy-tool-discovery` before returning it. Do not rely on prose-only shape checks; downstream phases branch on this contract.

### Caveats baked into the procedure

The procedure assumes — and the skill must surface in its rationale when relevant — the following Tool Shed realities (full detail in component-tool-shed-search §6):

- **Indexes are stale by design.** A freshly published tool may not appear; a deprecated tool may still appear. Treat absence as soft evidence, not proof.
- **Wildcard `*term*` wrapping** disables stemming; spelling matters. Try alternate phrasings before declaring `miss`.
- **No EDAM in shed search** — semantic queries that work in Galaxy's installed-toolbox search will not work here. Stick to lexical name/keyword queries.
- **Same XML id across repos.** Hits collapse only on `(repoName, owner)`; expect duplicates that need triage.
- **Repo-level discovery is a different surface.** For "find me the *package* that contains a tool about X" with server-side `owner:` / `category:` keywords, `gxwf repo-search` is the right command — out of scope for this skill but a known sibling.

### Non-goals

- **Authoring.** This skill never produces a tool wrapper. On `miss`, the harness's `discover-or-author` branch fall-through invokes author-galaxy-tool-wrapper.
- **Caching.** This skill emits a pin recommendation. The caller (or the next phase) runs `galaxy-tool-cache add toolshed.g2.bx.psu.edu/repos/<owner>/<repo>/<tool_id> --version <v>` to populate the cache.
- **Galaxy-instance discovery.** Hitting a running Galaxy server's installed-tool index (EDAM-aware, panel-aware) is a different mechanism — the future `discover-tool-via-galaxy-api` skill. The contrast is sketched in component-tool-shed-search §4.
- **Test-data resolution.** Out of scope; handled by the `test-data-resolution` branch elsewhere in the pipeline.

## Runtime Notes

- Do not read Foundry source files at runtime; use only files packaged in this skill bundle and user-supplied artifacts.
- Preserve declared artifact filenames unless the user or harness supplies explicit paths.
- Carry unresolved assumptions into the output artifact instead of silently inventing missing source evidence.