Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions cli/commands/update/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func Run() {
updateBrew()
updateClaude()
updateDevbox()
updatePi()
updateSolargraph()
reshimAsdf()
install.Call("vim")
Expand Down Expand Up @@ -92,6 +93,15 @@ func updateDevbox() {
run.Verbose("devbox version update")
}

func updatePi() {
if err := run.Silent("which pi"); err != nil {
log.Info("pi.dev not installed, skipping")
return
}
log.Info("Updating pi.dev")
run.Verbose("pi update")
}

func updateSolargraph() {
log.Info("Updating solargraph gem")
run.Verbose("gem update solargraph")
Expand Down
22 changes: 22 additions & 0 deletions openspec/changes/archive/2026-09-25-add-pi-self-update/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Change: Update pi.dev during `dots update`

## Why

`dots install pi` only installs `pi` when it's missing (`which pi` short-circuits the
installer) and is never called by `dots update`. Once installed, pi.dev's own binary never
gets refreshed by dots — the user has to remember to run `pi update` by hand. Every other
managed tool (Claude Code, Devbox, Homebrew, solargraph, asdf shims) is kept current by
`dots update`; pi.dev should be too.

## What Changes

- Add `updatePi()` to `cli/commands/update/root.go`, following the same
skip-if-not-installed pattern as `updateClaude`/`updateDevbox`: log and skip when `pi` is
not resolvable on `PATH`, otherwise run `pi update` (self-update only, matching the
existing narrow scope of each per-tool update step).
- Call `updatePi()` from `Run()`'s update sequence.

## Impact

- Affected specs: `config-update`
- Affected code: `cli/commands/update/root.go`
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## MODIFIED Requirements

### Requirement: Update Orchestration

`dots update` SHALL update the environment in sequence: pull and reinstall the
dots repository (`git fetch`, `git reset --hard origin/master`, `go install
./...`), update ZSH plugins via zinit (pruning broken completion symlinks),
update tmux plugins, update Homebrew and outdated packages, update Claude Code,
Devbox, pi.dev, and the solargraph gem, reshim asdf, and reinstall the `vim`
component. It SHALL set the tmux window title to `update` while running and
restore it afterward.

#### Scenario: Dots repo pulled and rebuilt

- **WHEN** `dots update` runs
- **THEN** it fetches and hard-resets the dots repo to `origin/master` and runs `go install ./...`

#### Scenario: Vim component reinstalled

- **WHEN** `dots update` runs
- **THEN** it invokes the `vim` installer as part of the update sequence

#### Scenario: pi.dev updated

- **WHEN** `dots update` runs and `pi` is on `PATH`
- **THEN** it runs `pi update` to self-update the pi.dev binary

### Requirement: Conditional Tool Updates

`dots update` SHALL skip updating Claude Code, Devbox, and pi.dev when their
commands are not resolvable on `PATH`, logging that they are not installed
rather than failing.

#### Scenario: Missing tool skipped

- **WHEN** `dots update` runs and `devbox` is not on `PATH`
- **THEN** the Devbox update is skipped with an informational log and the update continues

#### Scenario: Missing pi.dev skipped

- **WHEN** `dots update` runs and `pi` is not on `PATH`
- **THEN** the pi.dev update is skipped with an informational log and the update continues
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## 1. Implementation

- [x] 1.1 Add `updatePi()` to `cli/commands/update/root.go`: skip with an informational log when `which pi` fails, otherwise run `pi update` via `run.Verbose`
- [x] 1.2 Call `updatePi()` from `Run()`'s update sequence, alongside `updateClaude()`/`updateDevbox()`
- [x] 1.3 Update `README.md`'s `pi` component description if it documents install-only behavior (not needed — `dots update`'s per-tool steps aren't enumerated in README)
- [x] 1.4 Run `go install ./...`, `revive -set_exit_status ./...`, `go test ./...`, `bash .github/skill-tests/run_all.sh`, `bash .github/lint-skills.sh`, `qlty check --all --no-fix --level=high`, `qlty smells --all --no-snippets`
21 changes: 16 additions & 5 deletions openspec/specs/config-update/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ This spec documents the behavior that ships today.
dots repository (`git fetch`, `git reset --hard origin/master`, `go install
./...`), update ZSH plugins via zinit (pruning broken completion symlinks),
update tmux plugins, update Homebrew and outdated packages, update Claude Code,
Devbox, and the solargraph gem, reshim asdf, and reinstall the `vim` component.
It SHALL set the tmux window title to `update` while running and restore it
afterward.
Devbox, pi.dev, and the solargraph gem, reshim asdf, and reinstall the `vim`
component. It SHALL set the tmux window title to `update` while running and
restore it afterward.

#### Scenario: Dots repo pulled and rebuilt

Expand All @@ -31,6 +31,11 @@ afterward.
- **WHEN** `dots update` runs
- **THEN** it invokes the `vim` installer as part of the update sequence

#### Scenario: pi.dev updated

- **WHEN** `dots update` runs and `pi` is on `PATH`
- **THEN** it runs `pi update` to self-update the pi.dev binary

### Requirement: Weekly Auto-Clean

`dots update` SHALL run the cleanup routine before updating only when the
Expand All @@ -49,14 +54,20 @@ Within a week of the last clean, the cleanup step SHALL be skipped.

### Requirement: Conditional Tool Updates

`dots update` SHALL skip updating Claude Code and Devbox when their commands are
not resolvable on `PATH`, logging that they are not installed rather than failing.
`dots update` SHALL skip updating Claude Code, Devbox, and pi.dev when their
commands are not resolvable on `PATH`, logging that they are not installed
rather than failing.

#### Scenario: Missing tool skipped

- **WHEN** `dots update` runs and `devbox` is not on `PATH`
- **THEN** the Devbox update is skipped with an informational log and the update continues

#### Scenario: Missing pi.dev skipped

- **WHEN** `dots update` runs and `pi` is not on `PATH`
- **THEN** the pi.dev update is skipped with an informational log and the update continues

### Requirement: Cleanup Command

`dots clean` SHALL clean legacy artifacts: `brew cleanup -s` for Homebrew and
Expand Down
Loading