Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package arkade for openSUSE:Factory checked 
in at 2026-01-30 18:23:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/arkade (Old)
 and      /work/SRC/openSUSE:Factory/.arkade.new.1995 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "arkade"

Fri Jan 30 18:23:38 2026 rev:71 rq:1329943 version:0.11.69

Changes:
--------
--- /work/SRC/openSUSE:Factory/arkade/arkade.changes    2026-01-28 
15:09:44.572472558 +0100
+++ /work/SRC/openSUSE:Factory/.arkade.new.1995/arkade.changes  2026-01-30 
18:23:47.805332879 +0100
@@ -1,0 +2,9 @@
+Fri Jan 30 06:35:03 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 0.11.69 (.68 was not released):
+  * Reformat text
+  * Update sponsors message
+  * Retry failed downloads, improve messages
+  * Add copilot and charm
+
+-------------------------------------------------------------------

Old:
----
  arkade-0.11.67.obscpio

New:
----
  arkade-0.11.69.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ arkade.spec ++++++
--- /var/tmp/diff_new_pack.QV4VdC/_old  2026-01-30 18:23:50.249436151 +0100
+++ /var/tmp/diff_new_pack.QV4VdC/_new  2026-01-30 18:23:50.261436658 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           arkade
-Version:        0.11.67
+Version:        0.11.69
 Release:        0
 Summary:        Open Source Kubernetes Marketplace
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.QV4VdC/_old  2026-01-30 18:23:50.557449166 +0100
+++ /var/tmp/diff_new_pack.QV4VdC/_new  2026-01-30 18:23:50.585450348 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/alexellis/arkade</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">0.11.67</param>
+    <param name="revision">0.11.69</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.QV4VdC/_old  2026-01-30 18:23:50.725456264 +0100
+++ /var/tmp/diff_new_pack.QV4VdC/_new  2026-01-30 18:23:50.757457617 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/alexellis/arkade</param>
-              <param 
name="changesrevision">3db8251b4c65a3903e6e80b9a053bdef59e87d8d</param></service></servicedata>
+              <param 
name="changesrevision">d41670cce4347218c930be4d11988a3697e82737</param></service></servicedata>
 (No newline at EOF)
 

++++++ arkade-0.11.67.obscpio -> arkade-0.11.69.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/arkade-0.11.67/README.md new/arkade-0.11.69/README.md
--- old/arkade-0.11.67/README.md        2026-01-27 11:29:09.000000000 +0100
+++ new/arkade-0.11.69/README.md        2026-01-28 23:40:13.000000000 +0100
@@ -761,7 +761,6 @@
 ### Catalog of CLIs
 
 <!-- start of tool list -->
-
 |                                     TOOL                                     
|                                                                            
DESCRIPTION                                                                     
       |
 
|------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | [actions-usage](https://github.com/self-actuated/actions-usage)              
| Get usage insights from GitHub Actions.                                       
                                                                                
    |
@@ -791,11 +790,13 @@
 | [conftest](https://github.com/open-policy-agent/conftest)                    
| Write tests against structured configuration data using the Open Policy Agent 
Rego query language                                                             
    |
 | [consul](https://github.com/hashicorp/consul)                                
| A solution to connect and configure applications across dynamic, distributed 
infrastructure                                                                  
     |
 | [copa](https://github.com/project-copacetic/copacetic)                       
| CLI for patching container images                                             
                                                                                
    |
+| [copilot](https://github.com/github/copilot-cli)                             
| GitHub Copilot CLI - AI-powered command line assistant                        
                                                                                
    |
 | [cosign](https://github.com/sigstore/cosign)                                 
| Container Signing, Verification and Storage in an OCI registry.               
                                                                                
    |
 | [cr](https://github.com/helm/chart-releaser)                                 
| Hosting Helm Charts via GitHub Pages and Releases                             
                                                                                
    |
 | [crane](https://github.com/google/go-containerregistry)                      
| crane is a tool for interacting with remote images and registries             
                                                                                
    |
 | [croc](https://github.com/schollz/croc)                                      
| Easily and securely send things from one computer to another                  
                                                                                
    |
 | [crossplane](https://github.com/crossplane/crossplane)                       
| Simplify some development and administration aspects of Crossplane.           
                                                                                
    |
+| [crush](https://github.com/charmbracelet/crush)                              
| A delightful AI assistant for your terminal                                   
                                                                                
    |
 | [dagger](https://github.com/dagger/dagger)                                   
| A portable devkit for CI/CD pipelines.                                        
                                                                                
    |
 | [devpod](https://github.com/loft-sh/devpod)                                  
| Codespaces but open-source, client-only and unopinionated: Works with any IDE 
and lets you use any cloud, kubernetes or just localhost docker.                
    |
 | [devspace](https://github.com/devspace-sh/devspace)                          
| Automate your deployment workflow with DevSpace and develop software directly 
inside Kubernetes.                                                              
    |
@@ -953,9 +954,7 @@
 | [websocat](https://github.com/vi/websocat)                                   
| Command-line client for WebSockets, like netcat/socat but for WebSockets      
                                                                                
    |
 | [yq](https://github.com/mikefarah/yq)                                        
| Portable command-line YAML processor.                                         
                                                                                
    |
 | [yt-dlp](https://github.com/yt-dlp/yt-dlp)                                   
| Fork of youtube-dl with additional features and fixes                         
                                                                                
    |
-There are 189 tools, use `arkade get NAME` to download one.
-
+There are 191 tools, use `arkade get NAME` to download one.                    
                                                                                
                                                                                
     
 
-<!-- end of tool list -->
 
 > Note to contributors, run `go run . get --format markdown` to generate this 
 > list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/arkade-0.11.67/pkg/get/download.go 
new/arkade-0.11.69/pkg/get/download.go
--- old/arkade-0.11.67/pkg/get/download.go      2026-01-27 11:29:09.000000000 
+0100
+++ new/arkade-0.11.69/pkg/get/download.go      2026-01-28 23:40:13.000000000 
+0100
@@ -15,6 +15,8 @@
        "text/template"
        "time"
 
+       units "github.com/docker/go-units"
+
        "github.com/alexellis/arkade/pkg"
        "github.com/alexellis/arkade/pkg/archive"
        "github.com/alexellis/arkade/pkg/config"
@@ -45,16 +47,23 @@
        }
 
        if !quiet {
-               fmt.Printf("Downloading: %s\n", downloadURL)
+               log.Printf("Downloading: %s", downloadURL)
        }
 
+       start := time.Now()
        outFilePath, err := downloadFile(downloadURL, displayProgress)
        if err != nil {
                return "", "", err
        }
 
        if !quiet {
-               fmt.Printf("%s written.\n", outFilePath)
+               filename := path.Base(downloadURL)
+               stat, err := os.Stat(outFilePath)
+               size := ""
+               if err == nil {
+                       size = "(" + units.HumanSize(float64(stat.Size())) + ")"
+               }
+               log.Printf("Downloaded %s %s in %s.", filename, size, 
time.Since(start).Round(time.Millisecond))
        }
 
        if verify {
@@ -210,7 +219,7 @@
                }
 
                outFilePath = outPath
-               if !quiet {
+               if v, ok := os.LookupEnv("ARK_DEBUG"); ok && v == "1" {
                        log.Printf("Extracted: %s", outFilePath)
                }
        }
@@ -233,7 +242,7 @@
                localPath = filepath.Join(movePath, finalName)
        }
 
-       if !quiet {
+       if v, ok := os.LookupEnv("ARK_DEBUG"); ok && v == "1" {
                log.Printf("Copying %s to %s\n", outFilePath, localPath)
        }
 
@@ -259,57 +268,58 @@
 }
 
 func downloadFile(downloadURL string, displayProgress bool) (string, error) {
+       return retryWithBackoff(func() (string, error) {
+               req, err := http.NewRequest(http.MethodGet, downloadURL, nil)
+               if err != nil {
+                       return "", err
+               }
 
-       req, err := http.NewRequest(http.MethodGet, downloadURL, nil)
-       if err != nil {
-               return "", err
-       }
-
-       req.Header.Set("User-Agent", pkg.UserAgent())
+               req.Header.Set("User-Agent", pkg.UserAgent())
 
-       res, err := http.DefaultClient.Do(req)
-       if err != nil {
-               return "", err
-       }
+               res, err := http.DefaultClient.Do(req)
+               if err != nil {
+                       return "", err
+               }
 
-       if res.Body != nil {
-               defer res.Body.Close()
-       }
+               if res.Body != nil {
+                       defer res.Body.Close()
+               }
 
-       if res.StatusCode == http.StatusNotFound {
-               return "", &ErrNotFound{}
-       }
+               if res.StatusCode == http.StatusNotFound {
+                       return "", &ErrNotFound{}
+               }
 
-       if res.StatusCode != http.StatusOK {
-               return "", fmt.Errorf("server returned status: %d", 
res.StatusCode)
-       }
+               if res.StatusCode != http.StatusOK {
+                       return "", fmt.Errorf("server returned status: %d", 
res.StatusCode)
+               }
 
-       _, fileName := path.Split(downloadURL)
-       tmp := os.TempDir()
+               _, fileName := path.Split(downloadURL)
+               tmp := os.TempDir()
 
-       customTmp, err := os.MkdirTemp(tmp, "arkade-*")
-       if err != nil {
-               return "", err
-       }
+               customTmp, err := os.MkdirTemp(tmp, "arkade-*")
+               if err != nil {
+                       return "", err
+               }
 
-       outFilePath := path.Join(customTmp, fileName)
-       wrappedReader := withProgressBar(res.Body, int(res.ContentLength), 
displayProgress)
+               outFilePath := path.Join(customTmp, fileName)
+               wrappedReader := withProgressBar(res.Body, 
int(res.ContentLength), displayProgress)
 
-       // Owner/Group read/write/execute
-       // World - execute
-       out, err := os.OpenFile(outFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 
0775)
-       if err != nil {
-               return "", err
-       }
+               // Owner/Group read/write/execute
+               // World - execute
+               out, err := os.OpenFile(outFilePath, 
os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
+               if err != nil {
+                       return "", err
+               }
 
-       defer out.Close()
-       defer wrappedReader.Close()
+               defer out.Close()
+               defer wrappedReader.Close()
 
-       if _, err := io.Copy(out, wrappedReader); err != nil {
-               return "", err
-       }
+               if _, err := io.Copy(out, wrappedReader); err != nil {
+                       return "", err
+               }
 
-       return outFilePath, nil
+               return outFilePath, nil
+       }, 10, 100*time.Millisecond)
 }
 
 func CopyFile(src, dst string) (int64, error) {
@@ -404,7 +414,7 @@
                }
 
                if !quiet {
-                       fmt.Printf("Name: %s, size: %d", fInfo.Name(), 
fInfo.Size())
+                       log.Printf("Name: %s, size: %d", fInfo.Name(), 
fInfo.Size())
                }
 
                if err := archive.Unzip(archiveFile, fInfo.Size(), 
outFilePathDir, forceQuiet); err != nil {
@@ -416,27 +426,29 @@
 }
 
 func fetchText(url string) (string, error) {
-       req, err := http.NewRequest(http.MethodGet, url, nil)
-       if err != nil {
-               return "", err
-       }
-       req.Header.Set("User-Agent", pkg.UserAgent())
-       res, err := http.DefaultClient.Do(req)
-       if err != nil {
-               return "", err
-       }
+       return retryWithBackoff(func() (string, error) {
+               req, err := http.NewRequest(http.MethodGet, url, nil)
+               if err != nil {
+                       return "", err
+               }
+               req.Header.Set("User-Agent", pkg.UserAgent())
+               res, err := http.DefaultClient.Do(req)
+               if err != nil {
+                       return "", err
+               }
 
-       var body []byte
-       if res.Body != nil {
-               defer res.Body.Close()
-               body, _ = io.ReadAll(res.Body)
-       }
+               var body []byte
+               if res.Body != nil {
+                       defer res.Body.Close()
+                       body, _ = io.ReadAll(res.Body)
+               }
 
-       if res.StatusCode != http.StatusOK {
-               return "", fmt.Errorf("unexpected status code %d, body: %s", 
res.StatusCode, string(body))
-       }
+               if res.StatusCode != http.StatusOK {
+                       return "", fmt.Errorf("unexpected status code %d, body: 
%s", res.StatusCode, string(body))
+               }
 
-       return string(body), nil
+               return string(body), nil
+       }, 10, 100*time.Millisecond)
 }
 
 func verifySHA(shaSum, outFilePath string) error {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/arkade-0.11.67/pkg/get/get.go 
new/arkade-0.11.69/pkg/get/get.go
--- old/arkade-0.11.67/pkg/get/get.go   2026-01-27 11:29:09.000000000 +0100
+++ new/arkade-0.11.69/pkg/get/get.go   2026-01-28 23:40:13.000000000 +0100
@@ -9,6 +9,7 @@
        "log"
        "net"
        "net/http"
+
        "strings"
        "text/template"
        "time"
@@ -30,6 +31,45 @@
 var supportedOS = [...]string{"linux", "darwin", "ming"}
 var supportedArchitectures = [...]string{"x86_64", "arm", "amd64", "armv6l", 
"armv7l", "arm64", "aarch64"}
 
+// retryWithBackoff implements exponential backoff with retry logic
+func retryWithBackoff(fn func() (string, error), maxRetries int, 
initialBackoff time.Duration) (string, error) {
+       var lastErr error
+       for attempt := 0; attempt <= maxRetries; attempt++ {
+               if attempt > 0 {
+                       backoff := initialBackoff * 
time.Duration(1<<uint(attempt-1))
+                       if backoff > 10*time.Second {
+                               backoff = 10 * time.Second
+                       }
+                       log.Printf("Attempt %d: Retrying after %v due to: %v", 
attempt, backoff, lastErr)
+                       time.Sleep(backoff)
+               }
+
+               result, err := fn()
+               if err == nil {
+                       return result, nil
+               }
+
+               lastErr = err
+
+               // Don't retry permanent errors
+               if isPermanentError(err) {
+                       return "", err
+               }
+       }
+       return "", fmt.Errorf("failed after %d attempts: %w", maxRetries+1, 
lastErr)
+}
+
+func isPermanentError(err error) bool {
+       // 404, 429 are permanent errors
+       if strings.Contains(err.Error(), "404") {
+               return true
+       }
+       if strings.Contains(err.Error(), "429") {
+               return true
+       }
+       return false
+}
+
 // Tool describes how to download a CLI tool from a binary
 // release - whether a single binary, or an archive.
 type Tool struct {
@@ -205,16 +245,32 @@
 
                if _, supported := releaseLocations[releaseType]; supported {
 
+                       start := time.Now()
                        v, err := FindRelease(releaseType, tool.Owner, 
tool.Repo)
                        if err != nil {
                                return "", "", err
                        }
                        version = v
+                       if !quiet {
+                               log.Printf("Found %s version: %s (in %s)", 
tool.Name, version, time.Since(start).Round(time.Millisecond))
+                       }
                }
 
-               if !quiet {
-                       log.Printf("Found: %s", version)
+               resolvedVersion = version
+
+               if len(tool.URLTemplate) > 0 {
+                       res, err := getByDownloadTemplate(tool, os, arch, 
version)
+                       if err != nil {
+                               return "", "", err
+                       }
+                       return res, resolvedVersion, nil
+               }
+
+               res, err := getURLByGithubTemplate(tool, os, arch, version)
+               if err != nil {
+                       return "", "", err
                }
+               return res, resolvedVersion, nil
        }
 
        resolvedVersion = version
@@ -276,46 +332,48 @@
                return http.ErrUseLastResponse
        }
 
-       req, err := http.NewRequest(releaseLocations[location].Method, url, nil)
-       if err != nil {
-               return "", err
-       }
+       return retryWithBackoff(func() (string, error) {
+               req, err := http.NewRequest(releaseLocations[location].Method, 
url, nil)
+               if err != nil {
+                       return "", err
+               }
 
-       req.Header.Set("User-Agent", pkg.UserAgent())
+               req.Header.Set("User-Agent", pkg.UserAgent())
 
-       res, err := client.Do(req)
-       if err != nil {
-               return "", err
-       }
+               res, err := client.Do(req)
+               if err != nil {
+                       return "", err
+               }
+
+               defer res.Body.Close()
+
+               if releaseLocations[location].Method == http.MethodHead {
 
-       defer res.Body.Close()
+                       if res.StatusCode != http.StatusMovedPermanently && 
res.StatusCode != http.StatusFound {
+                               return "", fmt.Errorf("server returned status: 
%d", res.StatusCode)
+                       }
 
-       if releaseLocations[location].Method == http.MethodHead {
+                       loc := res.Header.Get("Location")
+                       if len(loc) == 0 {
+                               return "", fmt.Errorf("unable to determine 
release of tool")
+                       }
 
-               if res.StatusCode != http.StatusMovedPermanently && 
res.StatusCode != http.StatusFound {
-                       return "", fmt.Errorf("server returned status: %d", 
res.StatusCode)
+                       version := loc[strings.LastIndex(loc, "/")+1:]
+                       return version, nil
                }
 
-               loc := res.Header.Get("Location")
-               if len(loc) == 0 {
+               if res.Body == nil {
                        return "", fmt.Errorf("unable to determine release of 
tool")
                }
 
-               version := loc[strings.LastIndex(loc, "/")+1:]
-               return version, nil
-       }
-
-       if res.Body == nil {
-               return "", fmt.Errorf("unable to determine release of tool")
-       }
-
-       bodyBytes, err := io.ReadAll(res.Body)
-       if err != nil {
-               return "", err
-       }
+               bodyBytes, err := io.ReadAll(res.Body)
+               if err != nil {
+                       return "", err
+               }
 
-       version := strings.TrimSpace(string(bodyBytes))
-       return version, nil
+               version := strings.TrimSpace(string(bodyBytes))
+               return version, nil
+       }, 10, 100*time.Millisecond)
 }
 
 func formatUrl(url, owner, repo string) string {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/arkade-0.11.67/pkg/get/get_test.go 
new/arkade-0.11.69/pkg/get/get_test.go
--- old/arkade-0.11.67/pkg/get/get_test.go      2026-01-27 11:29:09.000000000 
+0100
+++ new/arkade-0.11.69/pkg/get/get_test.go      2026-01-28 23:40:13.000000000 
+0100
@@ -9613,3 +9613,115 @@
                })
        }
 }
+
+func Test_DownloadCopilot(t *testing.T) {
+       tools := MakeTools()
+       name := "copilot"
+       const version = "v0.0.396"
+
+       tool := getTool(name, tools)
+
+       tests := []test{
+               {
+                       os:      "ming",
+                       arch:    arch64bit,
+                       version: version,
+                       url:     
`https://github.com/github/copilot-cli/releases/download/v0.0.396/copilot-win32-x64.zip`,
+               },
+               {
+                       os:      "ming",
+                       arch:    archARM64,
+                       version: version,
+                       url:     
`https://github.com/github/copilot-cli/releases/download/v0.0.396/copilot-win32-arm64.zip`,
+               },
+               {
+                       os:      "linux",
+                       arch:    arch64bit,
+                       version: version,
+                       url:     
`https://github.com/github/copilot-cli/releases/download/v0.0.396/copilot-linux-x64.tar.gz`,
+               },
+               {
+                       os:      "linux",
+                       arch:    archARM64,
+                       version: version,
+                       url:     
`https://github.com/github/copilot-cli/releases/download/v0.0.396/copilot-linux-arm64.tar.gz`,
+               },
+               {
+                       os:      "darwin",
+                       arch:    arch64bit,
+                       version: version,
+                       url:     
`https://github.com/github/copilot-cli/releases/download/v0.0.396/copilot-darwin-x64.tar.gz`,
+               },
+               {
+                       os:      "darwin",
+                       arch:    archDarwinARM64,
+                       version: version,
+                       url:     
`https://github.com/github/copilot-cli/releases/download/v0.0.396/copilot-darwin-arm64.tar.gz`,
+               },
+       }
+
+       for _, tc := range tests {
+               t.Run(fmt.Sprintf("Download for: %s %s %s", tc.os, tc.arch, 
tc.version), func(r *testing.T) {
+                       got, _, err := tool.GetURL(tc.os, tc.arch, tc.version, 
false)
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+                       if got != tc.url {
+                               t.Errorf("\nwant: %s\ngot:  %s", tc.url, got)
+                       }
+               })
+       }
+}
+
+func Test_DownloadCrush(t *testing.T) {
+       tools := MakeTools()
+       name := "crush"
+       const version = "v0.36.0"
+
+       tool := getTool(name, tools)
+
+       tests := []test{
+               {
+                       os:      "ming",
+                       arch:    arch64bit,
+                       version: version,
+                       url:     
`https://github.com/charmbracelet/crush/releases/download/v0.36.0/crush_0.36.0_Windows_x86_64.zip`,
+               },
+               {
+                       os:      "linux",
+                       arch:    arch64bit,
+                       version: version,
+                       url:     
`https://github.com/charmbracelet/crush/releases/download/v0.36.0/crush_0.36.0_Linux_x86_64.tar.gz`,
+               },
+               {
+                       os:      "linux",
+                       arch:    archARM64,
+                       version: version,
+                       url:     
`https://github.com/charmbracelet/crush/releases/download/v0.36.0/crush_0.36.0_Linux_arm64.tar.gz`,
+               },
+               {
+                       os:      "darwin",
+                       arch:    arch64bit,
+                       version: version,
+                       url:     
`https://github.com/charmbracelet/crush/releases/download/v0.36.0/crush_0.36.0_Darwin_x86_64.tar.gz`,
+               },
+               {
+                       os:      "darwin",
+                       arch:    archDarwinARM64,
+                       version: version,
+                       url:     
`https://github.com/charmbracelet/crush/releases/download/v0.36.0/crush_0.36.0_Darwin_arm64.tar.gz`,
+               },
+       }
+
+       for _, tc := range tests {
+               t.Run(fmt.Sprintf("Download for: %s %s %s", tc.os, tc.arch, 
tc.version), func(r *testing.T) {
+                       got, _, err := tool.GetURL(tc.os, tc.arch, tc.version, 
false)
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+                       if got != tc.url {
+                               t.Errorf("\nwant: %s\ngot:  %s", tc.url, got)
+                       }
+               })
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/arkade-0.11.67/pkg/get/tools.go 
new/arkade-0.11.69/pkg/get/tools.go
--- old/arkade-0.11.67/pkg/get/tools.go 2026-01-27 11:29:09.000000000 +0100
+++ new/arkade-0.11.69/pkg/get/tools.go 2026-01-28 23:40:13.000000000 +0100
@@ -5281,5 +5281,57 @@
 
https://github.com/vi/websocat/releases/download/{{.Version}}/websocat.{{$target}}`,
                })
 
+       tools = append(tools,
+               Tool{
+                       Owner:       "github",
+                       Repo:        "copilot-cli",
+                       Name:        "copilot",
+                       Description: "GitHub Copilot CLI - AI-powered command 
line assistant",
+                       BinaryTemplate: `
+{{$os := ""}}
+{{$arch := ""}}
+{{$ext := "tar.gz"}}
+{{- if eq .OS "darwin" -}}
+       {{$os = "darwin"}}
+{{- else if eq .OS "linux" -}}
+       {{$os = "linux"}}
+{{- else if HasPrefix .OS "ming" -}}
+       {{$os = "win32"}}
+       {{$ext = "zip"}}
+{{- end -}}
+{{- if or (eq .Arch "x86_64") (eq .Arch "amd64") -}}
+       {{$arch = "x64"}}
+{{- else if or (eq .Arch "aarch64") (eq .Arch "arm64") -}}
+       {{$arch = "arm64"}}
+{{- end -}}
+{{.Name}}-{{$os}}-{{$arch}}.{{$ext}}`,
+               })
+
+       tools = append(tools,
+               Tool{
+                       Owner:       "charmbracelet",
+                       Repo:        "crush",
+                       Name:        "crush",
+                       Description: "A delightful AI assistant for your 
terminal",
+                       URLTemplate: `
+{{$arch := .Arch}}
+{{- if eq .Arch "x86_64" -}}
+       {{$arch = "x86_64"}}
+{{- else if eq .Arch "aarch64" -}}
+       {{$arch = "arm64"}}
+{{- end -}}
+{{$osStr := ""}}
+{{$extStr := "tar.gz"}}
+{{- if eq .OS "darwin" -}}
+       {{$osStr = "Darwin"}}
+{{- else if eq .OS "linux" -}}
+       {{$osStr = "Linux"}}
+{{- else if HasPrefix .OS "ming" -}}
+       {{$osStr = "Windows"}}
+       {{$extStr = "zip"}}
+{{- end -}}
+https://github.com/{{.Owner}}/{{.Repo}}/releases/download/{{.Version}}/{{.Name}}_{{.VersionNumber}}_{{$osStr}}_{{$arch}}.{{$extStr}}`,
+               })
+
        return tools
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/arkade-0.11.67/pkg/thanks.go 
new/arkade-0.11.69/pkg/thanks.go
--- old/arkade-0.11.67/pkg/thanks.go    2026-01-27 11:29:09.000000000 +0100
+++ new/arkade-0.11.69/pkg/thanks.go    2026-01-28 23:40:13.000000000 +0100
@@ -4,4 +4,4 @@
 package pkg
 
 // SupportMessageShort shows how to support arkade
-const SupportMessageShort = `👏 Say thanks for arkade and sponsor Alex via 
GitHub: https://github.com/sponsors/alexellis`
+const SupportMessageShort = `🤝 Sponsor Alex's work: 
https://github.com/sponsors/alexellis`

++++++ arkade.obsinfo ++++++
--- /var/tmp/diff_new_pack.QV4VdC/_old  2026-01-30 18:23:53.085555986 +0100
+++ /var/tmp/diff_new_pack.QV4VdC/_new  2026-01-30 18:23:53.101556663 +0100
@@ -1,5 +1,5 @@
 name: arkade
-version: 0.11.67
-mtime: 1769509749
-commit: 3db8251b4c65a3903e6e80b9a053bdef59e87d8d
+version: 0.11.69
+mtime: 1769640013
+commit: d41670cce4347218c930be4d11988a3697e82737
 

++++++ vendor.tar.gz ++++++

Reply via email to