Compare commits

...

10 Commits

Author SHA1 Message Date
Kevin Bond d965da9fb4 dev mode for cli 2025-10-12 11:43:45 -07:00
Arafatkatze af1291e40c Fix serilationaz 2025-10-12 11:43:35 -07:00
Arafatkatze 6b6e467f58 Fix serilationaz 2025-10-12 11:43:35 -07:00
Arafatkatze dd04eed3a1 Adding local install script 2025-10-12 11:43:35 -07:00
Arafatkatze b016475520 Adding Redirect URL for CLI 2025-10-12 11:43:35 -07:00
Arafatkatze d604ed9f58 debug logs added 2025-10-12 11:43:35 -07:00
Arafatkatze 67c809828e debug logs added 2025-10-12 11:43:35 -07:00
Arafatkatze 3369885394 refactor 2025-10-12 11:43:35 -07:00
Arafatkatze 8c3bef649d Temporary commit for workspace stuff 2025-10-12 11:43:35 -07:00
Arafatkatze 940b1eeea0 Adding multi root to cli 2025-10-12 11:43:21 -07:00
3 changed files with 235 additions and 2 deletions
+41 -2
View File
@@ -300,6 +300,9 @@ func KillInstanceByAddress(ctx context.Context, registry *ClientRegistry, addres
func startClineCore(corePort, hostPort int) (*exec.Cmd, error) {
fmt.Printf("Starting cline-core on port %d (with hostbridge on %d)\n", corePort, hostPort)
// Detect if running in development mode
isDevMode := IsDevMode()
// Get paths relative to the cline binary location
execPath, err := os.Executable()
if err != nil {
@@ -307,8 +310,44 @@ func startClineCore(corePort, hostPort int) (*exec.Cmd, error) {
}
binDir := path.Dir(execPath)
installDir := path.Dir(binDir)
nodePath := path.Join(binDir, "node")
clineCorePath := path.Join(installDir, "cline-core.js")
// Determine node path based on mode
var nodePath string
if isDevMode {
// In dev mode, use system node
nodePath = "node"
fmt.Println("DEBUG: Running in development mode - using system node")
} else {
// In production, use bundled node
nodePath = path.Join(binDir, "node")
// Fallback to system node if bundled version missing
if _, err := os.Stat(nodePath); os.IsNotExist(err) {
nodePath = "node"
fmt.Println("DEBUG: Bundled node not found, falling back to system node")
}
}
// Determine cline-core.js path based on mode
var clineCorePath string
if isDevMode {
// In dev mode, use dist-standalone
projectRoot, err := GetProjectRoot()
if err != nil {
return nil, fmt.Errorf("failed to get project root: %w", err)
}
clineCorePath = path.Join(projectRoot, "dist-standalone", "cline-core.js")
installDir = path.Join(projectRoot, "dist-standalone")
fmt.Printf("DEBUG: Using development paths\n")
fmt.Printf("DEBUG: Project root: %s\n", projectRoot)
} else {
// In production, use installation directory
clineCorePath = path.Join(installDir, "cline-core.js")
}
// Verify cline-core.js exists
if _, err := os.Stat(clineCorePath); os.IsNotExist(err) {
return nil, fmt.Errorf("cline-core.js not found at %s", clineCorePath)
}
// Create port-tagged log file in OS temp directory with full address
logFileName := fmt.Sprintf("cline-core-debug-localhost-%d.log", corePort)
+80
View File
@@ -0,0 +1,80 @@
package global
import (
"os"
"path/filepath"
)
// DevMode detection and configuration
// IsDevMode determines if the CLI is running in development mode.
// Development mode is detected when any of the following conditions are true:
// 1. CLINE_DEV_MODE environment variable is set to "1" or "true"
// 2. A .git directory exists in the project root (2 levels up from binary)
// 3. A .cline-dev marker file exists in the project root
//
// This allows developers to work without packaging while ensuring
// production installations work correctly.
func IsDevMode() bool {
// Check explicit environment variable first (highest priority)
if devMode := os.Getenv("CLINE_DEV_MODE"); devMode == "1" || devMode == "true" {
return true
}
// Get the binary's location
execPath, err := os.Executable()
if err != nil {
return false
}
// Resolve any symlinks
execPath, err = filepath.EvalSymlinks(execPath)
if err != nil {
return false
}
// Get project root (2 levels up: bin/cline -> cli -> project-root)
binDir := filepath.Dir(execPath)
cliDir := filepath.Dir(binDir)
projectRoot := filepath.Dir(cliDir)
// Check for .git directory (common in development)
gitDir := filepath.Join(projectRoot, ".git")
if stat, err := os.Stat(gitDir); err == nil && stat.IsDir() {
return true
}
// Check for explicit dev marker file
devMarker := filepath.Join(projectRoot, ".cline-dev")
if _, err := os.Stat(devMarker); err == nil {
return true
}
return false
}
// GetProjectRoot returns the project root directory based on the binary location.
// For development: returns the Git repository root
// For production: returns the installation directory
func GetProjectRoot() (string, error) {
execPath, err := os.Executable()
if err != nil {
return "", err
}
// Resolve symlinks
execPath, err = filepath.EvalSymlinks(execPath)
if err != nil {
return "", err
}
binDir := filepath.Dir(execPath)
installDir := filepath.Dir(binDir)
if IsDevMode() {
// In dev mode, go up one more level to project root
return filepath.Dir(installDir), nil
}
return installDir, nil
}
+114
View File
@@ -0,0 +1,114 @@
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'
# Configuration
INSTALL_DIR="${CLINE_INSTALL_DIR:-$HOME/.cline/cli}"
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
echo ""
echo -e "${MAGENTA}${BOLD}Installing Cline CLI from local build${NC}"
echo ""
# Always rebuild CLI to ensure latest changes
echo -e "${CYAN}${NC} ${DIM}Rebuilding CLI binaries...${NC}"
cd "$PROJECT_ROOT"
npm run compile-cli > /dev/null 2>&1
echo -e "${GREEN}${NC} CLI binaries rebuilt"
# Always rebuild standalone to ensure latest cline-core.js
echo -e "${CYAN}${NC} ${DIM}Rebuilding standalone package (this may take ~30 seconds)...${NC}"
npm run compile-standalone > /dev/null 2>&1
echo -e "${GREEN}${NC} Standalone package rebuilt"
echo ""
echo -e "${CYAN}${NC} ${DIM}Installing to $INSTALL_DIR${NC}"
# Remove existing installation (clean install)
# This ensures no conflicts with old versions and guarantees a fresh state
if [ -d "$INSTALL_DIR" ]; then
echo -e "${YELLOW}${NC} ${DIM}Removing existing installation for clean install${NC}"
rm -rf "$INSTALL_DIR"
fi
# Create installation directory
mkdir -p "$INSTALL_DIR/bin"
# Copy standalone package first (includes node_modules, cline-core.js, etc.)
rsync -a --exclude='bin' "$PROJECT_ROOT/dist-standalone/" "$INSTALL_DIR/"
# Detect platform for native modules
os=$(uname -s | tr '[:upper:]' '[:lower:]')
arch=$(uname -m)
if [[ "$arch" == "aarch64" ]]; then arch="arm64"; fi
if [[ "$arch" == "x86_64" ]]; then arch="x64"; fi
platform="$os-$arch"
# Copy platform-specific native modules (like better-sqlite3)
if [ -d "$PROJECT_ROOT/dist-standalone/binaries/$platform/node_modules" ]; then
echo -e "${CYAN}${NC} ${DIM}Installing platform-specific modules for $platform${NC}"
cp -r "$PROJECT_ROOT/dist-standalone/binaries/$platform/node_modules/"* "$INSTALL_DIR/node_modules/" 2>/dev/null || true
fi
# Copy binaries (this will create/overwrite the bin directory)
mkdir -p "$INSTALL_DIR/bin"
cp "$PROJECT_ROOT/cli/bin/cline" "$INSTALL_DIR/bin/"
cp "$PROJECT_ROOT/cli/bin/cline-host" "$INSTALL_DIR/bin/"
# Use system Node.js (symlink to avoid copying large binary)
if command -v node >/dev/null 2>&1; then
ln -sf "$(which node)" "$INSTALL_DIR/bin/node"
echo -e "${GREEN}${NC} Linked to system Node.js: $(node --version)"
else
echo -e "${YELLOW}${NC} Node.js not found in PATH. Please install Node.js."
exit 1
fi
# Make binaries executable
chmod +x "$INSTALL_DIR/bin/cline"
chmod +x "$INSTALL_DIR/bin/cline-host"
chmod +x "$INSTALL_DIR/bin/node" 2>/dev/null || true
# Rebuild better-sqlite3 for system Node.js version
echo -e "${CYAN}${NC} ${DIM}Rebuilding native modules for Node.js $(node --version)...${NC}"
cd "$INSTALL_DIR"
npm rebuild better-sqlite3 > /dev/null 2>&1
cd "$PROJECT_ROOT"
echo -e "${GREEN}${NC} Native modules rebuilt"
echo -e "${GREEN}${NC} Installed to ${MAGENTA}${BOLD}$INSTALL_DIR${NC}"
# Configure PATH
BIN_DIR="$INSTALL_DIR/bin"
SHELL_CONFIG="$HOME/.zshrc"
if [ -f "$HOME/.bashrc" ]; then
SHELL_CONFIG="$HOME/.bashrc"
fi
if ! grep -q "$BIN_DIR" "$SHELL_CONFIG" 2>/dev/null; then
echo "" >> "$SHELL_CONFIG"
echo "# Cline CLI" >> "$SHELL_CONFIG"
echo "export PATH=\"$BIN_DIR:\$PATH\"" >> "$SHELL_CONFIG"
echo -e "${GREEN}${NC} Added to PATH in ${CYAN}$(basename $SHELL_CONFIG)${NC}"
else
echo -e "${GREEN}${NC} Already in PATH"
fi
echo ""
echo -e "${GREEN}${BOLD}Installation complete!${NC}"
echo ""
echo -e "Run this to start using ${MAGENTA}${BOLD}cline${NC} immediately:"
echo ""
echo -e "${YELLOW}${BOLD} exec \$SHELL${NC}"
echo ""
echo -e "${DIM}(or just open a new terminal window)${NC}"
echo ""