Skip to content

Commit 37fa262

Browse files
authored
Merge pull request #23 from alex-feel/alex-feel-dev
Resolve npm install failures and SSL certificate errors
2 parents 4c95669 + d3c80b4 commit 37fa262

File tree

2 files changed

+85
-20
lines changed

2 files changed

+85
-20
lines changed

scripts/install-claude.py

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import platform
1010
import re
1111
import shutil
12+
import ssl
1213
import subprocess
1314
import sys
1415
import tempfile
@@ -192,9 +193,17 @@ def install_git_windows_download() -> bool:
192193
try:
193194
info('Downloading Git for Windows installer...')
194195

195-
# Get the download page
196-
with urlopen(GIT_WINDOWS_URL) as response:
197-
html = response.read().decode('utf-8')
196+
# Get the download page (with SSL fallback)
197+
try:
198+
with urlopen(GIT_WINDOWS_URL) as response:
199+
html = response.read().decode('utf-8')
200+
except ssl.SSLError:
201+
warning('SSL certificate verification failed, trying with unverified context')
202+
ctx = ssl.create_default_context()
203+
ctx.check_hostname = False
204+
ctx.verify_mode = ssl.CERT_NONE
205+
with urlopen(GIT_WINDOWS_URL, context=ctx) as response:
206+
html = response.read().decode('utf-8')
198207

199208
# Find the installer link
200209
match = re.search(r'href="([^"]+Git-[\d.]+-64-bit\.exe)"', html)
@@ -210,7 +219,17 @@ def install_git_windows_download() -> bool:
210219
temp_path = tmp.name
211220

212221
info(f'Downloading {installer_url}')
213-
urlretrieve(installer_url, temp_path)
222+
try:
223+
urlretrieve(installer_url, temp_path)
224+
except ssl.SSLError:
225+
warning('SSL certificate verification failed, trying with unverified context')
226+
ctx = ssl.create_default_context()
227+
ctx.check_hostname = False
228+
ctx.verify_mode = ssl.CERT_NONE
229+
import urllib.request
230+
opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=ctx))
231+
urllib.request.install_opener(opener)
232+
urlretrieve(installer_url, temp_path)
214233

215234
# Run installer silently
216235
info('Running Git installer silently...')
@@ -360,9 +379,17 @@ def install_nodejs_direct() -> bool:
360379
try:
361380
info('Downloading Node.js LTS installer...')
362381

363-
# Get LTS version info
364-
with urlopen(NODE_LTS_API) as response:
365-
versions = json.loads(response.read())
382+
# Get LTS version info (with SSL fallback)
383+
try:
384+
with urlopen(NODE_LTS_API) as response:
385+
versions = json.loads(response.read())
386+
except ssl.SSLError:
387+
warning('SSL certificate verification failed, trying with unverified context')
388+
ctx = ssl.create_default_context()
389+
ctx.check_hostname = False
390+
ctx.verify_mode = ssl.CERT_NONE
391+
with urlopen(NODE_LTS_API, context=ctx) as response:
392+
versions = json.loads(response.read())
366393

367394
lts_version = None
368395
for v in versions:
@@ -395,7 +422,17 @@ def install_nodejs_direct() -> bool:
395422
temp_path = tmp.name
396423

397424
info(f'Downloading {installer_url}')
398-
urlretrieve(installer_url, temp_path)
425+
try:
426+
urlretrieve(installer_url, temp_path)
427+
except ssl.SSLError:
428+
warning('SSL certificate verification failed, trying with unverified context')
429+
ctx = ssl.create_default_context()
430+
ctx.check_hostname = False
431+
ctx.verify_mode = ssl.CERT_NONE
432+
import urllib.request
433+
opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=ctx))
434+
urllib.request.install_opener(opener)
435+
urlretrieve(installer_url, temp_path)
399436

400437
# Install based on OS
401438
if system == 'Windows':
@@ -579,8 +616,8 @@ def install_claude_npm() -> bool:
579616

580617
info('Installing Claude Code CLI via npm...')
581618

582-
# Try without sudo first
583-
result = run_command(['npm', 'install', '-g', CLAUDE_NPM_PACKAGE])
619+
# Try without sudo first (show output for debugging)
620+
result = run_command(['npm', 'install', '-g', CLAUDE_NPM_PACKAGE], capture_output=False)
584621

585622
if result.returncode == 0:
586623
success('Claude Code installed successfully')
@@ -589,7 +626,7 @@ def install_claude_npm() -> bool:
589626
# Try with sudo on Unix systems
590627
if platform.system() != 'Windows':
591628
warning('Trying with sudo...')
592-
result = run_command(['sudo', 'npm', 'install', '-g', CLAUDE_NPM_PACKAGE])
629+
result = run_command(['sudo', 'npm', 'install', '-g', CLAUDE_NPM_PACKAGE], capture_output=False)
593630
if result.returncode == 0:
594631
success('Claude Code installed successfully')
595632
return True
@@ -606,20 +643,29 @@ def install_claude_native() -> bool:
606643
try:
607644
info('Trying official native installer...')
608645

609-
# Download installer script
610-
with urlopen(CLAUDE_INSTALLER_URL) as response:
611-
installer_script = response.read().decode('utf-8')
646+
# Download installer script (with SSL fallback)
647+
try:
648+
with urlopen(CLAUDE_INSTALLER_URL) as response:
649+
installer_script = response.read().decode('utf-8')
650+
except ssl.SSLError:
651+
# Fallback: create unverified SSL context for corporate environments
652+
warning('SSL certificate verification failed, trying with unverified context')
653+
ctx = ssl.create_default_context()
654+
ctx.check_hostname = False
655+
ctx.verify_mode = ssl.CERT_NONE
656+
with urlopen(CLAUDE_INSTALLER_URL, context=ctx) as response:
657+
installer_script = response.read().decode('utf-8')
612658

613659
# Save to temp file and execute
614660
with tempfile.NamedTemporaryFile(suffix='.ps1', delete=False, mode='w') as tmp:
615661
tmp.write(installer_script)
616662
temp_path = tmp.name
617663

618-
# Execute installer
664+
# Execute installer (show output for debugging)
619665
result = run_command([
620666
'powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass',
621667
'-File', temp_path,
622-
])
668+
], capture_output=False)
623669

624670
# Clean up
625671
with contextlib.suppress(Exception):

scripts/setup-python-environment.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import os
99
import platform
1010
import shutil
11+
import ssl
1112
import subprocess
1213
import sys
1314
import tempfile
@@ -121,8 +122,17 @@ def download_file(url: str, destination: Path, force: bool = False) -> bool:
121122
return True
122123

123124
try:
124-
response = urlopen(url)
125-
content = response.read()
125+
try:
126+
response = urlopen(url)
127+
content = response.read()
128+
except ssl.SSLError:
129+
warning('SSL certificate verification failed, trying with unverified context')
130+
ctx = ssl.create_default_context()
131+
ctx.check_hostname = False
132+
ctx.verify_mode = ssl.CERT_NONE
133+
response = urlopen(url, context=ctx)
134+
content = response.read()
135+
126136
destination.parent.mkdir(parents=True, exist_ok=True)
127137
destination.write_bytes(content)
128138
success(f'Downloaded: {filename}')
@@ -143,8 +153,17 @@ def install_claude() -> bool:
143153
if system == 'Windows':
144154
installer_url = f'{REPO_BASE_URL}/scripts/windows/install-claude-windows.ps1'
145155
with tempfile.NamedTemporaryFile(suffix='.ps1', delete=False, mode='w') as tmp:
146-
response = urlopen(installer_url)
147-
tmp.write(response.read().decode('utf-8'))
156+
try:
157+
response = urlopen(installer_url)
158+
content = response.read().decode('utf-8')
159+
except ssl.SSLError:
160+
warning('SSL certificate verification failed, trying with unverified context')
161+
ctx = ssl.create_default_context()
162+
ctx.check_hostname = False
163+
ctx.verify_mode = ssl.CERT_NONE
164+
response = urlopen(installer_url, context=ctx)
165+
content = response.read().decode('utf-8')
166+
tmp.write(content)
148167
temp_installer = tmp.name
149168

150169
# Run PowerShell installer

0 commit comments

Comments
 (0)