Fix CLI routing: single classifier, open-project for cold & hot start

- Add classify.ts as the single source of truth for CLI invocation
  routing (discriminated union, derives known commands from Commander)
- Remove all hardcoded command lists and duplicate path detection logic
- Simplify shell wrappers to dumb pipes (zero classification)
- Fix hot-start: use `open -n -g -a` (VS Code pattern) so second-instance
  event fires when app is already running
- Fix cold-start race: pull-based IPC (getPendingOpenProject) so renderer
  fetches the pending path after React mounts, instead of push event that
  arrived before the listener existed
- Fix asar read corruption: unpack node-entrypoint-runner.js from asar
  (Node.js v24 in Electron 41 can't parse package.json inside asar)
- Strip ELECTRON_RUN_AS_NODE from env when spawning desktop app from CLI
This commit is contained in:
Mohamed Boudra
2026-04-04 19:21:12 +07:00
parent fefe260f0a
commit 43542ac858
16 changed files with 441 additions and 288 deletions
+3 -26
View File
@@ -31,30 +31,7 @@ else
exit 1
fi
case "${1:-}" in
./*|../*|.|..|/*|~|~/*)
case "$1" in
~) ARG_PATH="$HOME" ;;
~/*) ARG_PATH="$HOME/${1#\~/}" ;;
*) ARG_PATH="$1" ;;
esac
if RESOLVED_PATH=$(CDPATH= cd -- "$ARG_PATH" 2>/dev/null && pwd); then
:
elif command -v realpath >/dev/null 2>&1; then
RESOLVED_PATH=$(realpath "$ARG_PATH" 2>/dev/null || printf "%s" "$ARG_PATH")
else
RESOLVED_PATH=$ARG_PATH
fi
if [ ! -e "${RESOLVED_PATH}" ]; then
echo "Path does not exist: ${RESOLVED_PATH}" >&2
exit 1
fi
if [ ! -d "${RESOLVED_PATH}" ]; then
echo "Not a directory: ${RESOLVED_PATH}" >&2
exit 1
fi
exec "${APP_EXECUTABLE}" --open-project "${RESOLVED_PATH}"
;;
esac
RUNNER_PATH="${RESOURCES_DIR}/app.asar.unpacked/dist/daemon/node-entrypoint-runner.js"
CLI_ENTRYPOINT="${RESOURCES_DIR}/app.asar/node_modules/@getpaseo/cli/dist/index.js"
exec env PASEO_DESKTOP_CLI=1 "${APP_EXECUTABLE}" "$@"
exec env ELECTRON_RUN_AS_NODE=1 "${APP_EXECUTABLE}" "${RUNNER_PATH}" node-script "${CLI_ENTRYPOINT}" "$@"
+1 -28
View File
@@ -9,33 +9,6 @@ if not exist "%APP_EXECUTABLE%" (
exit /b 1
)
set "FIRST_ARG=%~1"
if "%FIRST_ARG%"=="." goto :open_project
if "%FIRST_ARG%"==".." goto :open_project
if "%FIRST_ARG:~0,2%"==".\" goto :open_project
if "%FIRST_ARG:~0,2%"=="./" goto :open_project
if "%FIRST_ARG:~0,3%"=="..\" goto :open_project
if "%FIRST_ARG:~0,3%"=="../" goto :open_project
if "%FIRST_ARG:~0,1%"=="\" goto :open_project
if "%FIRST_ARG:~0,1%"=="/" goto :open_project
if "%FIRST_ARG:~1,2%"==":\" goto :open_project
if "%FIRST_ARG:~1,2%"==":/" goto :open_project
goto :cli_mode
:open_project
for %%I in ("%~1") do set "RESOLVED_PATH=%%~fI"
if not exist "%RESOLVED_PATH%" (
echo Path does not exist: %RESOLVED_PATH% 1>&2
exit /b 1
)
if not exist "%RESOLVED_PATH%\NUL" (
echo Not a directory: %RESOLVED_PATH% 1>&2
exit /b 1
)
"%APP_EXECUTABLE%" --open-project "%RESOLVED_PATH%"
exit /b %errorlevel%
:cli_mode
set "ELECTRON_RUN_AS_NODE=1"
"%APP_EXECUTABLE%" "%RESOURCES_DIR%\app.asar\dist\daemon\node-entrypoint-runner.js" bare "%RESOURCES_DIR%\app.asar\node_modules\@getpaseo\cli\dist\index.js" %*
"%APP_EXECUTABLE%" "%RESOURCES_DIR%\app.asar.unpacked\dist\daemon\node-entrypoint-runner.js" node-script "%RESOURCES_DIR%\app.asar\node_modules\@getpaseo\cli\dist\index.js" %*
exit /b %errorlevel%