Skip to content
Merged
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
34 changes: 31 additions & 3 deletions src/genie-commands/update.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { spawn } from 'node:child_process';
import { execSync, spawn } from 'node:child_process';
import {
chmodSync,
copyFileSync,
Expand Down Expand Up @@ -369,6 +369,32 @@ function updatePluginRegistry(claudePlugins: string, cacheDir: string, version:
}
}

const GENIE_TMUX_HEADER = '# Genie TUI — tmux configuration';

/** If ~/.tmux.conf was installed by genie, overwrite it and reload tmux. */
function syncTmuxConf(tmuxScriptsSrc: string): void {
const tmuxConfSrc = join(tmuxScriptsSrc, 'genie.tmux.conf');
const tmuxConfDest = join(homedir(), '.tmux.conf');
if (!existsSync(tmuxConfSrc) || !existsSync(tmuxConfDest)) return;

try {
const existing = readFileSync(tmuxConfDest, 'utf-8');
if (!existing.includes(GENIE_TMUX_HEADER)) return;

copyFileSync(tmuxConfSrc, tmuxConfDest);
success('Updated ~/.tmux.conf (genie-managed)');

try {
execSync('tmux source-file ~/.tmux.conf', { stdio: 'ignore' });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The execSync call uses a hardcoded path with ~, which relies on shell expansion and can be brittle (e.g., with spaces in the home directory path). It's more robust to use the tmuxConfDest variable, which holds the full path, and to quote it.

Suggested change
execSync('tmux source-file ~/.tmux.conf', { stdio: 'ignore' });
execSync('tmux source-file "' + tmuxConfDest + '"', { stdio: 'ignore' });

success('Reloaded tmux configuration');
} catch {
// tmux not running or reload failed — non-fatal
}
} catch {
// Read/write failed — non-fatal
}
}

/** Copy tmux scripts from the global package to ~/.genie/scripts/ */
function syncTmuxScripts(globalPkgDir: string): void {
const tmuxScriptsSrc = join(globalPkgDir, 'scripts', 'tmux');
Expand All @@ -379,12 +405,12 @@ function syncTmuxScripts(globalPkgDir: string): void {

let scriptCount = 0;
for (const entry of readdirSync(tmuxScriptsSrc)) {
if (entry.endsWith('.sh')) {
if (entry.endsWith('.sh') || entry === 'genie.tmux.conf') {
const src = join(tmuxScriptsSrc, entry);
const dest = join(scriptsDir, entry);
copyFileSync(src, dest);
try {
chmodSync(dest, 0o755);
chmodSync(dest, entry.endsWith('.sh') ? 0o755 : 0o644);
} catch {
// chmod may fail on some filesystems — non-fatal
}
Expand All @@ -395,6 +421,8 @@ function syncTmuxScripts(globalPkgDir: string): void {
if (scriptCount > 0) {
success(`Refreshed ${scriptCount} tmux scripts at ${scriptsDir}`);
}

syncTmuxConf(tmuxScriptsSrc);
}

async function syncPlugin(installType: InstallationType): Promise<void> {
Expand Down
Loading