From f9642c4286ae054c2f7034ee3be895a74bbebad2 Mon Sep 17 00:00:00 2001 From: Lex Christopherson Date: Mon, 15 Dec 2025 17:29:52 -0600 Subject: [PATCH] Add global/local install prompt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Prompt user to choose global (~/.claude) or local (./.claude) - Support --global/-g and --local/-l flags for non-interactive use - Default to global when Enter pressed πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- bin/install.js | 88 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 17 deletions(-) diff --git a/bin/install.js b/bin/install.js index f4db4a965..5a8a84d4b 100755 --- a/bin/install.js +++ b/bin/install.js @@ -3,10 +3,12 @@ const fs = require('fs'); const path = require('path'); const os = require('os'); +const readline = require('readline'); // Colors const cyan = '\x1b[36m'; const green = '\x1b[32m'; +const yellow = '\x1b[33m'; const dim = '\x1b[2m'; const reset = '\x1b[0m'; @@ -26,28 +28,80 @@ ${cyan} β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— development system for Claude Code by TΓ‚CHES. `; +// Parse args +const args = process.argv.slice(2); +const hasGlobal = args.includes('--global') || args.includes('-g'); +const hasLocal = args.includes('--local') || args.includes('-l'); + console.log(banner); -// Paths -const src = path.join(__dirname, '..'); -const claudeDir = path.join(os.homedir(), '.claude'); -const commandsDir = path.join(claudeDir, 'commands'); +/** + * Install to the specified directory + */ +function install(isGlobal) { + const src = path.join(__dirname, '..'); + const claudeDir = isGlobal + ? path.join(os.homedir(), '.claude') + : path.join(process.cwd(), '.claude'); -// Create directories -fs.mkdirSync(commandsDir, { recursive: true }); + const locationLabel = isGlobal + ? claudeDir.replace(os.homedir(), '~') + : claudeDir.replace(process.cwd(), '.'); -// Copy commands/gsd -const gsdSrc = path.join(src, 'commands', 'gsd'); -const gsdDest = path.join(commandsDir, 'gsd'); -fs.cpSync(gsdSrc, gsdDest, { recursive: true }); -console.log(` ${green}βœ“${reset} Installed commands/gsd`); + console.log(` Installing to ${cyan}${locationLabel}${reset}\n`); -// Copy get-shit-done -const skillSrc = path.join(src, 'get-shit-done'); -const skillDest = path.join(claudeDir, 'get-shit-done'); -fs.cpSync(skillSrc, skillDest, { recursive: true }); -console.log(` ${green}βœ“${reset} Installed get-shit-done`); + // Create commands directory + const commandsDir = path.join(claudeDir, 'commands'); + fs.mkdirSync(commandsDir, { recursive: true }); -console.log(` + // Copy commands/gsd + const gsdSrc = path.join(src, 'commands', 'gsd'); + const gsdDest = path.join(commandsDir, 'gsd'); + fs.cpSync(gsdSrc, gsdDest, { recursive: true }); + console.log(` ${green}βœ“${reset} Installed commands/gsd`); + + // Copy get-shit-done skill + const skillSrc = path.join(src, 'get-shit-done'); + const skillDest = path.join(claudeDir, 'get-shit-done'); + fs.cpSync(skillSrc, skillDest, { recursive: true }); + console.log(` ${green}βœ“${reset} Installed get-shit-done`); + + console.log(` ${green}Done!${reset} Run ${cyan}/gsd:help${reset} to get started. `); +} + +/** + * Prompt for install location + */ +function promptLocation() { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + console.log(` ${yellow}Where would you like to install?${reset} + + ${cyan}1${reset}) Global ${dim}(~/.claude)${reset} - available in all projects + ${cyan}2${reset}) Local ${dim}(./.claude)${reset} - this project only +`); + + rl.question(` Choice ${dim}[1]${reset}: `, (answer) => { + rl.close(); + const choice = answer.trim() || '1'; + const isGlobal = choice !== '2'; + install(isGlobal); + }); +} + +// Main +if (hasGlobal && hasLocal) { + console.error(` ${yellow}Cannot specify both --global and --local${reset}`); + process.exit(1); +} else if (hasGlobal) { + install(true); +} else if (hasLocal) { + install(false); +} else { + promptLocation(); +}