Posted by Claude (AI assistant) on behalf of @jmchilton — not authored by them personally.
Why this matters for Foundry
The per-step Galaxy authoring loop (advance-galaxy-draft-step → summarize-galaxy-tool → implement-galaxy-tool-step) needs concrete tool_version + ports for stock/built-in Galaxy tools (Filter1, sort1, Cut1, Show beginning1, Show tail1, collection ops, …). The intended resolution is the same galaxy-tool-cache flow used for Tool Shed tools, just with a bare tool_id instead of owner~repo~tool_id.
In a recent emulated INTERVIEW→GALAXY run that resolution path didn't fire and the agent hallucinated versions: Show beginning1 pinned 1.0.0 (cached real: 1.0.2), Show tail1 1.0.0 (real: 1.0.1). The wrong pins validated green locally (the run's shed-only --cache-dir skipped built-in tool_state) and only surfaced at terminal gxwf validate as a confusing "not in cache".
Root cause: galaxy-tool-cache add is broken for stock/built-in ids upstream (@galaxy-tool-util 1.7.2), so the cache can't be populated the documented way, so the loop has no version source and guesses. (add/summarize are meant to accept bare stock ids — normalizeShortTrsToolId explicitly passes cat1/upload1 through verbatim.)
What works today (verified)
With a cache already populated (locally worked-around), stock tools resolve fine with the bare id:
galaxy-tool-cache list --json — default cache enumerates stock + shed tools with versions (the version-discovery surface). e.g. Filter1 1.1.1, sort1 1.2.0, Cut1 1.0.2, Show beginning1 1.0.2, Show tail1 1.0.1.
galaxy-tool-cache summarize "Show beginning1" --tool-version 1.0.2 → full galaxy-tool-summary manifest (parsed_tool ports/datatypes, source.kind: local). Verified for all five tools above.
summarize requires --tool-version (no auto-default even when exactly one version is cached): summarize Cut1 → No version specified for tool: Cut1.
So the consumer side (summarize / list) is fine on bare stock ids. The gap is populating the cache via add.
The bug: add on a stock id
$ galaxy-tool-cache add Filter1 --cache-dir $TMP
TRS latest-version lookup failed for Filter1 on https://toolshed.g2.bx.psu.edu:
TRS versions request to https://toolshed.g2.bx.psu.edu/api/ga4gh/trs/v2/tools/Filter1/versions failed: 500 Internal Server Error
Error: No version available for tool: Filter1
at ToolInfoService.getToolInfo (.../@galaxy-tool-util/core/dist/tool-info.js:40:23)
... (unhandled throw, Node crash)
Root-cause chain (@galaxy-tool-util/core 1.7.2 → upstream jmchilton/galaxy-tool-util-ts)
- Stock coords are pinned to the ToolShed.
cache/tool-cache.js#resolveToolCoordinates: a stock id has no /repos/ and fails normalizeShortTrsToolId (not owner~repo~tool), so it falls through to toolshedUrl = defaultToolshedUrl, trsToolId = <id> verbatim, version = toolVersion ?? null. (Also yields a malformed readableId like toolshed.g2.bx.psu.edu/repos/Filter1.) Stock tools live in a Galaxy instance, not the shed — this is the wrong source.
- Version resolution only queries the ToolShed TRS.
tool-info.js#getToolInfo: when version === null it calls resolveLatestVersion(toolshedUrl, trsToolId) → TRS …/api/ga4gh/trs/v2/tools/<id>/versions. For a stock id that 500s → returns null → throw new Error("No version available for tool: <id>"). A stock tool's version can only come from Galaxy, which is never consulted for version resolution.
- No Galaxy source registered without
--galaxy-url. ToolInfoService constructor only pushes a {type:"galaxy"} source when opts.galaxyUrl is set; otherwise sources = [toolshed] only. So even past version resolution there's no viable fetch source for a stock id by default. (fetchFromGalaxy(url, toolId, version) → <galaxy>/api/tools/<toolId>/parsed is the path that should serve it.)
- Error-handling mismatch → unhandled crash.
cli/commands/add.js guards result === null ("Failed to fetch tool", exitCode=1), but getToolInfo throws on no-version, so the throw escapes the guard → Node stack-trace crash (and process.exitCode left 0).
Intended behavior
add "<stock_id>" (with a Galaxy source — a configured/default instance, and/or --galaxy-url) should fetch <galaxy>/api/tools/<stock_id>/parsed, resolve the version from Galaxy, and cache it (source: galaxy/local), so summarize/list/schema work with the bare id. The local workaround pre-seeds the cache from a Galaxy tree (→ source: local), confirming the fetched shape is correct.
Proposed upstream fixes (galaxy-tool-util-ts)
- Recognize stock/built-in ids (no
/repos/, no ~) and route them to a Galaxy source for both version resolution and fetch — not the ToolShed TRS.
- Let version resolution fall back to the Galaxy instance (
/api/tools/<id> version) when the shed has no entry, instead of throwing.
- Make stock
add usable without --galaxy-url (default/configured Galaxy) or fail fast with a clear "stock tool requires a Galaxy source (--galaxy-url)" message.
- Fix the throw-vs-null contract between
getToolInfo and add.js so failures exit cleanly (exitCode=1, no stack trace).
Foundry-side follow-up (after add is fixed upstream)
Harden the Tool-Shed-only framing so the loop resolves stock tools instead of guessing:
content/cli/galaxy-tool-cache/summarize.md — document bare stock-id support; --tool-version required.
- New
content/cli/galaxy-tool-cache/list.md — version-discovery surface; default cache carries stock tools.
content/cli/galaxy-tool-cache/add.md — stock ids aren't on the shed; populate from a Galaxy source.
- Molds
summarize-galaxy-tool, advance-galaxy-draft-step (step 2), implement-galaxy-tool-step (step 2) — add a built-in branch: discover version via list, populate via add (Galaxy source), summarize via bare id + --tool-version; never hand-guess a stock version.
- Optionally strengthen
draft-validate --concrete to resolve built-ins against the default cache so a guessed version can't validate green.
Env: @galaxy-tool-util/cli + @galaxy-tool-util/core 1.7.2 (vendored in node_modules), Node 25.6.1.
Why this matters for Foundry
The per-step Galaxy authoring loop (
advance-galaxy-draft-step→summarize-galaxy-tool→implement-galaxy-tool-step) needs concretetool_version+ ports for stock/built-in Galaxy tools (Filter1,sort1,Cut1,Show beginning1,Show tail1, collection ops, …). The intended resolution is the samegalaxy-tool-cacheflow used for Tool Shed tools, just with a baretool_idinstead ofowner~repo~tool_id.In a recent emulated INTERVIEW→GALAXY run that resolution path didn't fire and the agent hallucinated versions:
Show beginning1pinned1.0.0(cached real:1.0.2),Show tail11.0.0(real:1.0.1). The wrong pins validated green locally (the run's shed-only--cache-dirskipped built-in tool_state) and only surfaced at terminalgxwf validateas a confusing "not in cache".Root cause:
galaxy-tool-cache addis broken for stock/built-in ids upstream (@galaxy-tool-util1.7.2), so the cache can't be populated the documented way, so the loop has no version source and guesses. (add/summarizeare meant to accept bare stock ids —normalizeShortTrsToolIdexplicitly passescat1/upload1through verbatim.)What works today (verified)
With a cache already populated (locally worked-around), stock tools resolve fine with the bare id:
galaxy-tool-cache list --json— default cache enumerates stock + shed tools with versions (the version-discovery surface). e.g.Filter1 1.1.1,sort1 1.2.0,Cut1 1.0.2,Show beginning1 1.0.2,Show tail1 1.0.1.galaxy-tool-cache summarize "Show beginning1" --tool-version 1.0.2→ fullgalaxy-tool-summarymanifest (parsed_toolports/datatypes,source.kind: local). Verified for all five tools above.summarizerequires--tool-version(no auto-default even when exactly one version is cached):summarize Cut1→No version specified for tool: Cut1.So the consumer side (
summarize/list) is fine on bare stock ids. The gap is populating the cache viaadd.The bug:
addon a stock idRoot-cause chain (
@galaxy-tool-util/core1.7.2 → upstreamjmchilton/galaxy-tool-util-ts)cache/tool-cache.js#resolveToolCoordinates: a stock id has no/repos/and failsnormalizeShortTrsToolId(notowner~repo~tool), so it falls through totoolshedUrl = defaultToolshedUrl,trsToolId = <id>verbatim,version = toolVersion ?? null. (Also yields a malformedreadableIdliketoolshed.g2.bx.psu.edu/repos/Filter1.) Stock tools live in a Galaxy instance, not the shed — this is the wrong source.tool-info.js#getToolInfo: whenversion === nullit callsresolveLatestVersion(toolshedUrl, trsToolId)→ TRS…/api/ga4gh/trs/v2/tools/<id>/versions. For a stock id that 500s → returnsnull→throw new Error("No version available for tool: <id>"). A stock tool's version can only come from Galaxy, which is never consulted for version resolution.--galaxy-url.ToolInfoServiceconstructor only pushes a{type:"galaxy"}source whenopts.galaxyUrlis set; otherwisesources = [toolshed]only. So even past version resolution there's no viable fetch source for a stock id by default. (fetchFromGalaxy(url, toolId, version)→<galaxy>/api/tools/<toolId>/parsedis the path that should serve it.)cli/commands/add.jsguardsresult === null("Failed to fetch tool",exitCode=1), butgetToolInfothrows on no-version, so the throw escapes the guard → Node stack-trace crash (andprocess.exitCodeleft 0).Intended behavior
add "<stock_id>"(with a Galaxy source — a configured/default instance, and/or--galaxy-url) should fetch<galaxy>/api/tools/<stock_id>/parsed, resolve the version from Galaxy, and cache it (source: galaxy/local), sosummarize/list/schemawork with the bare id. The local workaround pre-seeds the cache from a Galaxy tree (→source: local), confirming the fetched shape is correct.Proposed upstream fixes (galaxy-tool-util-ts)
/repos/, no~) and route them to a Galaxy source for both version resolution and fetch — not the ToolShed TRS./api/tools/<id>version) when the shed has no entry, instead of throwing.addusable without--galaxy-url(default/configured Galaxy) or fail fast with a clear "stock tool requires a Galaxy source (--galaxy-url)" message.getToolInfoandadd.jsso failures exit cleanly (exitCode=1, no stack trace).Foundry-side follow-up (after
addis fixed upstream)Harden the Tool-Shed-only framing so the loop resolves stock tools instead of guessing:
content/cli/galaxy-tool-cache/summarize.md— document bare stock-id support;--tool-versionrequired.content/cli/galaxy-tool-cache/list.md— version-discovery surface; default cache carries stock tools.content/cli/galaxy-tool-cache/add.md— stock ids aren't on the shed; populate from a Galaxy source.summarize-galaxy-tool,advance-galaxy-draft-step(step 2),implement-galaxy-tool-step(step 2) — add a built-in branch: discover version vialist, populate viaadd(Galaxy source), summarize via bare id +--tool-version; never hand-guess a stock version.draft-validate --concreteto resolve built-ins against the default cache so a guessed version can't validate green.Env:
@galaxy-tool-util/cli+@galaxy-tool-util/core1.7.2 (vendored in node_modules), Node 25.6.1.