Files
paseo/packages/cli/src/classify.ts
Mohamed Boudra 43542ac858 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
2026-04-04 19:21:12 +07:00

71 lines
1.6 KiB
TypeScript

import { existsSync, statSync } from "node:fs";
import { homedir } from "node:os";
import path from "node:path";
export type CliInvocation =
| { kind: "cli"; argv: string[] }
| { kind: "open-project"; resolvedPath: string };
export function isPathLikeArg(arg: string): boolean {
return (
arg === "." ||
arg === ".." ||
arg.startsWith("./") ||
arg.startsWith("../") ||
arg.startsWith("/") ||
arg === "~" ||
arg.startsWith("~/") ||
/^[A-Za-z]:[\\/]/.test(arg)
);
}
export function expandUserPath(inputPath: string): string {
if (inputPath === "~") {
return homedir();
}
if (inputPath.startsWith("~/")) {
return path.join(homedir(), inputPath.slice(2));
}
return inputPath;
}
export function isExistingDirectory(input: { pathArg: string; cwd: string }): boolean {
const resolvedPath = path.resolve(input.cwd, expandUserPath(input.pathArg));
if (!existsSync(resolvedPath)) {
return false;
}
return statSync(resolvedPath).isDirectory();
}
export function classifyInvocation(input: {
argv: string[];
knownCommands: ReadonlySet<string>;
cwd: string;
}): CliInvocation {
const [firstArg] = input.argv;
if (!firstArg) {
return { kind: "cli", argv: input.argv };
}
if (firstArg.startsWith("-")) {
return { kind: "cli", argv: input.argv };
}
if (input.knownCommands.has(firstArg)) {
return { kind: "cli", argv: input.argv };
}
if (isExistingDirectory({ pathArg: firstArg, cwd: input.cwd })) {
return {
kind: "open-project",
resolvedPath: path.resolve(input.cwd, expandUserPath(firstArg)),
};
}
return { kind: "cli", argv: input.argv };
}