upgrade

package
v1.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package upgrade provides self-update functionality for the DWS CLI using GitHub Releases as the data source.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BinaryName

func BinaryName() string

BinaryName returns the platform-specific binary name.

func CleanupStaleFiles

func CleanupStaleFiles()

CleanupStaleFiles removes leftover .old and .rollback-tmp files from previous upgrades (relevant on Windows where locked files cannot be deleted immediately).

func CompareVersions

func CompareVersions(a, b string) int

CompareVersions compares two semver strings (e.g. "1.0.5", "v1.0.6-beta"). Returns -1 if a < b, 0 if equal, 1 if a > b. Only the numeric major.minor.patch segments are compared; prerelease suffixes after "-" are stripped before comparison.

func ComputeSHA256

func ComputeSHA256(filePath string) (string, error)

ComputeSHA256 computes the SHA256 hash of a file.

func CurrentBinaryPath

func CurrentBinaryPath() (string, error)

CurrentBinaryPath returns the resolved path of the currently running binary.

func Download

func Download(url, destPath string) (int64, error)

Download fetches url to destPath with default config.

func DownloadCacheDir

func DownloadCacheDir() string

DownloadCacheDir returns the path for temporary downloads during upgrade.

func DownloadWithConfig

func DownloadWithConfig(ctx context.Context, url, destPath string, cfg *DownloadConfig) (int64, error)

DownloadWithConfig fetches a file with custom configuration and retries.

func DownloadWithProgress

func DownloadWithProgress(ctx context.Context, url, destPath string, showProgress func(percent float64, downloaded, total int64)) (int64, error)

DownloadWithProgress downloads a file and reports progress.

func EnsureUpgradeDirectories

func EnsureUpgradeDirectories() error

EnsureUpgradeDirectories creates the directories needed for upgrade operations.

func ExtractDigestSHA256

func ExtractDigestSHA256(digest string) string

ExtractDigestSHA256 extracts the hex hash from a GitHub asset digest field. GitHub format: "sha256:abcdef1234..."

func ExtractZip

func ExtractZip(zipPath, targetDir string) error

ExtractZip unzips zipPath contents into targetDir. Contains zip-slip protection against path traversal attacks.

func FindBinaryInDir

func FindBinaryInDir(dir string) string

FindBinaryInDir recursively finds the dws binary in an extracted directory.

func LocateSkillMD

func LocateSkillMD(extractDir string) string

LocateSkillMD finds the directory containing SKILL.md in an extracted zip. It handles both flat layouts (SKILL.md at root) and nested layouts (dws/SKILL.md).

func NeedsUpgrade

func NeedsUpgrade(currentVersion, remoteVersion string) bool

NeedsUpgrade returns true when remoteVersion is newer than currentVersion.

func ParseChecksumFile

func ParseChecksumFile(content string) map[string]string

ParseChecksumFile parses a SHA256SUMS-style file. Each line: "hash filename" (two spaces or whitespace separated). Returns a map of filename -> lowercase hex hash.

func ReplaceSelf

func ReplaceSelf(newBinaryPath string) error

ReplaceSelf atomically replaces the currently running binary with newBinaryPath.

On Unix (macOS / Linux):

  1. Try atomic os.Rename (same filesystem, instant swap)
  2. Fallback to copy if cross-device

On Windows the running .exe is locked by the OS, so direct overwrite fails. Strategy: rename running exe → .old, then rename/copy new binary in, then clean up .old (best-effort, may be cleaned on next run).

func VerifyFileFromChecksums

func VerifyFileFromChecksums(filePath, filename, checksumsContent string) error

VerifyFileFromChecksums verifies a downloaded file against checksums.txt content.

func VerifySHA256

func VerifySHA256(filePath, expectedHash string) error

VerifySHA256 verifies a file against its expected SHA256 hash.

Types

type BackupInfo

type BackupInfo struct {
	Path       string    `json:"path"`
	BinaryPath string    `json:"binaryPath"`
	Version    string    `json:"version"`
	CreatedAt  time.Time `json:"createdAt"`
	Size       int64     `json:"size"`
}

BackupInfo contains information about a single backup.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client communicates with the GitHub Releases API.

func NewClient

func NewClient() *Client

NewClient creates a GitHub release client with default settings.

func NewClientWithBaseURL

func NewClientWithBaseURL(baseURL string) *Client

NewClientWithBaseURL creates a client with a custom base URL (for testing).

func (*Client) FetchAllReleases

func (c *Client) FetchAllReleases() ([]VersionEntry, error)

FetchAllReleases returns all non-draft releases, newest first.

func (*Client) FetchLatestRelease

func (c *Client) FetchLatestRelease() (*ReleaseInfo, error)

FetchLatestRelease returns the latest non-draft release.

func (*Client) FetchReleaseByTag

func (c *Client) FetchReleaseByTag(tag string) (*ReleaseInfo, error)

FetchReleaseByTag returns the release for a specific tag (e.g. "v1.0.5").

type DownloadConfig

type DownloadConfig struct {
	MaxRetries       int
	Timeout          time.Duration
	ProgressCallback func(downloaded, total int64)
	ProgressInterval time.Duration
}

DownloadConfig holds download configuration.

func DefaultDownloadConfig

func DefaultDownloadConfig() *DownloadConfig

DefaultDownloadConfig returns sensible download defaults.

type GitHubAsset

type GitHubAsset struct {
	Name               string `json:"name"`
	Size               int64  `json:"size"`
	Digest             string `json:"digest"`
	BrowserDownloadURL string `json:"browser_download_url"`
	ContentType        string `json:"content_type"`
}

GitHubAsset represents a release asset (downloadable file).

func FindBinaryAsset

func FindBinaryAsset(assets []GitHubAsset) (*GitHubAsset, error)

FindBinaryAsset locates the platform-specific binary archive from the release assets. Pattern: dws-{os}-{arch}.tar.gz (or .zip for windows).

func FindBinaryAssetFor

func FindBinaryAssetFor(assets []GitHubAsset, goos, goarch string) (*GitHubAsset, error)

FindBinaryAssetFor locates the binary archive for a specific platform.

func FindChecksumsAsset

func FindChecksumsAsset(assets []GitHubAsset) *GitHubAsset

FindChecksumsAsset locates the checksums.txt asset.

func FindSkillsAsset

func FindSkillsAsset(assets []GitHubAsset) *GitHubAsset

FindSkillsAsset locates the dws-skills.zip asset.

type GitHubRelease

type GitHubRelease struct {
	TagName     string        `json:"tag_name"`
	Name        string        `json:"name"`
	Body        string        `json:"body"`
	Prerelease  bool          `json:"prerelease"`
	Draft       bool          `json:"draft"`
	PublishedAt string        `json:"published_at"`
	Assets      []GitHubAsset `json:"assets"`
	HTMLURL     string        `json:"html_url"`
}

GitHubRelease represents a single release from the GitHub Releases API.

type ReleaseInfo

type ReleaseInfo struct {
	Version    string
	Date       string
	Changelog  string
	Prerelease bool
	HTMLURL    string
	Assets     []GitHubAsset
}

ReleaseInfo is the simplified view of a release used throughout the upgrade flow.

type RollbackManager

type RollbackManager struct {
	// contains filtered or unexported fields
}

RollbackManager manages backup and rollback operations.

func NewRollbackManager

func NewRollbackManager() *RollbackManager

NewRollbackManager creates a rollback manager using the standard backup directory.

func NewRollbackManagerWithDir

func NewRollbackManagerWithDir(backupDir string) *RollbackManager

NewRollbackManagerWithDir creates a rollback manager with a custom directory.

func (*RollbackManager) Backup

func (r *RollbackManager) Backup(currentVersion string) (string, error)

Backup creates a backup of the currently running binary. Returns the backup directory path.

func (*RollbackManager) Cleanup

func (r *RollbackManager) Cleanup(keep int) error

Cleanup removes old backups, keeping only the most recent N.

func (*RollbackManager) ListBackups

func (r *RollbackManager) ListBackups() ([]BackupInfo, error)

ListBackups returns all available backups, newest first.

func (*RollbackManager) Rollback

func (r *RollbackManager) Rollback() error

Rollback restores the most recent backup.

func (*RollbackManager) RollbackTo

func (r *RollbackManager) RollbackTo(backup BackupInfo) error

RollbackTo restores a specific backup. Uses replaceExeFile to handle Windows file-lock semantics correctly.

type SkillDirResult

type SkillDirResult struct {
	Dir    string         // destination directory (e.g. ~/.claude/skills/dws)
	Status SkillDirStatus // outcome
	Err    error          // non-nil when Status == SkillDirFailed
}

SkillDirResult holds the per-directory install result.

type SkillDirStatus

type SkillDirStatus int

SkillDirStatus describes the installation outcome for a single skill directory.

const (
	SkillDirOK          SkillDirStatus = iota // successfully installed
	SkillDirSkipped                           // agent not detected, directory skipped
	SkillDirBlacklisted                       // blacklisted, never touched
	SkillDirFailed                            // installation attempted but failed
)

type SkillUpgradeResult

type SkillUpgradeResult struct {
	Results []SkillDirResult
}

SkillUpgradeResult aggregates the outcome of an UpgradeSkillLocations call.

func UpgradeSkillLocations

func UpgradeSkillLocations(extractedDir string) (*SkillUpgradeResult, error)

UpgradeSkillLocations installs skills from extractedDir into all locations where they are currently installed or expected.

Strategy (matches npm install.js installSkillsToHomes):

  • ~/.agents/skills/dws/ is ALWAYS updated (primary install location)
  • Other agent dirs (claude, cursor, ...) are updated only when the parent directory exists (e.g. ~/.claude/ exists => user has Claude)
  • ~/.real/ and other blacklisted paths are NEVER touched
  • If no location was updated at all, fall back to ~/.agents/skills/dws/

func (*SkillUpgradeResult) Failed

func (r *SkillUpgradeResult) Failed() []SkillDirResult

Failed returns directories where installation was attempted but failed.

func (*SkillUpgradeResult) Succeeded

func (r *SkillUpgradeResult) Succeeded() []SkillDirResult

Succeeded returns directories that were successfully updated.

type VersionEntry

type VersionEntry struct {
	Version    string
	Date       string
	Changelog  string
	Prerelease bool
}

VersionEntry represents a single version in the version list.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL