Skip to content

fix(skills): treat bare github.com/<owner>/<repo> URLs as GitHubRepo#276

Merged
Hmbown merged 1 commit into
feat/v0.8.4from
fix/issue-269-skill-install-github-repo-url
May 2, 2026
Merged

fix(skills): treat bare github.com/<owner>/<repo> URLs as GitHubRepo#276
Hmbown merged 1 commit into
feat/v0.8.4from
fix/issue-269-skill-install-github-repo-url

Conversation

@Hmbown

@Hmbown Hmbown commented May 2, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #269 (`安装不了 superpowers` / "invalid gzip header" reported by @bigfoot88).

`/skill install https://github.com/obra/superpowers\` failed with `invalid gzip header` because `InstallSource::parse` routed any `https://`-prefixed spec to `DirectUrl`. The installer downloaded the HTML repo page (200 OK, `text/html`) and `GzDecoder` choked.

URL Before After (this PR)
`github:obra/superpowers` `GitHubRepo` `GitHubRepo` (unchanged)
`https://github.com/obra/superpowers\` `DirectUrl` (HTML) `GitHubRepo`
`https://github.com/obra/superpowers/\` `DirectUrl` `GitHubRepo`
`https://github.com/obra/superpowers.git\` `DirectUrl` `GitHubRepo`
`https://www.github.com/obra/superpowers\` `DirectUrl` `GitHubRepo`
`http://github.com/obra/superpowers\` `DirectUrl` `GitHubRepo`
`https://github.com/obra/superpowers/archive/refs/heads/main.tar.gz\` `DirectUrl` `DirectUrl` (unchanged)
`https://github.com/obra/superpowers/blob/main/README.md\` `DirectUrl` `DirectUrl` (unchanged)
`https://example.com/skill.tar.gz\` `DirectUrl` `DirectUrl` (unchanged)

The platform was a red herring: the user reported Win11 + PowerShell + 0.8.1 but the parse path is platform-independent. The macOS happy path was confirmed working pre-fix on `https://github.com/obra/superpowers/archive/refs/heads/main.tar.gz\` and post-fix on `https://github.com/obra/superpowers\`.

Test plan

  • `cargo test -p deepseek-tui --bin deepseek-tui --locked install` (25/25, includes 2 new regressions)
  • `cargo fmt --all -- --check`
  • `cargo clippy -p deepseek-tui --all-targets --locked -- -D warnings`
  • Maintainer to confirm `/skill install https://github.com/obra/superpowers\` succeeds on a release build before closing 安装不了 superpowers #269.

🤖 Generated with Claude Code


Open in Devin Review

Copilot AI review requested due to automatic review settings May 2, 2026 00:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes /skill install https://github.com/<owner>/<repo> being mis-parsed as a direct URL (downloading the HTML repo page, then failing with invalid gzip header) by recognizing bare GitHub repo URLs and routing them to the GitHubRepo install source.

Changes:

  • Route bare github.com/<owner>/<repo>[.git] URLs (with optional www., optional trailing slash) to InstallSource::GitHubRepo.
  • Add regression tests covering the new GitHub URL parsing behavior and ensuring archive/blob/tree URLs remain DirectUrl.
  • Document the fix in the Unreleased changelog.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
crates/tui/src/skills/install.rs Adds GitHub browser URL detection in InstallSource::parse plus regression tests.
CHANGELOG.md Notes the install fix for issue #269 under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +125 to +147
fn parse_github_browser_url(url: &str) -> Option<String> {
let after_scheme = url
.strip_prefix("https://")
.or_else(|| url.strip_prefix("http://"))?;
let (host, rest) = after_scheme.split_once('/')?;
if !host.eq_ignore_ascii_case("github.com") && !host.eq_ignore_ascii_case("www.github.com") {
return None;
}
let trimmed = rest.trim_end_matches('/');
let mut parts = trimmed.splitn(3, '/');
let owner = parts.next()?.trim();
let repo = parts.next()?.trim().trim_end_matches(".git");
if owner.is_empty() || repo.is_empty() {
return None;
}
// If there is a third segment, the URL points at a sub-resource
// (`/archive/...`, `/blob/...`, `/tree/...`). Treat that as a real direct
// URL — the user explicitly wants whatever lives at that path.
if parts.next().is_some() {
return None;
}
Some(format!("{owner}/{repo}"))
}
///
/// * `github:owner/repo` → [`InstallSource::GitHubRepo`]
/// * `http://` or `https://` prefix → [`InstallSource::DirectUrl`]
/// * `https://github.com/owner/repo[.git]` (no path past the repo) →

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses issue #269 by improving the parsing of GitHub URLs during skill installation. Previously, bare repository URLs were treated as direct URLs, causing the installer to download HTML pages and fail with gzip errors. The changes introduce logic to detect these bare URLs and route them to the GitHubRepo source, while preserving direct URL behavior for specific paths like archives or blobs. Unit tests were added to ensure correct routing for various URL formats. I have no feedback to provide.

Closes #269.

`/skill install https://github.com/obra/superpowers` failed on every
platform with `invalid gzip header`. Root cause: `InstallSource::parse`
matched any `https://`-prefixed spec as `DirectUrl`, so the installer
downloaded the HTML repo page (200 OK, `text/html`) and tried to
gzip-decode HTML. The user reported it from Win11 + PowerShell but the
parse path is platform-independent.

Recognize bare GitHub repo URLs in `InstallSource::parse`:

- `https://github.com/<owner>/<repo>`
- `https://github.com/<owner>/<repo>/`
- `https://github.com/<owner>/<repo>.git`
- `https://github.com/<owner>/<repo>.git/`
- `https://www.github.com/<owner>/<repo>`
- `http://github.com/<owner>/<repo>` (legacy)

…all route to the existing `GitHubRepo` source, which already produces
`https://github.com/<repo>/archive/refs/heads/{main,master}.tar.gz`
candidates with proper fallback. URLs with a third path segment
(`/archive/...`, `/blob/...`, `/tree/...`) keep going through
`DirectUrl` because the user picked that exact path.

Adds two regression tests: one asserting the seven recognised forms
all canonicalize to `github:obra/superpowers`, and one pinning the
sub-resource paths to `DirectUrl`.
@Hmbown Hmbown force-pushed the fix/issue-269-skill-install-github-repo-url branch from fa63a1c to 0ca1238 Compare May 2, 2026 01:29
@Hmbown Hmbown merged commit 3374a17 into feat/v0.8.4 May 2, 2026
2 checks passed
@Hmbown Hmbown deleted the fix/issue-269-skill-install-github-repo-url branch May 2, 2026 01:30
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.

2 participants