Skip to content

feat(cli): add hunk update self-update command - #788

Merged
benvinegar merged 2 commits into
mainfrom
claude/opencode-update-mechanism-0m7hl7
Aug 18, 2026
Merged

benvinegar merged 2 commits into
mainfrom
claude/opencode-update-mechanism-0m7hl7

Conversation

@benvinegar

@benvinegar benvinegar commented Aug 16, 2026 •

Copy link
Copy Markdown
Member

Adds an opencode-style self-update flow.

What it does

  • hunk update [version] [--method npm|brew] [--check] detects how Hunk was installed and delegates the upgrade to the package manager that owns the install:
    • npm / bun / pnpm global installs → npm install --global hunkdiff@<version> (or the owning client; .cmd shims on Windows)
    • Homebrew → brew upgrade hunk
    • Nix / mise / local source builds → prints the one command that does work (your Nix config / mise up hunk / bun run install:bin) instead of acting behind the user's back
  • Install-source detection (src/core/process/installSource.ts) reads HUNK_INSTALL_SOURCE, the /nix/store/ prefix, mise's installs layout, Homebrew prefixes (requiring the hunk artifact name, so a Homebrew-installed Bun running from source doesn't misclassify), the install:bin target directory, and the untagged-version sentinel.
  • Latest-version lookup (src/core/process/latestRelease.ts) asks each channel's own registry: npm dist-tags for npm installs, formulae.brew.sh for Homebrew. This also fixes the startup notice bug where Homebrew installs were compared against npm dist-tags and could be told about versions brew can't install yet.
  • The startup update notice now shares the same detector and points users at hunk update.
  • The [version] argument is validated as an exact release version; npm specs (tags, ranges, paths, aliases) are rejected.

Notes

  • All I/O (env, exec path, fetch, spawn, platform) is injectable; tests run offline.
  • New modules live in src/core/process/ per the post-Organize src/core into real modules #795 layout; bun run deps:check passes.
  • Greptile review comments are addressed in 689ce4d.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sf2y1jWD9fgx7aAKYbLQC6

@vercel

vercel Bot commented Aug 16, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hunk-web Ignored Ignored Preview Aug 17, 2026 9:42pm

Request Review

@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds an install-aware hunk update command, release-channel lookups, package-manager execution, and shared install-source/version logic, then connects the command through CLI parsing and startup dispatch.

  • Detects npm, Homebrew, Nix, mise, and local-development installations.
  • Fetches npm or Homebrew release metadata and updates startup notices accordingly.
  • Executes npm, bun, pnpm, or Homebrew updates and provides guidance for unmanaged installations.
  • Adds tests for source detection, release lookup, update execution, and notices.

Confidence Score: 3/5

The PR should not merge until local source builds are classified correctly and explicit update targets are restricted to valid Hunk versions.

The production self-update path can falsely report an untagged source build as current, while the unvalidated positional argument can cause npm to install targets outside the documented Hunk-version contract.

Files Needing Attention: src/core/selfUpdate.ts, src/core/cli.ts, src/core/installSource.ts

Important Files Changed

Filename Overview
src/core/selfUpdate.ts Implements update orchestration, but omits version-aware source detection and accepts arbitrary npm package specifications.
src/core/installSource.ts Adds centralized install-source and npm-client detection; its unknown-version fallback is bypassed by the self-update caller.
src/core/cli.ts Adds update command parsing and help, but leaves the version positional unvalidated.
src/core/latestRelease.ts Adds timeout-protected, channel-specific npm and Homebrew release metadata lookup with response validation.
src/core/updateNotice.ts Reuses install-aware release lookup and correctly supplies the installed version during source detection.
src/main.tsx Dispatches the new self-update startup plan as a short-lived CLI command.
src/app/startup.ts Maps parsed update input into the new self-update startup plan.
src/core/version.ts Extracts normalized version classification and guarded semver comparison helpers.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  CLI[hunk update version/options] --> Parse[parseUpdateCommand]
  Parse --> Plan[self-update StartupPlan]
  Plan --> Run[runSelfUpdateCommand]
  Run --> Detect[detectInstallSource]
  Detect -->|npm| Registry[npm dist-tags]
  Detect -->|Homebrew| Formula[Homebrew formula API]
  Detect -->|Nix/mise/dev| Guidance[Print owner-specific guidance]
  Registry --> Spawn[npm/bun/pnpm global install]
  Formula --> Brew[brew upgrade hunk]
Loading
Prompt To Fix All With AI
### Issue 1
src/core/selfUpdate.ts:162-164
**Untagged builds misclassified as npm**

When an untagged local build outside the recognized development install directory runs `hunk update` or `hunk update --check`, this detector omits `installedVersion` and falls back to npm, causing `0.0.0-unknown` to be reported as already up to date instead of showing the local-build update guidance.

```suggestion
  const installSource =
    input.method ??
    (io.resolveInstallSource ??
      (() => detectInstallSource({ env, executablePath, version: installedVersion })))();
```

### Issue 2
src/core/cli.ts:1667-1670
**Version accepts arbitrary npm specs**

When an npm-installed user supplies an npm alias, local path, repository, range, or tag as `[version]`, the unvalidated value is embedded in `hunkdiff@${targetVersion}`, causing the command to install a target outside the documented normalized Hunk-version contract.

### Issue 3
src/core/selfUpdate.ts:158
**Environment bypasses validated configuration**

The production self-update path defaults directly to `process.env`, bypassing the repository's required validated environment-access convention and making invalid install-source configuration harder to detect consistently.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "wip: checkpoint hunk update self-update ..." | Re-trigger Greptile

Comment thread src/core/selfUpdate.ts Outdated
Comment thread src/app/cli.ts
Comment thread src/core/process/selfUpdate.ts
claude added 2 commits August 17, 2026 21:39
Add an opencode-style self-update flow: detect how Hunk was installed
(npm, Homebrew, Nix, mise, or a local source build) from env and
executable path, query that channel's own registry for the latest
version, and delegate the upgrade to the channel's package manager.
Nix, mise, and dev installs get guidance instead of a spawned upgrade.
The startup update notice now shares the same detector and points
users at hunk update; Homebrew installs are compared against the brew
formula version instead of npm dist-tags, so they are no longer
notified about versions brew cannot install yet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sf2y1jWD9fgx7aAKYbLQC6
Pass the installed version into install-source detection so untagged
local builds outside the recognized install directory get source-build
guidance instead of falling back to npm, and validate the update
version argument as an exact release version so arbitrary npm specs
(tags, ranges, paths, aliases) never reach the package-manager spec.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sf2y1jWD9fgx7aAKYbLQC6
@benvinegar
benvinegar force-pushed the claude/opencode-update-mechanism-0m7hl7 branch from 0bd23e5 to 689ce4d Compare August 17, 2026 21:42
@benvinegar benvinegar changed the title wip: checkpoint hunk update self-update implementation feat(cli): add hunk update self-update command Aug 17, 2026
@benvinegar
benvinegar merged commit 7d25fbf into main Aug 18, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants