feat(projects): inherit the host's managed-projects registry (v0.4.0) - #25
Merged
Conversation
protoAgent 0.115.0 added a top-level `projects:` registry (ADR 0095) — one place to declare a project, with consumers projecting from it instead of re-declaring it. This is the GitHub half: a registered project's `github` field now feeds the repo picker and /issue, so declaring a project once is enough instead of also re-typing owner/name into `github.repos`. Two properties, both deliberate: Explicit config WINS. `github.repos` set => the registry is never consulted. Same non-regression property the core work has — configuring nothing new keeps today's behavior byte for byte. The version floor stays 0.27.0. The projection is additive, and bumping to 0.115.0 would cut off older hosts that don't want it anyway. So the host read is lazy and broadly guarded: no host (this suite), a pre-0.115.0 host (no `projects` attribute), or config not yet loaded all yield [] rather than raising. Same posture as register()'s existing hasattr(registry, "live_config") fallback. effective_default_repo stays PURE — the registry arrives as its `repos` argument rather than being read inside it — so /issue, the tools and the picker keep agreeing on one answer with no test churn. 8 host-free tests cover all three degrade paths plus dedupe/order, explicit-wins, and the blank-only list (`repos: ["", " "]` is an empty list, not a configured one). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Member
Author
Verified live against a real 0.115.0 hostBooted a fully isolated instance (own projects:
- {name: protoAgent, path: /Users/kj/dev/protoAgent, github: protoLabsAI/protoAgent, default_branch: main}
- {name: githubPlugin, path: /Users/kj/dev/github-plugin, github: protoLabsAI/github-plugin, default_branch: master}
- {name: notesOnly, path: /Users/kj/dev/projectBoard-plugin, fs: false} # no `github:` field
github:
repos: [] # EMPTY — must inherit from the registry
{
"repos": ["protoLabsAI/protoAgent", "protoLabsAI/github-plugin"],
"default_repo": "protoLabsAI/protoAgent",
"gh_available": true
}Three things confirmed at once:
Plugin registration was clean: Not observed live: nothing. This is the whole feature surface. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
protoAgent 0.115.0 added a top-level
projects:registry (ADR 0095) — one place to declare a project, with consumers projecting from it instead of re-declaring it. This is the GitHub half.What changes
A registered project's
githubfield now feeds the repo picker and/issue:…and
github.reposcan stay empty. Declare a project once instead of also re-typingowner/namehere.Two deliberate properties
Explicit config wins.
github.reposset ⇒ the registry is never consulted. Same non-regression property the core work has: configuring nothing new keeps today's behavior byte for byte.The version floor stays 0.27.0. The projection is purely additive, and bumping to 0.115.0 would cut off older hosts that don't want it anyway. So the host read is lazy and broadly guarded — no host, a pre-0.115.0 host (no
projectsattribute), or config not yet loaded all yield[]rather than raising. Same posture asregister()'s existinghasattr(registry, "live_config")fallback.Design note
effective_default_repostays a pure function — the registry arrives as itsreposargument rather than being read inside it. That keeps/issue, the tools, and the picker agreeing on one answer, and meant zero churn in the existing tests. The host read lives in exactly one guarded place (projects.py), whichapi.py::_reposandregister()both route through.Tests
8 new host-free tests in
tests/test_projects.py, covering all three degrade paths (no host / host without the registry / host whoseconfig()raises), dedupe-and-order, explicit-wins, and the blank-only list —repos: ["", " "]is an empty list, not a configured one, so it falls through.Gates:
pytest -q121 passed ·ruff checkclean.Not yet verified against a live 0.115.0 instance — that's the next step before I'd call this done.
🤖 Generated with Claude Code