Self-Update Mechanism
Relevant source files
The following files were used as context for generating this wiki page:
The Self-Update Mechanism is a core feature of the OCX CLI designed to ensure the tool remains current with the latest releases. It provides a automated workflow for detecting, downloading, verifying, and applying updates to the CLI binary itself. The system supports multiple installation environments, including direct binary downloads (curl-based) and various Node.js package managers such as npm, pnpm, bun, and yarn.
Architecturally, the mechanism adheres to the "5 Laws of Elegant Defense," prioritizing early exits for up-to-date versions, rigorous checksum verification for security, and atomic file replacement to prevent corruption during the update process. Sources: packages/cli/src/commands/self/update.ts:1-20, packages/cli/src/self-update/verify.ts:1-12
Update Detection and Strategy
The update process begins by checking the current version against the latest available version on the registry. The system uses an explicit timeout to ensure responsiveness and categorizes results into a typed structure.
Version Comparison and Methods
The CLI detects the original installation method to determine the appropriate update strategy. If the user installed via a package manager, the CLI invokes that manager's global install command. If installed via a direct binary download, it performs a manual download and verification.
The diagram above illustrates the decision logic used to select an update strategy based on the local environment and version status. Sources: packages/cli/src/commands/self/update.ts:65-103
| Install Method | Strategy Description | Command Example |
|---|---|---|
curl | Direct binary download, checksum verification, and atomic swap. | N/A (Internal Logic) |
npm | Shells out to npm global installation. | npm install -g ocx@<version> |
pnpm | Shells out to pnpm global installation. | pnpm install -g ocx@<version> |
bun | Shells out to bun global installation. | bun install -g ocx@<version> |
yarn | Shells out to yarn global installation. | yarn global add ocx@<version> |
Sources: packages/cli/src/commands/self/update.ts:153-200
Security and Verification
For direct binary updates (the curl method), the CLI implements a multi-stage security pipeline. This ensures that the downloaded executable is authentic and untampered with before it replaces the active binary.
Checksum Verification Pipeline
The verification process relies on SHA256 hashes. The CLI fetches a SHA256SUMS.txt file from the official repository releases and compares the hash of the downloaded temporary file against the expected hash for that specific platform architecture.
The sequence above details the security-first approach taken during binary updates to prevent the execution of malicious or corrupted code. Sources: packages/cli/src/self-update/verify.ts:60-85, packages/cli/src/commands/self/update.ts:119-145
Key Verification Functions
fetchChecksums(version): Downloads and parses the manifest containing hashes for all platform binaries.verifyChecksum(filePath, expectedHash, filename): Performs the actual comparison; throws anIntegrityErrorif the hashes do not match.hashContent(content): A utility function usingnode:cryptoto generate hex-encoded SHA256 hashes.
Sources: packages/cli/src/self-update/verify.ts:18-55
Component Updates vs. Self-Updates
While "Self-Update" refers to the CLI binary, the project also contains a standard update command for managing installed registry components. This system shares similar logic, such as hash-based change detection and lock file management.
Component Update Logic
Component updates use an ocx.lock file to track the current state of installed plugins, skills, and agents. The system resolves which components need updating by comparing local hashes with those fetched from the component registry.
| Feature | Self-Update (ocx self update) | Component Update (ocx update) |
|---|---|---|
| Scope | The CLI executable itself | Registry components (plugins, skills) |
| Verification | SHA256 via GitHub Releases | Content hashing via ocx.lock |
| Persistence | Replaces system binary | Updates .opencode/ files |
| Targeting | Latest release version | Specific components or --all |
Sources: packages/cli/src/commands/update.ts:80-120, packages/cli/src/commands/self/update.ts:65-75
Implementation Details
The implementation leverages Bun.spawn for package manager interactions and node:crypto for hash calculations. To prevent command injection during package manager updates, the CLI strictly validates version strings against a Semver regex pattern before execution.
// packages/cli/src/commands/self/update.ts:184-195
try {
switch (method) {
case "npm": {
await runPackageManager(["npm", "install", "-g", `ocx@${targetVersion}`])
break
}
case "bun": {
await runPackageManager(["bun", "install", "-g", `ocx@${targetVersion}`])
break
}
// ... other methods
}
}
Sources: packages/cli/src/commands/self/update.ts:184-195, packages/cli/src/commands/self/update.ts:50-52
The "Atomic Replace" pattern is used for binary updates, where the new binary is first downloaded to a temporary location and then moved to the final destination, ensuring the CLI is not left in a broken state if the download is interrupted. Sources: packages/cli/src/commands/self/update.ts:140-145
Summary
The Self-Update Mechanism in OCX provides a robust and secure way to keep the CLI and its components synchronized with the latest improvements. By integrating with both system-level package managers and direct binary verification workflows, it ensures cross-platform reliability while maintaining high security standards through SHA256 integrity checks.