projecta-rrr 1.16.8 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to RRR will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.16.9] - 2026-01-28
8
+
9
+ ### Fixed
10
+
11
+ - **SUMMARY Path Derivation Bug** - During parallel wave execution, SUMMARY files were incorrectly written to the wrong phase directory because `PHASE_DIR` was derived from where the PLAN file physically existed rather than from the PLAN's `phase:` frontmatter value. Now uses `find_phase_dir()` with phase frontmatter to ensure SUMMARYs always go to the correct phase folder.
12
+
7
13
  ## [1.16.8] - 2026-01-28
8
14
 
9
15
  ### Added
@@ -601,10 +601,25 @@ Track for SUMMARY.md generation.
601
601
  <summary_creation>
602
602
  After all tasks complete, create `{phase}-{plan}-SUMMARY.md`.
603
603
 
604
- **Location:** `{phase-dir}/{phase}-{plan}-SUMMARY.md`
604
+ **Location calculation (milestone-aware):**
605
+
606
+ ```bash
607
+ # Extract phase from PLAN frontmatter (NOT from file location)
608
+ PLAN_PATH="$phase_dir/$phase-$plan-PLAN.md"
609
+ PHASE_VALUE=$(grep -E "^phase:" "$PLAN_PATH" | sed 's/phase: *"\?//' | tr -d '"')
610
+
611
+ # Use find_phase_dir to get the correct phase directory
612
+ # Searches .planning/milestones/vX.X/phases/ first, then falls back to .planning/phases/
613
+ PHASE_DIR=$(find_phase_dir "$PHASE_VALUE")
614
+
615
+ # Build SUMMARY path
616
+ SUMMARY_FILE="${PHASE_DIR}/${phase}-${plan}-SUMMARY.md"
617
+ ```
605
618
 
606
619
  **Phase directory:** `.planning/milestones/v{X.Y}/phases/{phase-number}-{name}/` (milestone-aware structure since v1.11)
607
620
 
621
+ The SUMMARY goes to the phase directory matching the PLAN's `phase:` frontmatter value, not where the PLAN file physically exists. This ensures consistent behavior during parallel execution.
622
+
608
623
  **Use template from:** @~/.claude/rrr/templates/summary.md
609
624
 
610
625
  **Frontmatter population:**
@@ -717,7 +732,7 @@ After SUMMARY.md and STATE.md updates:
717
732
  **1. Stage execution artifacts:**
718
733
 
719
734
  ```bash
720
- git add "{phase-dir}/{phase}-{plan}-SUMMARY.md"
735
+ git add "${PHASE_DIR}/${phase}-${plan}-SUMMARY.md"
721
736
  git add .planning/STATE.md
722
737
  ```
723
738
 
@@ -730,7 +745,7 @@ Tasks completed: [N]/[N]
730
745
  - [Task 1 name]
731
746
  - [Task 2 name]
732
747
 
733
- SUMMARY: {phase-dir}/{phase}-{plan}-SUMMARY.md
748
+ SUMMARY: ${PHASE_DIR}/${phase}-${plan}-SUMMARY.md
734
749
  "
735
750
  ```
736
751
 
package/bin/install.js CHANGED
@@ -206,6 +206,7 @@ const hasHelp = args.includes('--help') || args.includes('-h');
206
206
  const forceStatusline = args.includes('--force-statusline');
207
207
  const forceNotify = args.includes('--force-notify');
208
208
  const noNotify = args.includes('--no-notify');
209
+ const hudOnly = args.includes('--hud-only');
209
210
 
210
211
  console.log(banner);
211
212
 
@@ -221,6 +222,7 @@ if (hasHelp) {
221
222
  ${cyan}--force-statusline${reset} Replace existing statusline config
222
223
  ${cyan}--force-notify${reset} Replace existing notification hook
223
224
  ${cyan}--no-notify${reset} Skip notification hook installation
225
+ ${cyan}--hud-only${reset} Install only HUD components (themes + stop hook)
224
226
 
225
227
  ${yellow}Examples:${reset}
226
228
  ${dim}# Install to default ~/.claude directory${reset}
@@ -235,6 +237,9 @@ if (hasHelp) {
235
237
  ${dim}# Install to current project only${reset}
236
238
  npx projecta-rrr --local
237
239
 
240
+ ${dim}# Install only HUD components (OhMyPosh themes + stop hook)${reset}
241
+ npx projecta-rrr --hud-only
242
+
238
243
  ${yellow}Notes:${reset}
239
244
  The --config-dir option is useful when you have multiple Claude Code
240
245
  configurations (e.g., for different subscriptions). It takes priority
@@ -730,6 +735,199 @@ function runExternalSkillsBootstrap() {
730
735
  }
731
736
  }
732
737
 
738
+ /**
739
+ * Backup settings.json before modification
740
+ * @param {string} settingsPath - Path to settings.json
741
+ * @returns {string|null} - Path to backup file, or null if backup failed
742
+ */
743
+ function backupSettings(settingsPath) {
744
+ if (!fs.existsSync(settingsPath)) {
745
+ return null;
746
+ }
747
+
748
+ const backupPath = settingsPath + '.bak';
749
+ try {
750
+ fs.copyFileSync(settingsPath, backupPath);
751
+ console.log(` ${dim}Backed up settings.json → settings.json.bak${reset}`);
752
+ return backupPath;
753
+ } catch (e) {
754
+ console.log(` ${yellow}⚠${reset} Could not backup settings.json: ${e.message}`);
755
+ return null;
756
+ }
757
+ }
758
+
759
+ /**
760
+ * Install OhMyPosh themes to ~/.poshthemes/
761
+ * @param {string} claudeDir - Claude config directory
762
+ * @param {boolean} isGlobal - Whether this is a global install
763
+ * @returns {object} - { installed: string[], skipped: string[] }
764
+ */
765
+ function installOhMyPoshThemes(claudeDir, isGlobal) {
766
+ const src = path.join(__dirname, '..', 'rrr', 'ohmyposh');
767
+ const installed = [];
768
+ const skipped = [];
769
+
770
+ // Check if source themes directory exists
771
+ if (!fs.existsSync(src)) {
772
+ console.log(` ${dim}No OhMyPosh themes found in rrr/ohmyposh/${reset}`);
773
+ return { installed, skipped };
774
+ }
775
+
776
+ // Determine destination path
777
+ const poshthemesDir = path.join(os.homedir(), '.poshthemes');
778
+ fs.mkdirSync(poshthemesDir, { recursive: true });
779
+
780
+ // Copy each theme file
781
+ const themes = fs.readdirSync(src).filter(f => f.endsWith('.omp.json'));
782
+ for (const theme of themes) {
783
+ const srcFile = path.join(src, theme);
784
+ const destFile = path.join(poshthemesDir, theme);
785
+
786
+ if (fs.existsSync(destFile)) {
787
+ skipped.push(theme);
788
+ console.log(` ${yellow}⚠${reset} Skipped ~/.poshthemes/${theme} (already exists)`);
789
+ } else {
790
+ try {
791
+ fs.copyFileSync(srcFile, destFile);
792
+ installed.push(theme);
793
+ console.log(` ${green}✓${reset} Installed ~/.poshthemes/${theme}`);
794
+ } catch (e) {
795
+ console.log(` ${yellow}⚠${reset} Could not install ~/.poshthemes/${theme}: ${e.message}`);
796
+ }
797
+ }
798
+ }
799
+
800
+ return { installed, skipped };
801
+ }
802
+
803
+ /**
804
+ * Install HUD stop hook and configure it in settings.json
805
+ * @param {string} claudeDir - Claude config directory
806
+ * @param {object} settings - Settings object to modify
807
+ * @param {boolean} isGlobal - Whether this is a global install
808
+ * @param {boolean} bashAvailable - Whether bash is available
809
+ * @returns {boolean} - True if hook was configured
810
+ */
811
+ function installHudStopHook(claudeDir, settings, isGlobal, bashAvailable) {
812
+ const src = path.join(__dirname, '..', 'hooks', 'rrr-update-hud-state.sh');
813
+
814
+ // Check if source hook exists
815
+ if (!fs.existsSync(src)) {
816
+ console.log(` ${dim}HUD stop hook not found${reset}`);
817
+ return false;
818
+ }
819
+
820
+ // Skip if bash is not available
821
+ if (!bashAvailable) {
822
+ console.log(` ${yellow}⚠${reset} Skipped HUD stop hook (bash not available)`);
823
+ return false;
824
+ }
825
+
826
+ // Copy hook file
827
+ const hooksDest = path.join(claudeDir, 'hooks');
828
+ fs.mkdirSync(hooksDest, { recursive: true });
829
+ const destFile = path.join(hooksDest, 'rrr-update-hud-state.sh');
830
+
831
+ try {
832
+ fs.copyFileSync(src, destFile);
833
+ fs.chmodSync(destFile, 0o755);
834
+ console.log(` ${green}✓${reset} Installed hooks/rrr-update-hud-state.sh`);
835
+ } catch (e) {
836
+ console.log(` ${yellow}⚠${reset} Could not install HUD hook: ${e.message}`);
837
+ return false;
838
+ }
839
+
840
+ // Configure hook in settings.json
841
+ const hookCommand = isGlobal
842
+ ? '$HOME/.claude/hooks/rrr-update-hud-state.sh'
843
+ : `${path.basename(claudeDir)}/hooks/rrr-update-hud-state.sh`;
844
+
845
+ // Check if HUD hook already exists
846
+ const hasHudHook = settings.hooks?.Stop?.some(entry =>
847
+ entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-update-hud-state'))
848
+ );
849
+
850
+ if (hasHudHook) {
851
+ console.log(` ${dim}HUD stop hook already configured${reset}`);
852
+ return true;
853
+ }
854
+
855
+ // Add hook to Stop hooks
856
+ if (!settings.hooks) {
857
+ settings.hooks = {};
858
+ }
859
+ if (!settings.hooks.Stop) {
860
+ settings.hooks.Stop = [];
861
+ }
862
+
863
+ settings.hooks.Stop.push({
864
+ hooks: [
865
+ {
866
+ type: 'command',
867
+ command: hookCommand
868
+ }
869
+ ]
870
+ });
871
+
872
+ console.log(` ${green}✓${reset} Configured HUD stop hook`);
873
+ return true;
874
+ }
875
+
876
+ /**
877
+ * HUD-only installation mode
878
+ * Installs only OhMyPosh themes and HUD stop hook
879
+ */
880
+ function installHudOnly() {
881
+ const configDir = expandTilde(explicitConfigDir) || expandTilde(process.env.CLAUDE_CONFIG_DIR);
882
+ const claudeDir = configDir || path.join(os.homedir(), '.claude');
883
+ const isGlobal = true;
884
+
885
+ console.log(`\n ${cyan}Installing RRR HUD components${reset}\n`);
886
+
887
+ // Check bash availability
888
+ let bashStatus = { available: true };
889
+ if (isWindows()) {
890
+ bashStatus = checkBashAvailability();
891
+ if (!bashStatus.available) {
892
+ printWindowsBashWarning();
893
+ }
894
+ }
895
+
896
+ // Install OhMyPosh themes
897
+ console.log(` ${cyan}OhMyPosh Themes${reset}`);
898
+ const themesResult = installOhMyPoshThemes(claudeDir, isGlobal);
899
+
900
+ // Read and backup settings
901
+ const settingsPath = path.join(claudeDir, 'settings.json');
902
+ const settings = readSettings(settingsPath);
903
+
904
+ if (fs.existsSync(settingsPath)) {
905
+ backupSettings(settingsPath);
906
+ }
907
+
908
+ // Install HUD stop hook
909
+ console.log(`\n ${cyan}HUD Stop Hook${reset}`);
910
+ installHudStopHook(claudeDir, settings, isGlobal, bashStatus.available);
911
+
912
+ // Write settings if modified
913
+ if (settings.hooks?.Stop) {
914
+ writeSettings(settingsPath, settings);
915
+ console.log(` ${green}✓${reset} Updated settings.json`);
916
+ }
917
+
918
+ console.log(`
919
+ ${green}HUD installation complete!${reset}
920
+
921
+ ${yellow}Next steps:${reset}
922
+ 1. Add to your shell profile:
923
+ source ~/.claude/rrr/ohmyposh/rrr-env.sh
924
+ eval "$(oh-my-posh init bash)"
925
+ oh-my-posh --config ~/.poshthemes/rrr-kushal.omp.json
926
+
927
+ 2. Restart your terminal or source ~/.zshrc
928
+ `);
929
+ }
930
+
733
931
  /**
734
932
  * Install to the specified directory
735
933
  */
@@ -932,6 +1130,17 @@ function install(isGlobal) {
932
1130
  console.log(` ${green}✓${reset} Installed rrr/scripts/rrr-hud.js`);
933
1131
  }
934
1132
 
1133
+ // PATCH-01: Copy rrr-hud-dynamic.js to ~/.claude/rrr/scripts/
1134
+ // Dynamic HUD state sync from RRR project files
1135
+ const hudDynamicSrc = path.join(src, 'scripts', 'rrr-hud-dynamic.js');
1136
+ if (fs.existsSync(hudDynamicSrc)) {
1137
+ const scriptsDestDir = path.join(claudeDir, 'rrr', 'scripts');
1138
+ fs.mkdirSync(scriptsDestDir, { recursive: true });
1139
+ const hudDynamicDest = path.join(scriptsDestDir, 'rrr-hud-dynamic.js');
1140
+ fs.copyFileSync(hudDynamicSrc, hudDynamicDest);
1141
+ console.log(` ${green}✓${reset} Installed rrr/scripts/rrr-hud-dynamic.js`);
1142
+ }
1143
+
935
1144
  // PATCH-01: Copy rrr-memory/ directory to ~/.claude/rrr/scripts/
936
1145
  // Memory store and state detector for proactive guidance
937
1146
  const rrrMemorySrc = path.join(src, 'scripts', 'rrr-memory');
@@ -1121,6 +1330,37 @@ function install(isGlobal) {
1121
1330
  }
1122
1331
  }
1123
1332
 
1333
+ // Configure SessionStart hook for HUD state sync (only if hook file exists AND bash available)
1334
+ const hudSyncCommand = isGlobal
1335
+ ? '$HOME/.claude/hooks/rrr-sync-hud-state.sh'
1336
+ : `${localDirName}/hooks/rrr-sync-hud-state.sh`;
1337
+
1338
+ if (bashStatus.available && hookFileExists(claudeDir, 'rrr-sync-hud-state.sh')) {
1339
+ if (!settings.hooks) {
1340
+ settings.hooks = {};
1341
+ }
1342
+ if (!settings.hooks.SessionStart) {
1343
+ settings.hooks.SessionStart = [];
1344
+ }
1345
+
1346
+ // Check if HUD sync hook already exists
1347
+ const hasHudSyncHook = settings.hooks.SessionStart.some(entry =>
1348
+ entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-sync-hud-state'))
1349
+ );
1350
+
1351
+ if (!hasHudSyncHook) {
1352
+ settings.hooks.SessionStart.push({
1353
+ hooks: [
1354
+ {
1355
+ type: 'command',
1356
+ command: hudSyncCommand
1357
+ }
1358
+ ]
1359
+ });
1360
+ console.log(` ${green}✓${reset} Configured HUD state sync hook`);
1361
+ }
1362
+ }
1363
+
1124
1364
  // Install Pushpa Mode and MCP setup scripts to the project directory
1125
1365
  // For local install, use current directory; for global, also install to cwd if it has package.json
1126
1366
  const projectDir = process.cwd();
@@ -1599,7 +1839,11 @@ function promptLocation() {
1599
1839
  }
1600
1840
 
1601
1841
  // Main
1602
- if (hasGlobal && hasLocal) {
1842
+ if (hudOnly) {
1843
+ // HUD-only installation mode
1844
+ installHudOnly();
1845
+ process.exit(0);
1846
+ } else if (hasGlobal && hasLocal) {
1603
1847
  console.error(` ${yellow}Cannot specify both --global and --local${reset}`);
1604
1848
  process.exit(1);
1605
1849
  } else if (explicitConfigDir && hasLocal) {
@@ -0,0 +1,37 @@
1
+ # Check for RRR-impacting upstream changes
2
+
3
+ Runs all upstream watchers (Claude Code, Get-Shit-Done, Taches CC Resources) and reports changes that may affect RRR workflows.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ /rrr:check-upstream
9
+ /rrr:check-upstream --verbose # Show detailed change list
10
+ /rrr:check-upstream --watcher # Run specific watcher only
11
+ ```
12
+
13
+ ## Output
14
+
15
+ Reports:
16
+ - Current version of each upstream
17
+ - NEW releases with HIGH risk changes (hooks, permissions, tasks)
18
+ - NEW releases with MEDIUM risk changes (subagents, statusline, setup, fileops, context)
19
+ - Links to release notes for further review
20
+
21
+ HIGH risk changes require immediate attention for RRR compatibility.
22
+ MEDIUM risk changes should be reviewed for improvement opportunities.
23
+
24
+ ## Watchers
25
+
26
+ | Upstream | Role | What's Monitored |
27
+ |----------|------|------------------|
28
+ | Claude Code | toolchain | CLI changes affecting RRR workflows |
29
+ | Get-Shit-Done | strict_baseline | Commands, agents, scripts that RRR extends |
30
+ | Taches CC Resources | capability_harvest | Skills, prompts, workflows for pattern harvest |
31
+
32
+ ## Examples
33
+
34
+ ```
35
+ /rrr:check-upstream # Quick check for new releases with impact
36
+ /rrr:check-upstream --verbose # Show all RRR-impacting changes
37
+ ```
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: rrr:doctor
3
3
  description: Diagnose and fix duplicate RRR installs - non-destructive with rollback
4
- argument-hint: [--report | --fix | --phases | --include-local]
4
+ argument-hint: [--report | --fix | --phases | --include-local | --footer | --fix-footer]
5
5
  allowed-tools: Read, Bash, Glob, Grep, Edit, Write
6
6
  ---
7
7
 
@@ -19,6 +19,8 @@ Diagnose RRR installation for issues and optionally fix them safely.
19
19
  - `--fix`: Quarantine duplicate roots safely, keeping one canonical root
20
20
  - `--phases`: Check and fix duplicate phase directories (v1.15.9+)
21
21
  - `--include-local`: Also scan/fix repo-local `.claude/commands/rrr`
22
+ - `--footer`: Check HUD/footer installation (OhMyPosh themes, hooks, settings)
23
+ - `--fix-footer`: Auto-repair HUD/footer installation issues
22
24
  </objective>
23
25
 
24
26
  <windows_compatible>true</windows_compatible>
@@ -216,6 +218,75 @@ RECOMMENDED ACTIONS:
216
218
  ```
217
219
  </step>
218
220
 
221
+ <step name="footer_check_mode">
222
+ **Footer/HUD Installation Check (--footer)**
223
+
224
+ Check OhMyPosh HUD installation status:
225
+
226
+ ```bash
227
+ node ~/.claude/rrr/scripts/doctor-rrr.js --footer
228
+ ```
229
+
230
+ **Checks performed:**
231
+ - OhMyPosh themes installed (`rrr-atomic.omp.json`, `rrr-kushal.omp.json`)
232
+ - HUD stop hook installed (`rrr-update-hud-state.sh`)
233
+ - HUD sync hook configured in settings.json (`rrr-sync-hud-state.sh`)
234
+ - `rrr-env.sh` sourced for environment variables
235
+ - `hud-state.json` exists
236
+
237
+ **Example output:**
238
+ ```
239
+ RRR HUD / Footer Installation Check
240
+ ═══════════════════════════════════════════════════════════════
241
+
242
+ ✓ OhMyPosh themes: 2/2 installed
243
+ ✓ HUD stop hook: rrr-update-hud-state.sh exists
244
+ ✓ HUD hook config: Configured in settings.json
245
+ ⚠ RRR env script: rrr-env.sh not found (optional)
246
+ ✓ HUD state file: hud-state.json exists
247
+
248
+ ─────────────────────────────────────────────────────────────
249
+ Status: HEALTHY
250
+ ─────────────────────────────────────────────────────────────
251
+
252
+ Run with --fix-footer to auto-repair issues.
253
+ ```
254
+ </step>
255
+
256
+ <step name="footer_fix_mode">
257
+ **Footer/HUD Repair (--fix-footer)**
258
+
259
+ Auto-repair HUD installation issues:
260
+
261
+ ```bash
262
+ node ~/.claude/rrr/scripts/doctor-rrr.js --fix-footer
263
+ ```
264
+
265
+ **Repairs performed:**
266
+ 1. Copies OhMyPosh themes to `~/.claude/rrr/ohmyposh/`
267
+ 2. Installs HUD stop hook to `~/.claude/hooks/`
268
+ 3. Installs HUD sync hook to `~/.claude/hooks/`
269
+ 4. Configures both hooks in `settings.json`
270
+ 5. Copies `rrr-env.sh` for shell integration
271
+
272
+ **What it fixes:**
273
+ - Missing theme files
274
+ - Missing hook files
275
+ - Hooks not configured in settings.json
276
+ - Stale hook paths
277
+
278
+ **Example output:**
279
+ ```
280
+ Repaired:
281
+
282
+ ✓ Installed rrr-atomic.omp.json
283
+ ✓ Installed rrr-kushal.omp.json
284
+ ✓ Installed rrr-update-hud-state.sh
285
+ ✓ Installed rrr-sync-hud-state.sh
286
+ ✓ Configured HUD hooks in settings.json
287
+ ```
288
+ </step>
289
+
219
290
  </process>
220
291
 
221
292
  <success_criteria>
@@ -227,6 +298,9 @@ RECOMMENDED ACTIONS:
227
298
  - [ ] Validation confirms exactly one root remains
228
299
  - [ ] Repo-local roots are protected by default
229
300
  - [ ] Works on Windows (no bash constructs)
301
+ - [ ] Footer mode checks all HUD components (themes, hooks, settings)
302
+ - [ ] Fix-footer mode repairs missing/broken HUD components
303
+ - [ ] HUD state syncs dynamically from RRR project files
230
304
  </success_criteria>
231
305
 
232
306
  <notes>
@@ -203,6 +203,50 @@ Run /rrr:doctor --fix to complete cleanup.
203
203
  ```
204
204
  </step>
205
205
 
206
+ <step name="refresh_hud_components">
207
+ After successful update, refresh HUD components (OhMyPosh themes and stop hook):
208
+
209
+ ```bash
210
+ # Check if HUD components need refresh
211
+ HUD_REFRESH_NEEDED=false
212
+
213
+ # Check if themes exist in source
214
+ if [ -d "rrr/ohmyposh" ]; then
215
+ # Compare modification times
216
+ SOURCE_THEMES_MTIME=$(stat -f "%m" rrr/ohmyposh/rrr-atomic.omp.json 2>/dev/null || stat -c "%Y" rrr/ohmyposh/rrr-atomic.omp.json 2>/dev/null)
217
+ INSTALLED_THEMES_MTIME=$(stat -f "%m" ~/.claude/rrr/ohmyposh/rrr-atomic.omp.json 2>/dev/null || stat -c "%Y" ~/.claude/rrr/ohmyposh/rrr-atomic.omp.json 2>/dev/null)
218
+
219
+ if [ "$SOURCE_THEMES_MTIME" -gt "$INSTALLED_THEMES_MTIME" ]; then
220
+ HUD_REFRESH_NEEDED=true
221
+ fi
222
+ fi
223
+
224
+ # Check if HUD hook exists and needs refresh
225
+ if [ -f "hooks/rrr-update-hud-state.sh" ] && [ -f ~/.claude/hooks/rrr-update-hud-state.sh ]; then
226
+ SOURCE_HOOK_MTIME=$(stat -f "%m" hooks/rrr-update-hud-state.sh 2>/dev/null || stat -c "%Y" hooks/rrr-update-hud-state.sh 2>/dev/null)
227
+ INSTALLED_HOOK_MTIME=$(stat -f "%m" ~/.claude/hooks/rrr-update-hud-state.sh 2>/dev/null || stat -c "%Y" ~/.claude/hooks/rrr-update-hud-state.sh 2>/dev/null)
228
+
229
+ if [ "$SOURCE_HOOK_MTIME" -gt "$INSTALLED_HOOK_MTIME" ]; then
230
+ HUD_REFRESH_NEEDED=true
231
+ fi
232
+ fi
233
+
234
+ # Refresh if needed
235
+ if [ "$HUD_REFRESH_NEEDED" = true ]; then
236
+ node bin/install.js --hud-only --global
237
+ echo "+ HUD components refreshed"
238
+ fi
239
+ ```
240
+
241
+ **Note:** The update process automatically runs `node bin/install.js --hud-only --global` as part of the postinstall hook when installing via npm. This step is for verification only.
242
+
243
+ **Display result:**
244
+ ```
245
+ ✓ OhMyPosh themes up to date
246
+ ✓ HUD stop hook configured
247
+ ```
248
+ </step>
249
+
206
250
  <step name="fetch_secrets_optional">
207
251
  **Optional: Auto-fetch secrets from Infisical**
208
252