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:
@@ -5,15 +5,15 @@ import { mkdir, mkdtemp } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import {
|
||||
isExistingDirectoryArg,
|
||||
classifyInvocation,
|
||||
isExistingDirectory,
|
||||
isPathLikeArg,
|
||||
openDesktopWithProject,
|
||||
shouldOpenProjectArg,
|
||||
} from "../src/commands/open.ts";
|
||||
} from "../src/classify.ts";
|
||||
import { openDesktopWithProject } from "../src/commands/open.ts";
|
||||
|
||||
console.log("📋 Phase 32: Open Project CLI Tests\n");
|
||||
|
||||
console.log(" Testing path-like detection exports...");
|
||||
console.log(" Testing path-like detection exports...");
|
||||
assert.equal(isPathLikeArg("."), true);
|
||||
assert.equal(isPathLikeArg("./app"), true);
|
||||
assert.equal(isPathLikeArg("/tmp/app"), true);
|
||||
@@ -28,21 +28,28 @@ await mkdir(existingProject);
|
||||
const originalCwd = process.cwd();
|
||||
process.chdir(join(existingProject, ".."));
|
||||
|
||||
assert.equal(isExistingDirectoryArg("project"), true);
|
||||
assert.equal(isExistingDirectory({ pathArg: "project", cwd: process.cwd() }), true);
|
||||
assert.equal(
|
||||
shouldOpenProjectArg({ arg: "project", knownCommands: new Set(["run", "status"]) }),
|
||||
true,
|
||||
classifyInvocation({
|
||||
argv: ["project"],
|
||||
knownCommands: new Set(["run", "status"]),
|
||||
cwd: process.cwd(),
|
||||
}).kind,
|
||||
"open-project",
|
||||
);
|
||||
assert.equal(
|
||||
shouldOpenProjectArg({ arg: "run", knownCommands: new Set(["run", "status"]) }),
|
||||
false,
|
||||
classifyInvocation({
|
||||
argv: ["run"],
|
||||
knownCommands: new Set(["run", "status"]),
|
||||
cwd: process.cwd(),
|
||||
}).kind,
|
||||
"cli",
|
||||
);
|
||||
|
||||
process.chdir(originalCwd);
|
||||
console.log(" ✅ existing directories open as projects, but known commands still win");
|
||||
|
||||
console.log(" Testing nonexistent project path errors...");
|
||||
const missingProject = join(tmpdir(), "paseo-open-project-missing");
|
||||
console.log(" Testing desktop CLI passthrough guard...");
|
||||
const originalWrite = process.stderr.write.bind(process.stderr);
|
||||
const stderrChunks: string[] = [];
|
||||
process.stderr.write = ((chunk: string | Uint8Array) => {
|
||||
@@ -52,13 +59,16 @@ process.stderr.write = ((chunk: string | Uint8Array) => {
|
||||
|
||||
const previousExitCode = process.exitCode;
|
||||
process.exitCode = undefined;
|
||||
const previousDesktopCli = process.env.PASEO_DESKTOP_CLI;
|
||||
process.env.PASEO_DESKTOP_CLI = "1";
|
||||
|
||||
await openDesktopWithProject(missingProject);
|
||||
await openDesktopWithProject(existingProject);
|
||||
|
||||
process.stderr.write = originalWrite;
|
||||
assert.equal(process.exitCode, 1);
|
||||
assert.match(stderrChunks.join(""), /Path does not exist:/);
|
||||
assert.match(stderrChunks.join(""), /desktop CLI passthrough mode/);
|
||||
process.exitCode = previousExitCode;
|
||||
console.log(" ✅ nonexistent paths fail with a helpful error");
|
||||
process.env.PASEO_DESKTOP_CLI = previousDesktopCli;
|
||||
console.log(" ✅ desktop CLI passthrough mode is rejected");
|
||||
|
||||
console.log("\n✅ Phase 32: Open Project CLI Tests PASSED");
|
||||
|
||||
Reference in New Issue
Block a user