Resolve the correct repository for a task — detect VCS platform, match ticket to repo, clone if missing. Run this in a sub-agent to avoid filling main context.
60
—
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
You are resolving which repository a task should be worked on. This skill handles VCS platform detection, scoped repo discovery, and cloning when needed.
IMPORTANT: This skill is designed to run inside a sub-agent (via the Agent tool) to keep the main session context clean. Return a concise result — do NOT explore repo contents or read large files.
This skill must stay lightweight:
package.json name/description fields, and git remote URLs as local signalsYou will receive these as context when invoked:
WORKSPACE_DIR — the parent directory containing multiple repos (e.g., ~/dev/aircall)TICKET_TITLE — the Jira/Linear/GitHub issue titleTICKET_DESCRIPTION — the issue description or acceptance criteria (keep only first ~200 chars for matching)TICKET_LABELS — labels/components from the ticket (if any)TICKET_ID — the ticket ID (e.g., MES-3716)Source the determinism-fix lib once before your bash work:
for f in ~/.claude/lib/determinism/functions/*.sh; do . "$f"; doneThese functions are sound, not complete (see ~/.claude/lib/determinism/CONTRACT.md):
they return a value (exit 0) only for unambiguous input and abstain (exit 10) /
error (exit 1) otherwise. Use them deterministic-first; fall back to model judgment
ONLY on a non-zero exit — never as a second opinion on a confident answer:
val=$(detect_vcs_platform "$REMOTE") || val="" # empty ⇒ lib abstained ⇒ you infer itUsed in this skill: detect_vcs_platform, extract_repo_group, extract_ticket_id.
Do NOT determinize the repo SCORING / ranking (Steps 2 & 4) — that is judgment and a
deterministic version is confidently worse; keep it model-driven and only pin its OUTPUT
format (Steps 4 & 6).
Scan WORKSPACE_DIR for git repos — collect only lightweight metadata:
for dir in "$WORKSPACE_DIR"/*/; do
if [ -d "$dir/.git" ] || git -C "$dir" rev-parse --git-dir &>/dev/null; then
NAME=$(basename "$dir")
REMOTE=$(git -C "$dir" remote get-url origin 2>/dev/null)
PKG_NAME=$(jq -r '.name // empty' "$dir/package.json" 2>/dev/null)
PKG_DESC=$(jq -r '.description // empty' "$dir/package.json" 2>/dev/null)
echo "$NAME|$PKG_NAME|$PKG_DESC|$REMOTE"
fi
doneFrom each remote URL, extract platform + group with the lib (D1, D2 — deterministic, abstain→AI). Do NOT classify the host or "judge the group" in prose:
PLATFORM=$(detect_vcs_platform "$REMOTE") || PLATFORM="" # github|gitlab|bitbucket|azure ; "" ⇒ abstained (unknown/self-hosted)
GROUP=$(extract_repo_group "$REMOTE") || GROUP="" # e.g. aircall/messaging ; "" ⇒ abstained (no group segment)PLATFORM is empty (lib abstained on an unknown/self-hosted host), THEN infer it
yourself from the URL — that is the only case AI runs.GROUPs across local repos (deterministic — compute it, don't judge "most specific").
If repos share aircall/messaging, scope to that, not aircall. If the common prefix
is empty or the repos diverge at the org root, fall back to asking the user.If no local repos exist, ask the user for the platform and group.
Always try local repos before going remote. Score each local repo against the ticket:
ID=$(extract_ticket_id "$TICKET_ID") || ID="$TICKET_ID"; PREFIX="${ID%%-*}" — then
case-insensitive substring-match PREFIX against repo names. No hand-coded synonym list.package.json description.
Drop stop words with a FIXED list (D5), not by judgment:
the|a|an|for|in|on|of|to|and|or|with|is|are|fix|add|update|support.Scoring stays model-driven (judgment — do NOT determinize: a fixed weight table is
confidently worse here). Weigh the signals and assign each repo a band, but emit ONLY the
pinned labels HIGH / MEDIUM / LOW — never qualifiers ("probably", "likely",
"confident"). A HIGH local match (clear winner) skips the remote lookup in step 3 — but it
does NOT skip the Repo Match Results block: you ALWAYS emit that block (step 4) before
resolving, listing the local candidates only. An ambiguous / no-confident match → step 3.
Only reach this step if no local repo matched confidently.
Fetch repos only from the same group/subgroup as the local repos — never the whole company org:
# Scoped to the specific group — NOT the top-level org
glab api "groups/<url-encoded-group>/projects?per_page=50&simple=true&order_by=name" 2>/dev/null \
| jq -r '.[] | "\(.path)|\(.description // "")"'# Scoped to the org derived from local repos
gh repo list "<org>" --limit 50 --json name,description --jq '.[] | "\(.name)|\(.description // "")"'Key constraints:
This block is always emitted, before the Resolved Repository block — including when step 2 found a clear HIGH local winner and step 3 was skipped (in that case list only the local candidates). Merge local and remote lists; for repos that exist both locally and remotely, prefer the local entry.
Score using the same signals from step 2. Order deterministically (D7): sort by band (HIGH → MEDIUM → LOW), then alphabetically by repo name within a band. Emit EXACTLY this block (D6). These rules are mandatory — the output is machine-checked:
N. **<name>** — <BAND>: <reasons> [<TAG>].<BAND> is one of HIGH / MEDIUM / LOW, written bare and immediately followed by a colon — HIGH: not **HIGH**:, never a synonym or qualifier.[LOCAL] or [REMOTE]. Never omit it.### Local / ### Remote sub-headers.## Repo Match Results
### Local (no cloning needed)
1. **messaging** — HIGH: prefix "MES", keyword "messaging" [LOCAL]
2. **internal-api** — LOW: keyword "api" [LOCAL]
### Remote (would need cloning)
3. **messaging-webhooks** — MEDIUM: keyword "messaging", "webhook" [REMOTE]If top match is LOCAL → return it directly.
If top match is REMOTE → confirm with the user before cloning:
<WORKSPACE_DIR>/<repo-name>?"git clone <remote-url> (construct URL from platform + group + repo name)cd "$WORKSPACE_DIR/<repo>"
[ -f "package.json" ] && echo "Run: npm install / yarn"
[ -f "Makefile" ] && echo "Run: make install"
[ -f ".env.example" ] && echo "Copy .env.example → .env"If ambiguous → return top 3 candidates and let the caller ask the user.
If no match → ask the user which repo, or if they need a different group/subgroup.
Emit EXACTLY this block (D9) — these fields, in this order; output ONLY the block, no
leading/trailing prose, no markdown fences. VCS Platform ∈ {github, gitlab, bitbucket,
azure, unknown}; Cloned ∈ {yes (just now), no (already existed)}:
## Resolved Repository
**Repo:** <repo-name>
**Path:** <full-path>
**VCS Platform:** <github | gitlab | bitbucket | azure | unknown>
**VCS Group:** <group/subgroup used for scoping>
**Remote:** <remote-url>
**Cloned:** <yes (just now) | no (already existed)>
**Setup needed:** <list if just cloned, or "none">glab/gh is not installed, provide install instructions and a manual clone URL.$ARGUMENTS
9556c94
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.