From 60c142227233cd46f6faeb7b50f08119eb447209 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 2 Jun 2026 05:12:46 +0000 Subject: [PATCH 1/2] fix: add fast-syntax-highlighting and zsh-autocomplete to plugin catalog These two external oh-my-zsh plugins were referenced by real user configs but absent from data/zsh-plugins.yaml. cloneExternalPlugins treats catalog misses as built-in/unknown and skips the git clone, so oh-my-zsh logged "plugin 'fast-syntax-highlighting' not found" (and likewise for zsh-autocomplete) at shell startup. Add both with their canonical maintained repos and a regression test covering the popular external plugins. --- internal/config/data/zsh-plugins.yaml | 4 ++++ internal/config/zshplugins_test.go | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/internal/config/data/zsh-plugins.yaml b/internal/config/data/zsh-plugins.yaml index 64671d3..ec13d54 100644 --- a/internal/config/data/zsh-plugins.yaml +++ b/internal/config/data/zsh-plugins.yaml @@ -13,3 +13,7 @@ plugins: repo: https://github.com/zsh-users/zsh-completions - name: zsh-history-substring-search repo: https://github.com/zsh-users/zsh-history-substring-search + - name: fast-syntax-highlighting + repo: https://github.com/zdharma-continuum/fast-syntax-highlighting + - name: zsh-autocomplete + repo: https://github.com/marlonrichert/zsh-autocomplete diff --git a/internal/config/zshplugins_test.go b/internal/config/zshplugins_test.go index 79c62d8..2ee6043 100644 --- a/internal/config/zshplugins_test.go +++ b/internal/config/zshplugins_test.go @@ -13,6 +13,22 @@ func TestZshPluginRepoURL_KnownExternal(t *testing.T) { assert.True(t, strings.HasPrefix(url, "https://"), "repo URL must be https, got %q", url) } +func TestZshPluginRepoURL_PopularExternalPlugins(t *testing.T) { + // Regression: these external plugins were referenced by real user configs + // but missing from the catalog, so cloneExternalPlugins skipped them and + // oh-my-zsh logged "plugin not found" at shell startup. + for _, name := range []string{ + "zsh-autosuggestions", + "zsh-syntax-highlighting", + "fast-syntax-highlighting", + "zsh-autocomplete", + } { + url, ok := ZshPluginRepoURL(name) + assert.True(t, ok, "%s should be a known external plugin", name) + assert.True(t, strings.HasPrefix(url, "https://"), "%s repo must be https, got %q", name, url) + } +} + func TestZshPluginRepoURL_BuiltinReturnsFalse(t *testing.T) { for _, builtin := range []string{"git", "docker", "kubectl", "z"} { url, ok := ZshPluginRepoURL(builtin) From 387f1188c135a32c0eb2f4f0a80a435df4d93b7c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 2 Jun 2026 05:22:35 +0000 Subject: [PATCH 2/2] fix: restore shell theme and plugins when installing from remote config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit planFromRemoteConfig set plan.InstallOhMyZsh from rc.Shell.OhMyZsh but dropped rc.Shell.Theme and rc.Shell.Plugins. As a result `openboot install ` (and any remote-config install) took the bare "fresh install" branch in applyShell — installing Oh-My-Zsh but never writing plugins=() nor git-cloning external plugins. The snapshot/state path (PlanFromSnapshot) already copies all three fields; this brings the remote-config path in line. Combined with the catalog additions, installing a config that lists external plugins now clones them into $ZSH_CUSTOM/plugins instead of leaving zsh to log "plugin '...' not found" at every shell startup. --- internal/installer/plan.go | 6 ++++++ internal/installer/plan_test.go | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/internal/installer/plan.go b/internal/installer/plan.go index 49f9e50..8f93583 100644 --- a/internal/installer/plan.go +++ b/internal/installer/plan.go @@ -93,6 +93,12 @@ func planFromRemoteConfig(opts *config.InstallOptions, st *config.InstallState, if rc.Shell != nil && rc.Shell.OhMyZsh { plan.InstallOhMyZsh = true + // Carry theme and plugins through so applyShell takes the restore path + // (writes plugins=() and git-clones external plugins). Dropping these + // silently downgraded remote-config installs to a bare OMZ install with + // no plugins cloned. + plan.ShellTheme = rc.Shell.Theme + plan.ShellPlugins = rc.Shell.Plugins } for _, p := range rc.MacOSPrefs { diff --git a/internal/installer/plan_test.go b/internal/installer/plan_test.go index 298ccd5..4f94efe 100644 --- a/internal/installer/plan_test.go +++ b/internal/installer/plan_test.go @@ -418,6 +418,29 @@ func TestPlanFromSnapshot_ShellRestored(t *testing.T) { assert.Equal(t, []string{"git", "kubectl"}, plan.ShellPlugins) } +func TestPlan_RemoteConfig_ShellThemeAndPluginsRestored(t *testing.T) { + // Regression: planFromRemoteConfig used to set only InstallOhMyZsh and drop + // the theme/plugins, so `openboot install ` installed a bare OMZ and + // never wrote plugins=() or cloned external plugins. + opts := &config.InstallOptions{DryRun: true, Silent: true} + st := &config.InstallState{ + RemoteConfig: &config.RemoteConfig{ + Shell: &config.RemoteShellConfig{ + OhMyZsh: true, + Theme: "robbyrussell", + Plugins: []string{"git", "zsh-autosuggestions", "fast-syntax-highlighting"}, + }, + }, + } + + plan, err := Plan(opts, st) + require.NoError(t, err) + + assert.True(t, plan.InstallOhMyZsh) + assert.Equal(t, "robbyrussell", plan.ShellTheme) + assert.Equal(t, []string{"git", "zsh-autosuggestions", "fast-syntax-highlighting"}, plan.ShellPlugins) +} + func TestPlanFromSnapshot_ShellSkipFlag(t *testing.T) { cfg := &config.Config{ InstallOptions: config.InstallOptions{