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:
2026-10-06 20:22:34 +07:00
parent f8acd5fc29
commit af014d9829
22 changed files with 151 additions and 27 deletions
+2 -2
View File
@@ -85,14 +85,14 @@ export function ConfirmModal({
>
<div
ref={panelRef}
className="relative w-full max-w-md rounded-xl border border-border bg-surface-1 shadow-xl shadow-black/40"
className="relative flex max-h-full w-full max-w-md flex-col rounded-xl border border-border bg-surface-1 shadow-xl shadow-black/40"
onClick={(e) => e.stopPropagation()}
role="dialog"
aria-modal="true"
aria-labelledby={titleId}
aria-describedby={message ? messageId : undefined}
>
<div className="flex items-start gap-3 p-5">
<div className="flex min-h-0 items-start gap-3 overflow-y-auto p-5">
{destructive && (
<div className="w-9 h-9 rounded-lg bg-status-danger/10 border border-status-danger/20 flex items-center justify-center flex-shrink-0">
<AlertTriangle className="w-4.5 h-4.5 text-status-danger" aria-hidden />
+1 -1
View File
@@ -208,7 +208,7 @@ function QuotaPanel({
onMouseLeave={onLeave}
onFocus={onEnter}
onBlur={onLeave}
className="fixed bottom-7 right-2 z-[9999] w-[19rem] max-w-[calc(100vw-1rem)] rounded-lg border border-border bg-surface-2 px-3 py-2.5 text-[11px] leading-snug text-fg-primary shadow-lg shadow-black/20"
className="fixed bottom-7 right-2 z-[9999] max-h-[calc(100vh-2.5rem)] w-[19rem] max-w-[calc(100vw-1rem)] overflow-y-auto rounded-lg border border-border bg-surface-2 px-3 py-2.5 text-[11px] leading-snug text-fg-primary shadow-lg shadow-black/20"
>
<div className="mb-2 font-semibold">{t("statusBar.quotaTitle")}</div>
{groups.map(([id, list]) => (
+2 -2
View File
@@ -330,7 +330,7 @@ export function UpdateNotifier() {
longest label is a whole sentence ("restarting the dashboard…"). */}
<div
ref={panelRef}
className="w-full max-w-2xl card shadow-2xl animate-slide-up overflow-hidden"
className="w-full max-w-2xl max-h-full flex flex-col card shadow-2xl animate-slide-up overflow-hidden"
>
{/* Header */}
<div className="flex items-start justify-between gap-3 px-5 py-4 border-b border-border">
@@ -370,7 +370,7 @@ export function UpdateNotifier() {
</div>
{/* Body */}
<div className="px-5 py-4 space-y-3">
<div className="min-h-0 overflow-y-auto px-5 py-4 space-y-3">
<p className="text-sm text-fg-secondary leading-relaxed">
{pluginManaged ? t("pluginAutoNote") : release ? t("releaseLead") : t("lead")}
</p>
@@ -67,7 +67,7 @@ export function ConfirmDeleteModal<
aria-modal="true"
aria-labelledby="cc-confirm-delete-title"
aria-describedby="cc-confirm-delete-body"
className="relative w-full max-w-lg rounded-xl border border-status-danger/40 bg-surface-1"
className="relative flex max-h-full w-full max-w-lg flex-col rounded-xl border border-status-danger/40 bg-surface-1"
onClick={(e) => e.stopPropagation()}
>
<div className="border-b border-border px-4 py-2.5 flex items-center gap-2">
@@ -76,7 +76,7 @@ export function ConfirmDeleteModal<
{t("edit.confirmDelete")}
</span>
</div>
<div className="p-4 space-y-3">
<div className="min-h-0 overflow-y-auto p-4 space-y-3">
<p id="cc-confirm-delete-body" className="text-xs text-fg-secondary leading-relaxed">
{t("edit.confirmDeleteBody")}
</p>
+1 -1
View File
@@ -1229,7 +1229,7 @@ function ClearDataDialog({
aria-modal="true"
aria-labelledby="clear-data-title"
aria-describedby="clear-data-body"
className="card w-full max-w-md space-y-4 border-status-danger/40 p-5"
className="card max-h-full w-full max-w-md space-y-4 overflow-y-auto border-status-danger/40 p-5"
onClick={(e) => e.stopPropagation()}
>
<h2
@@ -7233,7 +7233,7 @@ exports[`screen snapshots > Settings — about 1`] = `
<p
class="text-[10px] text-status-warning/90 mt-1"
>
UI build v2.5.2 (rebuild client to match)
UI build v2.5.3 (rebuild client to match)
</p>
</div>
<div