Skip to content

Commit cf7015a

Browse files
authored
feat(agent-skill): track installed version in .version file (#303)
Resolve the commit SHA from the GitHub API during skill installation and write a .version file (branch + commit) to each install directory. This enables checking which version is installed and detecting updates.
1 parent e5ec5f1 commit cf7015a

2 files changed

Lines changed: 68 additions & 1 deletion

File tree

pkg/cmd/agentskill/agentskill.go

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package agentskill
33

44
import (
55
"bufio"
6+
"encoding/json"
67
"fmt"
78
"io"
89
"net/http"
@@ -22,6 +23,9 @@ const (
2223
// GitHub raw content base URL template
2324
baseURLTemplate = "https://raw.githubusercontent.com/brevdev/brev-cli/%s/.agents/skills/brev-cli"
2425

26+
// GitHub API URL template for resolving branch to commit SHA
27+
githubAPICommitTemplate = "https://api.github.com/repos/brevdev/brev-cli/commits/%s"
28+
2529
// Default branch
2630
defaultBranch = "main"
2731

@@ -30,16 +34,61 @@ const (
3034

3135
// Skill name
3236
skillName = "brev-cli"
37+
38+
// Version file name
39+
versionFileName = ".version"
3340
)
3441

3542
// getBaseURL returns the base URL for downloading skill files
3643
// Uses BREV_SKILL_BRANCH env var if set, otherwise defaults to main
3744
func getBaseURL() string {
45+
return fmt.Sprintf(baseURLTemplate, getBranch())
46+
}
47+
48+
// getBranch returns the branch used for downloading skill files
49+
func getBranch() string {
3850
branch := os.Getenv(branchEnvVar)
3951
if branch == "" {
4052
branch = defaultBranch
4153
}
42-
return fmt.Sprintf(baseURLTemplate, branch)
54+
return branch
55+
}
56+
57+
// resolveCommitSHA uses the GitHub API to resolve a branch/ref to a commit SHA
58+
func resolveCommitSHA(client *http.Client, ref string) (string, error) {
59+
url := fmt.Sprintf(githubAPICommitTemplate, ref)
60+
req, err := http.NewRequest("GET", url, nil) //nolint:noctx // simple API call
61+
if err != nil {
62+
return "", breverrors.WrapAndTrace(err)
63+
}
64+
req.Header.Set("Accept", "application/vnd.github.v3+json")
65+
66+
resp, err := client.Do(req) //nolint:bodyclose // closed below
67+
if err != nil {
68+
return "", breverrors.WrapAndTrace(err)
69+
}
70+
defer resp.Body.Close()
71+
72+
if resp.StatusCode != http.StatusOK {
73+
return "", breverrors.NewValidationError(fmt.Sprintf("failed to resolve commit for %s: %s", ref, resp.Status))
74+
}
75+
76+
var result struct {
77+
SHA string `json:"sha"`
78+
}
79+
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
80+
return "", breverrors.WrapAndTrace(err)
81+
}
82+
83+
return result.SHA, nil
84+
}
85+
86+
// writeVersionFile writes a .version file to all skill directories
87+
func writeVersionFile(skillDirs []string, branch, commitSHA string) {
88+
content := fmt.Sprintf("branch=%s\ncommit=%s\n", branch, commitSHA)
89+
for _, dir := range skillDirs {
90+
_ = os.WriteFile(filepath.Join(dir, versionFileName), []byte(content), 0o644) //nolint:gosec // not sensitive
91+
}
4392
}
4493

4594
// Files to download (relative to skill directory)
@@ -224,6 +273,15 @@ func InstallSkill(t *terminal.Terminal, homeDir string, quiet bool) error {
224273
}
225274
}
226275

276+
// Resolve commit SHA and write .version file
277+
branch := getBranch()
278+
if commitSHA, err := resolveCommitSHA(client, branch); err == nil {
279+
writeVersionFile(skillDirs, branch, commitSHA)
280+
if !quiet {
281+
fmt.Printf(" %s .version (%s)\n", t.Green("✓"), commitSHA[:12])
282+
}
283+
}
284+
227285
fmt.Println()
228286

229287
if failed > 0 {

scripts/install-agent-skill.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,15 @@ for file in "${FILES[@]}"; do
115115
done
116116
rm -rf "$TMPDIR"
117117

118+
# Resolve commit SHA and write .version file
119+
COMMIT_SHA=$(curl -fsSL "https://api.github.com/repos/$REPO/commits/$BRANCH" 2>/dev/null | grep '"sha"' | head -1 | sed 's/.*"sha": *"\([^"]*\)".*/\1/')
120+
if [[ -n "$COMMIT_SHA" ]]; then
121+
for dir in "${INSTALL_DIRS[@]}"; do
122+
printf 'branch=%s\ncommit=%s\n' "$BRANCH" "$COMMIT_SHA" > "$dir/.version"
123+
done
124+
echo -e " ${GREEN}${NC} .version (${COMMIT_SHA:0:12})"
125+
fi
126+
118127
echo ""
119128

120129
if [[ $FAILED -gt 0 ]]; then

0 commit comments

Comments
 (0)