Skip to content

fix(manifest): resolve composed repository origins through their own Manifest's repositories - #365

Merged
aroff merged 1 commit into
mainfrom
fix/composed-manifest-repositories
Sep 23, 2026
Merged

aroff merged 1 commit into
mainfrom
fix/composed-manifest-repositories

Conversation

@aroff

@aroff aroff commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Problem

A composed Manifest ([tool.fastskill.manifests]) contributed its dependencies but not its [[tool.fastskill.repositories]]. A shared dependency such as { origin = { type = "repository", repo = "team", … } } then either:

  • failed with Repository 'team' is not configured when the consuming project did not declare team, or
  • silently resolved against the consuming project's team catalog when it happened to declare one with the same name but a different definition (the wrong-catalog case).

Change

  • SkillProjectToml::composed_repositories(project_dir) walks the same composition graph as dependencies and returns the project's own repositories plus every composed Manifest's, with a composed local path anchored to the Manifest that declares it.
  • One repository name with different definitions is refused: Repository 'team' is defined differently by <a> and <b>; give one of them another name. Identical definitions merge.
  • Resolution paths use the merged list: CLI skill add/install origin resolution (load_resolution_repositories), the edge-service injection, serve's manifest handler and all /registry/* browse routes.
  • fastskill repo add/update/remove/list still read and write only the project's own repositories (load_repositories_from_project), so a composed catalog is never copied into the project's toml.
  • Composed Manifests' skills_directory, [tool.fastskill.eval] and [tool.fastskill.server] stay ignored on purpose; documented in webdocs/skill-management/manifest-system.mdx.

Tests

  • manifest_composition_cli_test.rs: the wrong-catalog / not-configured case and the conflicting-name case (both fail on main), identical definitions merging, and repo add never copying composed repositories.
  • New http_registry_sources_tests.rs: the /registry/* routes had never run against real repositories. They now run over a wiremock zip-url marketplace, unreadable Git and zip-url marketplaces, a local catalog, an HTTP registry, composed repositories and a conflicting composition.
  • http_handler_route_tests.rs: serve_index_file error paths (missing index root, a path through a file, a directory, a symlink out of the index).
  • Small simplifications in registry.rs so the whole-file coverage gate passes: one project_sources_manager helper replaces four copies of the same error mapping, and the index file response is built with IntoResponse instead of a fallible builder.

./scripts/run-tests.sh passes locally (fmt, file-size cap, clippy, build, nextest, modified-file coverage).

🤖 Generated with Claude Code

@aroff
aroff enabled auto-merge (squash) September 23, 2026 18:53
Comment thread crates/fastskill-core/src/http/handlers/registry.rs Dismissed
…Manifest's repositories

A composed Manifest could declare a `repository` origin, but only the
consuming project's `[tool.fastskill.repositories]` were ever loaded. The
origin then failed with "Repository 'team' is not configured". Worse, if the
consumer happened to define a repository with the same name, it silently
installed the skill from the consumer's catalog instead of the one the
shared Manifest meant.

`SkillProjectToml::composed_repositories` now walks the same composition as
`to_skill_entries`, through one shared visitor. It collects every Manifest's
repositories, and anchors a composed Manifest's relative local path to that
Manifest. One name with identical definitions is merged. One name with
different definitions is an error that names both Manifests, never a silent
pick.

Install, update, add and serve resolve through the composed set. The `repo`
commands keep loading only the project's own repositories, because
`repo add/update/remove` save the whole list back and must not copy a
composed Manifest's repositories into the project.

A composed Manifest's skills_directory, eval and server settings stay
ignored on purpose; the Manifest docs now say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aroff
aroff force-pushed the fix/composed-manifest-repositories branch from 56753ed to 3e2c5d0 Compare September 23, 2026 19:14
@aroff
aroff merged commit ba62b53 into main Sep 23, 2026
14 checks passed
@aroff
aroff deleted the fix/composed-manifest-repositories branch September 23, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants