# Release v1.6.7 - Changelog

Released: Unreleased

## Overview

Folder picker improvements for Windows: drive selector, home directory quick-nav, and error handling.

## Features

### FolderPicker: Windows drive navigation
- Added drive selector bar showing all available Windows drives (A–Z) so users can navigate between drives without typing paths
- Active drive is visually highlighted with the accent color
- Drive list is fetched from the server and only shown on Windows

### FolderPicker: Home directory shortcut
- Added a Home button in the path bar to quickly jump to the user's home directory (`~`)
- Server resolves `~` to the actual home directory path

## Improvements

### Feature ideas integrated into PLAN.md
- Moved 20 prioritized feature ideas from standalone `docs/FEATURE-IDEAS.md` into PLAN.md's "Planned Feature Details" section, organized by 5 priority tiers
- Deleted standalone file to keep planning centralized

## Fixes

### Windows CMD window flash and infinite restart loop
- Added `windowsHide: true` to **every** `spawn()`, `exec()`, `execSync()`, and `execAsync()` call across the entire server — previous fix only covered `pm2.js` and a few services, missing ~20 other spawn sites in routes, cos-runner, agents, scaffold, git cloner, brain, digital-twin, aiDetect, pm2Standardizer, taskConflict, platform, and detect
- Added `windowsHide: IS_WIN` to all 6 app definitions in `ecosystem.config.cjs` so PM2 daemon spawns PortOS processes without visible CMD windows
- Added `windowsHide: IS_WIN` to PM2 programmatic API calls (`pm2.start()` in `startApp` and `startWithCommand`) — these were the primary path for starting managed apps like sdlive
- Added `max_restarts: 10`, `min_uptime: '10s'`, and `restart_delay: 5000` to `startApp` and `startWithCommand` — previously had `autorestart: true` with no restart cap, causing infinite CMD window spawn loops when a managed app crashed on startup
- Fixed PM2 fork mode crash on Windows: when ecosystem configs use `script: 'npm'` (common pattern), PM2 resolves it to `npm.cmd` and tries to `require()` a batch file as JavaScript, causing `SyntaxError: Invalid or unexpected token` + infinite restart loop. On Windows, `startFromEcosystem` now loads the config, patches non-JS scripts with `interpreter: 'none'` (spawn mode), writes a temp config, and starts PM2 with it. Same fix applied to `startWithCommand` and `startApp`.
- Eliminated remaining CMD window flashes by bypassing `pm2.cmd` entirely: all PM2 CLI invocations (`jlist`, `logs`, `start`, `stop`, `restart`, `delete`) now run `node pm2/bin/pm2` directly instead of `spawn('pm2', {shell:true})` which created a `cmd.exe → pm2.cmd → node` chain where the intermediate `.cmd` batch file flashed a visible window. New `spawnPm2()` and `execPm2()` helpers in `pm2.js` are shared by logs, socket, detect, streamingDetect, and cos services.
- Updated all `pm2:*` npm scripts in package.json to use `node ./node_modules/pm2/bin/pm2` instead of bare `pm2` command, avoiding `pm2.cmd` batch file wrapper on Windows
- Fixed `autofixer/server.js` and `autofixer/ui.js` still using bare `pm2` commands via `exec()` and `spawn('pm2', {shell:true})` — these were the last remaining CMD window sources, now bypassed with local `node pm2/bin/pm2` pattern
- Rewrote `scripts/dev-start.js` to use `execFileSync` instead of `execSync` (avoids cmd.exe) with local PM2 binary resolution

### PM2 binary resolution fails when pm2 not globally installed
- `spawnPm2()` on macOS/Linux fell back to `spawn('pm2', ...)` which requires a global pm2 install — now always uses `node pm2/bin/pm2` via the local binary on all platforms
- Fixed `PM2_BIN` path using `require.resolve('pm2/package.json')` instead of a hardcoded relative path that broke when pm2 was hoisted to the root `node_modules`
- This caused all app status queries to silently fail, making every app appear "Offline"

### `npm run dev` uses PM2 instead of concurrently
- Changed `npm run dev` to `pm2 start ecosystem.config.cjs && pm2 logs` so dev mode uses the same PM2 process management as production
- Enabled file watching on `portos-server` for automatic restart on code changes
- Fixed Vite binary path in ecosystem config (`client/node_modules/vite` → `node_modules/vite`) since vite is hoisted to root
- Removed unused `concurrently` devDependency

### settings.test.js incorrect assertion
- Fixed test "should throw on invalid JSON in file" which expected `getSettings()` to reject on empty input — the actual implementation uses `safeJSONParse(raw, {})` which returns `{}` gracefully

### FolderPicker: Error state handling
- Directory load errors now display inline with a message and "Go to default directory" recovery button instead of silently failing
- Select button is disabled when no path is loaded
