fix(skills): marketplace setup incorrectly reports error after successful clone - #242
Conversation
…-zero but .git is valid On Windows with Git Credential Manager, git can write authentication warnings to stderr and exit non-zero even though the clone was written to disk. After a non-zero exit, verify with `git rev-parse HEAD`; only surface the error if no valid repository exists at the destination. Closes #239 Co-authored-by: Sunny Kolattukudy <kolatts@users.noreply.github.com>
|
Claude finished @claude[bot]'s task in 2m 18s —— View job PR Review
Verdict: Approve (can't self-approve; tagging for human merge) The fix is correct. One nit (inline suggestion posted): the // current
let cloneActuallySucceeded = false;
try {
execFileSync('git', ['-C', resolvedPath, 'rev-parse', 'HEAD'], { stdio: 'pipe' });
cloneActuallySucceeded = true;
} catch { /* ... */ }
if (!cloneActuallySucceeded) { throw ... }
// simpler
try {
execFileSync('git', ['-C', resolvedPath, 'rev-parse', 'HEAD'], { stdio: 'pipe' });
} catch {
const msg = e instanceof Error ? e.message : String(e);
throw new Error(msg.replace(...));
}Test coverage: The command action handler isn't unit-tested, but that's a pre-existing gap for all No blocking issues. |
| let cloneActuallySucceeded = false; | ||
| try { | ||
| execFileSync('git', ['-C', resolvedPath, 'rev-parse', 'HEAD'], { stdio: 'pipe' }); | ||
| cloneActuallySucceeded = true; | ||
| } catch { /* repo not valid — fall through and re-throw original error */ } | ||
| if (!cloneActuallySucceeded) { | ||
| const msg = e instanceof Error ? e.message : String(e); | ||
| throw new Error(msg.replace(/x-(?:token-auth|access-token):[^@]+@/g, 'x-token-auth:***@')); | ||
| } |
There was a problem hiding this comment.
The boolean flag can be eliminated — re-throw inside the inner catch instead:
| let cloneActuallySucceeded = false; | |
| try { | |
| execFileSync('git', ['-C', resolvedPath, 'rev-parse', 'HEAD'], { stdio: 'pipe' }); | |
| cloneActuallySucceeded = true; | |
| } catch { /* repo not valid — fall through and re-throw original error */ } | |
| if (!cloneActuallySucceeded) { | |
| const msg = e instanceof Error ? e.message : String(e); | |
| throw new Error(msg.replace(/x-(?:token-auth|access-token):[^@]+@/g, 'x-token-auth:***@')); | |
| } | |
| try { | |
| execFileSync('git', ['-C', resolvedPath, 'rev-parse', 'HEAD'], { stdio: 'pipe' }); | |
| } catch { | |
| // rev-parse failed — repo is not valid, surface the original clone error | |
| const msg = e instanceof Error ? e.message : String(e); | |
| throw new Error(msg.replace(/x-(?:token-auth|access-token):[^@]+@/g, 'x-token-auth:***@')); | |
| } |
Same semantics, one less variable, easier to read at a glance.
Summary
git cloneexits non-zero, verify the destination withgit rev-parse HEADbefore surfacing the errorTest plan
npm run typecheck— passesnpm run lint— passesnpm test— 295 tests passpncli skills marketplace setupagainst a Bitbucket Server with GCM on Windows to confirm the false-negative is gone; run against an actually unauthenticated URL to confirm the real auth error is still surfacedCloses #239
Generated with Claude Code