This commit is contained in:
2026-01-09 17:06:48 -08:00
parent 1bd97b9665
commit 37afa15dfd
2 changed files with 31 additions and 93 deletions

View File

@@ -2,9 +2,9 @@
## Problem on "Other Computer" ## Problem on "Other Computer"
When running `bootstrap.py` on another machine, the installation completes successfully with messages about creating `mm.ps1` and `mm.bat`, but the `mm` command is not recognized when executed. When running `bootstrap.py` on another machine, the installation completes successfully with messages about creating `mm.bat`, but the `mm` command is not recognized when executed.
**Root Cause:** Windows terminal sessions cache the PATH environment variable. When registry changes are made, existing terminal sessions don't automatically reload the new PATH. The shim files are created correctly, but they're not discoverable until PATH is reloaded. **Root Cause:** Windows terminal sessions cache the PATH environment variable. When registry changes are made, existing terminal sessions don't automatically reload the new PATH. The batch shim is created correctly, but it isn't discoverable until either the current session reloads PATH or a new terminal is opened.
## Solution ## Solution
@@ -25,13 +25,7 @@ $env:PATH = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Envir
mm --help mm --help
``` ```
Note: The bootstrap installation automatically attempts this, but it may not work if PowerShell was launched with a restricted execution policy. Note: The bootstrap installation already attempts a reload for you, but it only affects new commands started after the update (or terminals that already inherit the updated PATH).
### Option 3: Manual PATH Reload (PowerShell)
```powershell
$env:Path = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')
mm --help
```
## Diagnostic Command ## Diagnostic Command
@@ -42,8 +36,8 @@ python scripts/bootstrap.py --check-install
``` ```
This will check: This will check:
-Shim files exist (`mm.ps1` and `mm.bat`) -Batch shim exists (`mm.bat`)
- ✓ Shim files have valid content - ✓ Shim content is valid and points at the local venv
- ✓ PATH environment variable is configured - ✓ PATH environment variable is configured
- ✓ Registry PATH was updated - ✓ Registry PATH was updated
- ✓ Test if `mm` command is accessible - ✓ Test if `mm` command is accessible
@@ -54,26 +48,25 @@ This will check:
Checking 'mm' command installation... Checking 'mm' command installation...
Checking for shim files: Checking for shim files:
mm.ps1: ✓ (C:\Users\Admin\bin\mm.ps1) mm.bat: ✓ (C:\Users\Admin\bin\mm.bat)
mm.bat: ✓ (C:\Users\Admin\bin\mm.bat)
Checking PATH environment variable: Checking PATH environment variable:
C:\Users\Admin\bin in current session PATH: C:\Users\Admin\bin in current session PATH:
C:\Users\Admin\bin in registry PATH: C:\Users\Admin\bin in registry PATH:
Testing 'mm' command... Testing 'mm' command...
✗ 'mm' command not found in PATH ✗ 'mm' command not found in PATH
Shims exist but command is not accessible via PATH Shims exist but command is not accessible via PATH
Attempting to call shim directly... Attempting to call shim directly...
✓ Direct shim call works! ✓ Direct shim call works!
The shim files are valid and functional. The shim files are valid and functional.
⚠️ 'mm' is not in PATH, but the shims are working correctly. ⚠️ 'mm' is not in PATH, but the shim is working correctly.
Possible causes and fixes: Possible causes and fixes:
1. Terminal needs restart: Close and reopen your terminal/PowerShell 1. Terminal needs restart: Close and reopen your terminal/PowerShell
2. PATH reload: Run: . scripts\reload-path.ps1 2. PATH reload: Run: $env:Path = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')
3. Manual PATH: Add C:\Users\Admin\bin to your system PATH manually 3. Manual PATH: Add C:\Users\Admin\bin to your system PATH manually
``` ```
If the diagnostic shows: If the diagnostic shows:
@@ -118,13 +111,11 @@ This shows:
## Shim File Locations ## Shim File Locations
The installation creates Windows shim files in: The installation creates a Windows shim in:
- **User bin directory:** `C:\Users\<YourUsername>\bin\` - **User bin directory:** `C:\Users\<YourUsername>\bin\`
- **Files created:** - **File created:** `mm.bat` a batch shim that both CMD and PowerShell can execute without changing the system execution policy.
- `mm.ps1` - PowerShell shim
- `mm.bat` - Command Prompt shim
These files contain the absolute path to your project and venv, so they work from any location. The batch shim contains the absolute path to your project and venv, so it always runs the local CLI regardless of the current directory.
## Why This Happens ## Why This Happens

View File

@@ -551,21 +551,12 @@ def main() -> int:
if system == "windows": if system == "windows":
user_bin = Path(os.environ.get("USERPROFILE", str(home))) / "bin" user_bin = Path(os.environ.get("USERPROFILE", str(home))) / "bin"
mm_ps1 = user_bin / "mm.ps1"
mm_bat = user_bin / "mm.bat" mm_bat = user_bin / "mm.bat"
print(f"Checking for shim files:") print(f"Checking for shim files:")
print(f" mm.ps1: {'' if mm_ps1.exists() else ''} ({mm_ps1})")
print(f" mm.bat: {'' if mm_bat.exists() else ''} ({mm_bat})") print(f" mm.bat: {'' if mm_bat.exists() else ''} ({mm_bat})")
print() print()
if mm_ps1.exists():
ps1_content = mm_ps1.read_text(encoding="utf-8")
if "$repo" in ps1_content or "$REPO" in ps1_content:
print(f" mm.ps1 content looks valid ({len(ps1_content)} bytes)")
else:
print(f" ⚠️ mm.ps1 content may be corrupted")
if mm_bat.exists(): if mm_bat.exists():
bat_content = mm_bat.read_text(encoding="utf-8") bat_content = mm_bat.read_text(encoding="utf-8")
if "REPO=" in bat_content or "PY=" in bat_content: if "REPO=" in bat_content or "PY=" in bat_content:
@@ -617,7 +608,7 @@ def main() -> int:
print("Attempting to call shim directly...") print("Attempting to call shim directly...")
try: try:
result = subprocess.run( result = subprocess.run(
["powershell", "-NoProfile", "-Command", f"& '{mm_ps1}' --help"], [str(mm_bat), "--help"],
capture_output=True, text=True, timeout=5 capture_output=True, text=True, timeout=5
) )
if result.returncode == 0: if result.returncode == 0:
@@ -629,7 +620,7 @@ def main() -> int:
print("Possible causes and fixes:") print("Possible causes and fixes:")
print(f" 1. Terminal needs restart: Close and reopen your terminal/PowerShell") print(f" 1. Terminal needs restart: Close and reopen your terminal/PowerShell")
print(f" 2. PATH reload: Run: $env:Path = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')") print(f" 2. PATH reload: Run: $env:Path = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')")
print(f" 3. Manual PATH: Add C:\\Users\\Admin\\bin to your system PATH manually") print(f" 3. Manual PATH: Add {user_bin} to your system PATH manually")
else: else:
print(f" ✗ Direct shim call failed") print(f" ✗ Direct shim call failed")
if result.stderr: if result.stderr:
@@ -1001,35 +992,7 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
if not (repo / "scripts").exists(): if not (repo / "scripts").exists():
print(f"WARNING: scripts folder not found at {repo}/scripts - mm command may not work", file=sys.stderr) print(f"WARNING: scripts folder not found at {repo}/scripts - mm command may not work", file=sys.stderr)
# Convert repo path to string with proper escaping # Write mm.bat (CMD shim for all shells; avoids PowerShell execution policy issues)
repo_str = str(repo).replace("\\", "\\\\")
# Write mm.ps1 (PowerShell shim)
mm_ps1 = user_bin / "mm.ps1"
ps1_text = (
"Param([Parameter(ValueFromRemainingArguments=$true)] $args)\n"
f'$repo = "{repo_str}"\n'
"$venv = Join-Path $repo '.venv'\n"
"$py = Join-Path $venv 'Scripts\\python.exe'\n"
"if (Test-Path $py) {\n"
" if ($env:MM_DEBUG) {\n"
' Write-Host "MM_DEBUG: using venv python at $py" -ForegroundColor Yellow\n'
" & $py -c \"import sys; print('sys.executable:', sys.executable); print('sys.path:', sys.path[:5])\"\n"
" }\n"
" & $py -m scripts.cli_entry @args; exit $LASTEXITCODE\n"
"}\n"
"# Fallback to system python if venv doesn't exist\n"
"if ($env:MM_DEBUG) { Write-Host 'MM_DEBUG: venv python not found at' $py ', trying system python' -ForegroundColor Yellow }\n"
"python -m scripts.cli_entry @args\n"
)
if mm_ps1.exists():
bak = mm_ps1.with_suffix(f".bak{int(time.time())}")
mm_ps1.replace(bak)
mm_ps1.write_text(ps1_text, encoding="utf-8")
if not args.quiet:
print(f"Created {mm_ps1}")
# Write mm.bat (CMD shim for better compatibility)
mm_bat = user_bin / "mm.bat" mm_bat = user_bin / "mm.bat"
repo_bat_str = str(repo) repo_bat_str = str(repo)
bat_text = ( bat_text = (
@@ -1056,15 +1019,12 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
mm_bat.replace(bak) mm_bat.replace(bak)
mm_bat.write_text(bat_text, encoding="utf-8") mm_bat.write_text(bat_text, encoding="utf-8")
# Validate that shim files were created correctly # Validate that the batch shim was created correctly
ps1_ok = mm_ps1.exists() and len(mm_ps1.read_text(encoding="utf-8")) > 0
bat_ok = mm_bat.exists() and len(mm_bat.read_text(encoding="utf-8")) > 0 bat_ok = mm_bat.exists() and len(mm_bat.read_text(encoding="utf-8")) > 0
if not bat_ok:
if not ps1_ok or not bat_ok: raise RuntimeError("Failed to create mm.bat shim")
raise RuntimeError(f"Failed to create shim files: mm.ps1={ps1_ok}, mm.bat={bat_ok}")
if args.debug: if args.debug:
print(f"DEBUG: Created mm.ps1 ({len(ps1_text)} bytes)")
print(f"DEBUG: Created mm.bat ({len(bat_text)} bytes)") print(f"DEBUG: Created mm.bat ({len(bat_text)} bytes)")
print(f"DEBUG: Repo path embedded in shims: {repo}") print(f"DEBUG: Repo path embedded in shims: {repo}")
print(f"DEBUG: Venv location: {repo}/.venv") print(f"DEBUG: Venv location: {repo}/.venv")
@@ -1117,26 +1077,13 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
print(f"DEBUG: Could not persist PATH to registry: {e}", file=sys.stderr) print(f"DEBUG: Could not persist PATH to registry: {e}", file=sys.stderr)
if not args.quiet: if not args.quiet:
print(f"Installed global launchers to: {user_bin}") print(f"Installed global launcher to: {user_bin}")
print(f"✓ mm.ps1 (PowerShell)") print(f"✓ mm.bat (Command Prompt and PowerShell)")
print(f"✓ mm.bat (Command Prompt)")
print() print()
print("You can now run 'mm' from any shell to start the application.") print("You can now run 'mm' from any terminal window.")
print() print(f"If 'mm' is not found, restart your terminal or reload PATH:")
print("📝 If 'mm' is not recognized, you may need to:") print(" PowerShell: $env:PATH = [Environment]::GetEnvironmentVariable('PATH','User') + ';' + [Environment]::GetEnvironmentVariable('PATH','Machine')")
print(f" 1. Restart your terminal") print(" CMD: path %PATH%")
print(f" 2. Or add '{user_bin}' manually to your PATH")
print()
print("🐛 Debug mode: Set MM_DEBUG=1 environment variable for detailed info:")
print(" PowerShell: $env:MM_DEBUG=1; mm --help")
print(" CMD: set MM_DEBUG=1 && mm --help")
if not args.quiet:
print(f"\nInstalled global launchers to: {user_bin}")
print(f"✓ mm.ps1 (PowerShell)")
print(f"✓ mm.bat (Command Prompt)")
print(f"\nYou can now run 'mm' from any terminal window.")
print(f"To use in the current terminal, reload your profile or run: $env:PATH = '{str_bin};' + $env:PATH")
else: else:
# POSIX # POSIX