Add git reference support for skill install#4046
Closed
JAORMX wants to merge 4 commits intorefactor/move-git-packagefrom
Closed
Add git reference support for skill install#4046JAORMX wants to merge 4 commits intorefactor/move-git-packagefrom
JAORMX wants to merge 4 commits intorefactor/move-git-packagefrom
Conversation
13536fb to
efa601e
Compare
Users can now install skills directly from git repositories using: thv skill install git://github.com/org/repo#path/to/skill This eliminates the "pending forever" problem where plain skill names created dead-end records. Unresolved plain names now return an actionable 404 error suggesting valid installation methods. New package pkg/skills/gitresolver/ provides: - Reference parsing with SSRF prevention (private IP/localhost rejection) - Path traversal validation (reject .., absolute paths, backslashes) - Host-scoped auth (GITHUB_TOKEN only sent to github.com, etc.) - Clone timeout (2 minutes) to prevent slowloris attacks - Supply chain defense (SKILL.md name must match git reference) - File writer with symlink checks and permission sanitization (0644 cap) Security reviewed: credential exfiltration prevented by scoping tokens to their respective hosts. DNS rebinding mitigation deferred as follow-up (requires custom DialContext). Relates to #4015 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add filepath.Clean at function entry so CodeQL can trace the sanitized path through all downstream os calls. Add #nosec annotations for gosec consistency with the existing installer.go patterns. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The targetDir parameter in WriteFiles is produced by PathResolver.GetSkillPath which builds paths from known base directories — not directly from user input. Add codeql[go/path-injection] inline suppression comments to document this. This is the same false-positive pattern as the existing alerts in pkg/skills/installer.go and pkg/skills/skillsvc/skillsvc.go on main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The git reference support PR replaced dead-end "pending" records with an actionable 404 for unresolvable plain skill names. The E2E tests were still installing plain names without building first. Each affected test now calls buildTestSkill() before installSkill() to place the artifact in the local OCI store, matching the real build-then-install workflow. A new test explicitly covers the 404 path for unresolvable names. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6202e00 to
bd0f454
Compare
Contributor
There was a problem hiding this comment.
Large PR Detected
This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.
How to unblock this PR:
Add a section to your PR description with the following format:
## Large PR Justification
[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformationAlternative:
Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.
See our Contributing Guidelines for more details.
This review will be automatically dismissed once you add the justification section.
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.
Summary
thv skill install my-skill) created "pending" records that never resolved — a dead-end UX problem. This replaces the pending path with an actionable 404 error.thv skill install git://github.com/org/repo#path/to/skillpkg/skills/gitresolver/package handles URL parsing, clone resolution, host-scoped auth, and secure file writing.Relates to #4015
Type of change
Test plan
task test)task test-e2e)task lint-fix)Changes
pkg/skills/gitresolver/reference.gogit://URL parsing with SSRF prevention (private IP/localhost rejection, absolute path/backslash rejection)pkg/skills/gitresolver/resolver.goResolverinterface: clones repo, extracts skill files, enforces 2-min clone timeoutpkg/skills/gitresolver/auth.goGITHUB_TOKENonly sent to github.com, etc.)pkg/skills/gitresolver/writer.gopkg/skills/skillsvc/git_install.goinstallFromGit,resolveGitReference,upsertGitSkillmethods with supply chain defensepkg/skills/skillsvc/skillsvc.goInstall(), dead-endinstallPendingreplaced with actionable 404pkg/skills/skillsvc/skillsvc_test.gopkg/api/server.goWithGitResolverin service constructioncmd/thv/app/skill_install.goLongdescription with git reference examplestest/e2e/api_skills_test.goDoes this introduce a user-facing change?
Yes.
thv skill installnow accepts git references:Plain skill names that can't be resolved locally now return an actionable error instead of creating a dead-end "pending" record.
Special notes for reviewers
Security review completed
GITHUB_TOKENonly sent togithub.com,GITLAB_TOKENonly togitlab.com.GIT_TOKENis opt-in fallback.context.WithTimeoutprevents slowloris-style hangs.validateSkillPathrejects absolute paths and backslashes in addition to..traversal.SKILL.mdmust match the name implied by the git reference.LimitedFscaps clones at 10k files / 100MB.Known limitations for follow-up
http.TransportwithDialContexthook)collectFilesreads only top-level files in the skill directory (flat structure)Resolvermock generated yet —installFromGitunit tests should be added with a mockThis is PR 2 of 2 — split from #4042. Depends on the git package move in the base branch.
Generated with Claude Code