fix: v2.5.3 — Windows workspace folders, picker on top, no console flashes
A workspace could not be created on Windows: "cwd must be an absolute path" for D:\…, because createLane/canonicalCwd tested for a leading "/". - lanes.js: path.isAbsolute/path.resolve; canonicalCwd stops at any root (a missing drive looped forever); resolveLaneByCwd and /ensure accept "\" too - native-dialog.js: the Windows picker gets an invisible TopMost owner form, shown first — an ownerless dialog from the background server opened behind the browser, or hidden - windows-hide.js: every child process on Windows starts with windowsHide, required first by the server and the detached scripts (a console window flashed per git/npm call) - Confirm/update/clear-data modals and the quota panel scroll instead of overflowing a short window
This commit is contained in:
+12
-9
@@ -9,6 +9,7 @@
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
const path = require("node:path");
|
||||
const { db } = require("../db");
|
||||
const aiTools = require("./ai-tools");
|
||||
const {
|
||||
@@ -182,17 +183,18 @@ function normalizeTitle(value) {
|
||||
*/
|
||||
function canonicalCwd(cwd) {
|
||||
// A relative path must stay relative, so createLane still refuses it.
|
||||
if (!cwd.startsWith("/")) return cwd;
|
||||
const trimmed = cwd.replace(/\/+$/, "");
|
||||
// path.isAbsolute, not a leading "/": a Windows cwd is `D:\…`.
|
||||
if (!path.isAbsolute(cwd)) return cwd;
|
||||
const trimmed = path.resolve(cwd);
|
||||
// A path that does not exist yet resolves through its deepest existing
|
||||
// ancestor, so /link/new and /real/new still name the same lane.
|
||||
const path = require("node:path");
|
||||
const tail = [];
|
||||
for (let dir = trimmed; ; dir = path.dirname(dir)) {
|
||||
try {
|
||||
return path.join(require("node:fs").realpathSync.native(dir || "/"), ...tail);
|
||||
return path.join(require("node:fs").realpathSync.native(dir), ...tail);
|
||||
} catch {
|
||||
if (dir === "/" || !dir) return trimmed;
|
||||
// A root (`/`, `D:\` — a drive that does not exist) is its own dirname.
|
||||
if (path.dirname(dir) === dir) return trimmed;
|
||||
tail.unshift(path.basename(dir));
|
||||
}
|
||||
}
|
||||
@@ -210,7 +212,7 @@ function createLane({
|
||||
tool = "claude",
|
||||
router_profile = null,
|
||||
} = {}) {
|
||||
if (!cwd || typeof cwd !== "string" || !cwd.startsWith("/")) {
|
||||
if (!cwd || typeof cwd !== "string" || !path.isAbsolute(cwd)) {
|
||||
throw Object.assign(new Error("cwd must be an absolute path"), { code: "EBADCWD" });
|
||||
}
|
||||
validateKind(kind);
|
||||
@@ -603,12 +605,13 @@ function recoverInterruptedProvisioning() {
|
||||
*/
|
||||
function resolveLaneByCwd(cwd, tool) {
|
||||
if (!cwd || typeof cwd !== "string") return null;
|
||||
const target = cwd.replace(/\/+$/, "");
|
||||
// A Windows cwd ends in and nests under `\`.
|
||||
const target = cwd.replace(/[\\/]+$/, "");
|
||||
let best = null;
|
||||
for (const lane of listLanes()) {
|
||||
if (tool && lane.tool !== tool) continue;
|
||||
const base = lane.cwd.replace(/\/+$/, "");
|
||||
if (target === base || target.startsWith(`${base}/`)) {
|
||||
const base = lane.cwd.replace(/[\\/]+$/, "");
|
||||
if (target === base || target.startsWith(`${base}/`) || target.startsWith(base + path.sep)) {
|
||||
if (!best || base.length > best.cwd.length) best = lane;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user