@co0ontty/wand 1.43.0 → 1.43.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"commit": "
|
|
3
|
-
"builtAt": "2026-05-
|
|
4
|
-
"version": "1.43.
|
|
2
|
+
"commit": "968ab29608433dbadc5cd58b11323ba51f757d2d",
|
|
3
|
+
"builtAt": "2026-05-31T05:44:17.877Z",
|
|
4
|
+
"version": "1.43.2",
|
|
5
5
|
"channel": "stable"
|
|
6
6
|
}
|
|
@@ -1563,7 +1563,7 @@
|
|
|
1563
1563
|
|
|
1564
1564
|
// ===== 桌面:点 sidebar 外的空白处自动收起 =====
|
|
1565
1565
|
// 只对「临时打开但未锁定」的全尺寸侧栏生效;已锁定的 pinned 侧栏
|
|
1566
|
-
// 必须保持常驻,除非用户明确点 X
|
|
1566
|
+
// 必须保持常驻,除非用户明确点 X 关闭。
|
|
1567
1567
|
// - 仅 desktop + 未锁定 + 全尺寸(非窄条)+ 已打开 时生效
|
|
1568
1568
|
// - 窄条态不触发(窄条本来就是稳定常驻形态)
|
|
1569
1569
|
// - 手机端由 .drawer-backdrop 元素自己接住点击,不在这里重复处理
|
|
@@ -1588,7 +1588,7 @@
|
|
|
1588
1588
|
".folder-picker-dropdown, .path-suggestions, " +
|
|
1589
1589
|
".permission-prompt-overlay, .restart-overlay"
|
|
1590
1590
|
)) return;
|
|
1591
|
-
|
|
1591
|
+
closeTransientSessionsDrawer();
|
|
1592
1592
|
}, true);
|
|
1593
1593
|
|
|
1594
1594
|
renderBootLoading();
|
|
@@ -1783,6 +1783,7 @@
|
|
|
1783
1783
|
var terminalInfo = selectedSession ? (selectedSession.mode + " | " + selectedSession.status) : "点击上方「新对话」开始";
|
|
1784
1784
|
var currentDraft = state.selectedId ? (state.drafts[state.selectedId] || "") : "";
|
|
1785
1785
|
var drawerClass = state.sessionsDrawerOpen ? " open" : "";
|
|
1786
|
+
var backdropClass = shouldShowSessionsBackdrop() ? " open" : "";
|
|
1786
1787
|
var preferredTool = getComposerTool();
|
|
1787
1788
|
var composerMode = getSafeModeForTool(preferredTool, state.chatMode);
|
|
1788
1789
|
|
|
@@ -1796,7 +1797,7 @@
|
|
|
1796
1797
|
var collapsedCls = isCollapsed ? ' sidebar-collapsed' : '';
|
|
1797
1798
|
var sidebarCollapsedCls = isCollapsed ? ' collapsed' : '';
|
|
1798
1799
|
return '<div class="app-container">' +
|
|
1799
|
-
'<div id="sessions-drawer-backdrop" class="drawer-backdrop' +
|
|
1800
|
+
'<div id="sessions-drawer-backdrop" class="drawer-backdrop' + backdropClass + '"></div>' +
|
|
1800
1801
|
'<div class="main-layout' + (state.sessionsDrawerOpen ? ' sidebar-open' : '') + (isAnchored ? ' sidebar-pinned' : '') + collapsedCls + '">' +
|
|
1801
1802
|
'<aside id="sessions-drawer" class="sidebar' + drawerClass + (isAnchored ? ' pinned' : '') + sidebarCollapsedCls + '">' +
|
|
1802
1803
|
'<div class="sidebar-header">' +
|
|
@@ -2245,7 +2246,11 @@
|
|
|
2245
2246
|
var quickCommitDragState = null;
|
|
2246
2247
|
|
|
2247
2248
|
function normalizeQuickCommitAction(value) {
|
|
2248
|
-
if (
|
|
2249
|
+
if (
|
|
2250
|
+
value === "commit-tag" ||
|
|
2251
|
+
value === "commit-tag-push" ||
|
|
2252
|
+
value === "commit-push"
|
|
2253
|
+
) return value;
|
|
2249
2254
|
return "commit";
|
|
2250
2255
|
}
|
|
2251
2256
|
|
|
@@ -2258,7 +2263,7 @@
|
|
|
2258
2263
|
verb: "提交、打 Tag 并推送",
|
|
2259
2264
|
withTag: true,
|
|
2260
2265
|
push: true,
|
|
2261
|
-
tone: "
|
|
2266
|
+
tone: "all",
|
|
2262
2267
|
};
|
|
2263
2268
|
}
|
|
2264
2269
|
if (action === "commit-tag") {
|
|
@@ -2271,6 +2276,16 @@
|
|
|
2271
2276
|
tone: "tag",
|
|
2272
2277
|
};
|
|
2273
2278
|
}
|
|
2279
|
+
if (action === "commit-push") {
|
|
2280
|
+
return {
|
|
2281
|
+
action: action,
|
|
2282
|
+
label: "Commit + Push",
|
|
2283
|
+
verb: "提交并推送",
|
|
2284
|
+
withTag: false,
|
|
2285
|
+
push: true,
|
|
2286
|
+
tone: "push",
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2274
2289
|
return {
|
|
2275
2290
|
action: "commit",
|
|
2276
2291
|
label: "Commit",
|
|
@@ -2281,16 +2296,11 @@
|
|
|
2281
2296
|
};
|
|
2282
2297
|
}
|
|
2283
2298
|
|
|
2284
|
-
function getQuickCommitActionFromRatio(ratio) {
|
|
2285
|
-
if (ratio >= 0.74) return "commit-tag-push";
|
|
2286
|
-
if (ratio >= 0.38) return "commit-tag";
|
|
2287
|
-
return "commit";
|
|
2288
|
-
}
|
|
2289
|
-
|
|
2290
2299
|
function openQuickCommitModal() {
|
|
2291
2300
|
if (!state.selectedId) return;
|
|
2292
2301
|
state.quickCommitOpen = true;
|
|
2293
2302
|
state.quickCommitSubmitting = false;
|
|
2303
|
+
state.quickCommitAutoGenerating = false;
|
|
2294
2304
|
state.quickCommitError = "";
|
|
2295
2305
|
state.quickCommitForm = {
|
|
2296
2306
|
customMessage: "",
|
|
@@ -2416,121 +2426,194 @@
|
|
|
2416
2426
|
attachQuickCommitDrag();
|
|
2417
2427
|
}
|
|
2418
2428
|
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
var
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
if (
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
for (var i = 0; i < stages.length; i++) {
|
|
2440
|
-
var stageAction = stages[i].getAttribute("data-qc-stage");
|
|
2441
|
-
var passed = order[stageAction] <= order[action];
|
|
2442
|
-
stages[i].classList.toggle("is-active", stageAction === action);
|
|
2443
|
-
stages[i].classList.toggle("is-passed", passed);
|
|
2444
|
-
}
|
|
2429
|
+
// Compose the final action from which stations the orb attached during the drag.
|
|
2430
|
+
// Commit is implicit — every action starts with a commit.
|
|
2431
|
+
function composeOrbAction(attached) {
|
|
2432
|
+
var hasTag = !!(attached && attached.tag);
|
|
2433
|
+
var hasPush = !!(attached && attached.push);
|
|
2434
|
+
if (hasTag && hasPush) return "commit-tag-push";
|
|
2435
|
+
if (hasTag) return "commit-tag";
|
|
2436
|
+
if (hasPush) return "commit-push";
|
|
2437
|
+
return "commit";
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
// How close (px) the pointer must come to a loose chip's home before that chip is
|
|
2441
|
+
// magnetically picked up into the chip currently being dragged.
|
|
2442
|
+
var QC_DOCK_PICKUP_R = 58;
|
|
2443
|
+
|
|
2444
|
+
// A plain tap on a chip fires its own action directly (tag/push imply a commit too).
|
|
2445
|
+
function qcChipTapAction(id) {
|
|
2446
|
+
if (id === "tag") return "commit-tag";
|
|
2447
|
+
if (id === "push") return "commit-push";
|
|
2448
|
+
return "commit";
|
|
2445
2449
|
}
|
|
2446
2450
|
|
|
2451
|
+
// Magnetic dock: three loose chips (Commit / Tag / Push) rest in a field. Grab ANY chip and
|
|
2452
|
+
// drag it; whenever the pointer brushes another chip it sticks to the travelling cluster and
|
|
2453
|
+
// moves along (ordered Commit → Tag → Push). Fling the cluster into the right-side ▶ pad to
|
|
2454
|
+
// fire compose(members) — a commit is always implied. Release anywhere else and every chip
|
|
2455
|
+
// springs back home. A plain tap (no drag) on a chip fires that chip's own action.
|
|
2447
2456
|
function attachQuickCommitDrag() {
|
|
2448
|
-
var
|
|
2449
|
-
var
|
|
2450
|
-
|
|
2451
|
-
|
|
2457
|
+
var field = document.getElementById("qc-dock-field");
|
|
2458
|
+
var stage = document.getElementById("qc-dock-stage");
|
|
2459
|
+
var launch = document.getElementById("qc-dock-launch");
|
|
2460
|
+
var cluster = document.getElementById("qc-dock-cluster");
|
|
2461
|
+
if (!field || !stage || !launch || !cluster) return;
|
|
2462
|
+
|
|
2463
|
+
var ORDER = ["commit", "tag", "push"];
|
|
2464
|
+
var chips = {};
|
|
2465
|
+
ORDER.forEach(function(id) { chips[id] = field.querySelector('[data-chip="' + id + '"]'); });
|
|
2466
|
+
if (!chips.commit || !chips.tag || !chips.push) return;
|
|
2467
|
+
|
|
2468
|
+
function cw(id) { return chips[id] ? chips[id].offsetWidth : 90; }
|
|
2469
|
+
function chH() { return chips.commit ? chips.commit.offsetHeight : 38; }
|
|
2470
|
+
|
|
2471
|
+
// Resting (home) positions — the three chips in one centered row.
|
|
2472
|
+
function homePositions() {
|
|
2473
|
+
var fw = field.clientWidth, fh = field.clientHeight, H = chH();
|
|
2474
|
+
var gap = 14;
|
|
2475
|
+
var total = ORDER.reduce(function(s, id) { return s + cw(id); }, 0) + (ORDER.length - 1) * gap;
|
|
2476
|
+
var x = Math.max(8, (fw - total) / 2);
|
|
2477
|
+
var y = (fh - H) / 2;
|
|
2478
|
+
var pos = {};
|
|
2479
|
+
ORDER.forEach(function(id) { pos[id] = { x: x, y: y }; x += cw(id) + gap; });
|
|
2480
|
+
return pos;
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
var home = {};
|
|
2484
|
+
function placeChip(id, x, y) {
|
|
2485
|
+
if (chips[id]) chips[id].style.transform = "translate(" + x.toFixed(1) + "px," + y.toFixed(1) + "px)";
|
|
2486
|
+
}
|
|
2487
|
+
function layoutHome(animated) {
|
|
2488
|
+
home = homePositions();
|
|
2489
|
+
ORDER.forEach(function(id) {
|
|
2490
|
+
chips[id].classList.toggle("qc-chip--anim", !!animated);
|
|
2491
|
+
placeChip(id, home[id].x, home[id].y);
|
|
2492
|
+
});
|
|
2493
|
+
}
|
|
2494
|
+
layoutHome(false);
|
|
2495
|
+
|
|
2496
|
+
var drag = null;
|
|
2497
|
+
|
|
2498
|
+
// Lay the current cluster members in a tight row centered on (cx, cy) within the field.
|
|
2499
|
+
function layoutCluster(members, cx, cy) {
|
|
2500
|
+
var H = chH(), gapIn = 5;
|
|
2501
|
+
var ids = ORDER.filter(function(id) { return members.indexOf(id) >= 0; });
|
|
2502
|
+
var total = ids.reduce(function(s, id) { return s + cw(id); }, 0) + Math.max(0, ids.length - 1) * gapIn;
|
|
2503
|
+
var fh = field.clientHeight;
|
|
2504
|
+
var x = cx - total / 2;
|
|
2505
|
+
var y = Math.max(2, Math.min(fh - H - 2, cy - H / 2));
|
|
2506
|
+
ids.forEach(function(id) { placeChip(id, x, y); x += cw(id) + gapIn; });
|
|
2507
|
+
return { x: cx - total / 2 - 7, y: y - 7, w: total + 14, h: H + 14 };
|
|
2508
|
+
}
|
|
2509
|
+
function showCluster(box) {
|
|
2510
|
+
cluster.classList.add("is-active");
|
|
2511
|
+
cluster.style.transform = "translate(" + box.x.toFixed(1) + "px," + box.y.toFixed(1) + "px)";
|
|
2512
|
+
cluster.style.width = box.w.toFixed(1) + "px";
|
|
2513
|
+
cluster.style.height = box.h.toFixed(1) + "px";
|
|
2514
|
+
}
|
|
2515
|
+
function hideCluster() { cluster.classList.remove("is-active"); }
|
|
2516
|
+
|
|
2517
|
+
function clusterAction(members) {
|
|
2518
|
+
return composeOrbAction({
|
|
2519
|
+
commit: true,
|
|
2520
|
+
tag: members.indexOf("tag") >= 0,
|
|
2521
|
+
push: members.indexOf("push") >= 0,
|
|
2522
|
+
});
|
|
2523
|
+
}
|
|
2524
|
+
function setLaunchLabel(t) {
|
|
2525
|
+
var l = document.getElementById("qc-dock-launch-label");
|
|
2526
|
+
if (l) l.textContent = t;
|
|
2527
|
+
}
|
|
2528
|
+
function pointInLaunch(x, y) {
|
|
2529
|
+
var r = launch.getBoundingClientRect();
|
|
2530
|
+
return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;
|
|
2531
|
+
}
|
|
2452
2532
|
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2533
|
+
function onDown(id) {
|
|
2534
|
+
return function(e) {
|
|
2535
|
+
if (chips[id].disabled || isQuickCommitOpInFlight()) return;
|
|
2536
|
+
drag = { anchor: id, pointerId: e.pointerId, startX: e.clientX, startY: e.clientY, moved: false, members: [id] };
|
|
2537
|
+
ORDER.forEach(function(m) { chips[m].classList.remove("qc-chip--anim"); });
|
|
2538
|
+
chips[id].classList.add("is-grabbing");
|
|
2539
|
+
try { chips[id].setPointerCapture(e.pointerId); } catch (err) { /* ignored */ }
|
|
2540
|
+
stage.classList.add("is-dragging");
|
|
2541
|
+
e.preventDefault();
|
|
2461
2542
|
};
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
e.
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
var
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2543
|
+
}
|
|
2544
|
+
function onMove(e) {
|
|
2545
|
+
if (!drag || drag.pointerId !== e.pointerId) return;
|
|
2546
|
+
if (Math.abs(e.clientX - drag.startX) > 3 || Math.abs(e.clientY - drag.startY) > 3) drag.moved = true;
|
|
2547
|
+
var fr = field.getBoundingClientRect();
|
|
2548
|
+
var fx = e.clientX - fr.left, fy = e.clientY - fr.top;
|
|
2549
|
+
// magnetic pickup: any loose chip whose home center is near the pointer joins the cluster.
|
|
2550
|
+
ORDER.forEach(function(id) {
|
|
2551
|
+
if (drag.members.indexOf(id) >= 0) return;
|
|
2552
|
+
var hx = home[id].x + cw(id) / 2, hy = home[id].y + chH() / 2;
|
|
2553
|
+
var dx = fx - hx, dy = fy - hy;
|
|
2554
|
+
if (Math.sqrt(dx * dx + dy * dy) < QC_DOCK_PICKUP_R) {
|
|
2555
|
+
drag.members.push(id);
|
|
2556
|
+
chips[id].classList.remove("qc-chip--anim");
|
|
2557
|
+
chips[id].classList.add("is-attached");
|
|
2558
|
+
}
|
|
2559
|
+
});
|
|
2560
|
+
var box = layoutCluster(drag.members, fx, fy);
|
|
2561
|
+
var hot = pointInLaunch(e.clientX, e.clientY);
|
|
2562
|
+
stage.setAttribute("data-hot", hot ? "1" : "0");
|
|
2563
|
+
stage.setAttribute("data-action", clusterAction(drag.members));
|
|
2564
|
+
if (drag.members.length > 1) showCluster(box); else hideCluster();
|
|
2565
|
+
setLaunchLabel(hot ? "松手执行" : "提交");
|
|
2566
|
+
}
|
|
2567
|
+
function endDrag(e, cancelled) {
|
|
2568
|
+
if (!drag || drag.pointerId !== e.pointerId) return;
|
|
2569
|
+
var cur = drag; drag = null;
|
|
2570
|
+
stage.classList.remove("is-dragging");
|
|
2571
|
+
stage.setAttribute("data-hot", "0");
|
|
2572
|
+
setLaunchLabel("提交");
|
|
2573
|
+
hideCluster();
|
|
2574
|
+
ORDER.forEach(function(m) { chips[m].classList.remove("is-grabbing", "is-attached"); });
|
|
2575
|
+
try { chips[cur.anchor].releasePointerCapture(cur.pointerId); } catch (err) { /* ignored */ }
|
|
2576
|
+
|
|
2577
|
+
if (!cancelled && !cur.moved) {
|
|
2578
|
+
// plain tap → fire this chip's own action
|
|
2579
|
+
submitQuickCommit(qcChipTapAction(cur.anchor));
|
|
2487
2580
|
return;
|
|
2488
2581
|
}
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
2493
|
-
};
|
|
2494
|
-
var onPointerUp = function(e) {
|
|
2495
|
-
if (!quickCommitDragState || quickCommitDragState.pointerId !== e.pointerId) return;
|
|
2496
|
-
finish(e, false);
|
|
2497
|
-
};
|
|
2498
|
-
var onPointerCancel = function(e) {
|
|
2499
|
-
if (!quickCommitDragState || quickCommitDragState.pointerId !== e.pointerId) return;
|
|
2500
|
-
finish(e, true);
|
|
2501
|
-
};
|
|
2502
|
-
var onKeyDown = function(e) {
|
|
2503
|
-
if (knob.disabled || isQuickCommitOpInFlight()) return;
|
|
2504
|
-
if (e.key === "ArrowRight") {
|
|
2505
|
-
e.preventDefault();
|
|
2506
|
-
var next = state.quickCommitDragAction === "commit"
|
|
2507
|
-
? "commit-tag"
|
|
2508
|
-
: (state.quickCommitDragAction === "commit-tag" ? "commit-tag-push" : "commit-tag-push");
|
|
2509
|
-
updateQuickCommitDragVisual(next);
|
|
2510
|
-
} else if (e.key === "ArrowLeft") {
|
|
2511
|
-
e.preventDefault();
|
|
2512
|
-
var prev = state.quickCommitDragAction === "commit-tag-push"
|
|
2513
|
-
? "commit-tag"
|
|
2514
|
-
: (state.quickCommitDragAction === "commit-tag" ? "commit" : "commit");
|
|
2515
|
-
updateQuickCommitDragVisual(prev);
|
|
2516
|
-
} else if (e.key === "Enter" || e.key === " ") {
|
|
2517
|
-
e.preventDefault();
|
|
2518
|
-
submitQuickCommit(state.quickCommitDragAction || "commit");
|
|
2582
|
+
if (!cancelled && pointInLaunch(e.clientX, e.clientY)) {
|
|
2583
|
+
submitQuickCommit(clusterAction(cur.members));
|
|
2584
|
+
return;
|
|
2519
2585
|
}
|
|
2520
|
-
|
|
2586
|
+
// released loose → everyone springs back home
|
|
2587
|
+
stage.setAttribute("data-action", "commit");
|
|
2588
|
+
layoutHome(true);
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
var onResize = function() { if (state.quickCommitOpen && !drag) layoutHome(false); };
|
|
2592
|
+
window.addEventListener("resize", onResize);
|
|
2593
|
+
|
|
2594
|
+
ORDER.forEach(function(id) {
|
|
2595
|
+
var c = chips[id];
|
|
2596
|
+
c.addEventListener("pointerdown", onDown(id));
|
|
2597
|
+
c.addEventListener("pointermove", onMove);
|
|
2598
|
+
c.addEventListener("pointerup", function(e) { endDrag(e, false); });
|
|
2599
|
+
c.addEventListener("pointercancel", function(e) { endDrag(e, true); });
|
|
2600
|
+
c.addEventListener("keydown", function(e) {
|
|
2601
|
+
if (c.disabled || isQuickCommitOpInFlight()) return;
|
|
2602
|
+
if (e.key === "Enter" || e.key === " " || e.key === "Spacebar") {
|
|
2603
|
+
e.preventDefault();
|
|
2604
|
+
submitQuickCommit(qcChipTapAction(id));
|
|
2605
|
+
}
|
|
2606
|
+
});
|
|
2607
|
+
});
|
|
2608
|
+
|
|
2609
|
+
launch.addEventListener("click", function() {
|
|
2610
|
+
if (launch.disabled || isQuickCommitOpInFlight() || drag) return;
|
|
2611
|
+
submitQuickCommit("commit");
|
|
2612
|
+
});
|
|
2521
2613
|
|
|
2522
|
-
knob.addEventListener("pointerdown", onPointerDown);
|
|
2523
|
-
knob.addEventListener("pointermove", onPointerMove);
|
|
2524
|
-
knob.addEventListener("pointerup", onPointerUp);
|
|
2525
|
-
knob.addEventListener("pointercancel", onPointerCancel);
|
|
2526
|
-
knob.addEventListener("keydown", onKeyDown);
|
|
2527
2614
|
quickCommitDragCleanup = function() {
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
knob.removeEventListener("pointerup", onPointerUp);
|
|
2531
|
-
knob.removeEventListener("pointercancel", onPointerCancel);
|
|
2532
|
-
knob.removeEventListener("keydown", onKeyDown);
|
|
2533
|
-
quickCommitDragState = null;
|
|
2615
|
+
window.removeEventListener("resize", onResize);
|
|
2616
|
+
drag = null;
|
|
2534
2617
|
};
|
|
2535
2618
|
}
|
|
2536
2619
|
|
|
@@ -2592,11 +2675,9 @@
|
|
|
2592
2675
|
var withTag = meta.withTag;
|
|
2593
2676
|
var userTag = withTag ? (form.tag || "").trim() : "";
|
|
2594
2677
|
var message = (form.customMessage || "").trim();
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
return;
|
|
2599
|
-
}
|
|
2678
|
+
// Auto-generate flow: empty commit message → ask backend to write one (autoMessage:true).
|
|
2679
|
+
// Empty tag (when withTag) → ask backend to derive one (autoTag:true). Both go in one round-trip.
|
|
2680
|
+
var autoMessage = !message;
|
|
2600
2681
|
var before = {
|
|
2601
2682
|
branch: (state.gitStatus || {}).branch || "",
|
|
2602
2683
|
commitHash: (state.gitStatus || {}).lastCommit && (state.gitStatus || {}).lastCommit.shortHash
|
|
@@ -2608,13 +2689,14 @@
|
|
|
2608
2689
|
tag: (state.gitStatus || {}).latestTag || "",
|
|
2609
2690
|
};
|
|
2610
2691
|
var payload = {
|
|
2611
|
-
autoMessage:
|
|
2612
|
-
customMessage: message,
|
|
2692
|
+
autoMessage: autoMessage,
|
|
2693
|
+
customMessage: autoMessage ? "" : message,
|
|
2613
2694
|
tag: userTag,
|
|
2614
2695
|
autoTag: !!(withTag && !userTag),
|
|
2615
2696
|
push: !!meta.push
|
|
2616
2697
|
};
|
|
2617
2698
|
state.quickCommitSubmitting = true;
|
|
2699
|
+
state.quickCommitAutoGenerating = autoMessage || payload.autoTag;
|
|
2618
2700
|
state.quickCommitError = "";
|
|
2619
2701
|
state.quickCommitPushError = "";
|
|
2620
2702
|
state.quickCommitResult = null;
|
|
@@ -2668,6 +2750,7 @@
|
|
|
2668
2750
|
})
|
|
2669
2751
|
.finally(function() {
|
|
2670
2752
|
state.quickCommitSubmitting = false;
|
|
2753
|
+
state.quickCommitAutoGenerating = false;
|
|
2671
2754
|
if (state.quickCommitOpen) rerenderQuickCommitModal();
|
|
2672
2755
|
});
|
|
2673
2756
|
}
|
|
@@ -2790,23 +2873,40 @@
|
|
|
2790
2873
|
}
|
|
2791
2874
|
|
|
2792
2875
|
function renderQuickCommitDragControl(hasChanges) {
|
|
2793
|
-
var action = normalizeQuickCommitAction(state.quickCommitDragAction || "commit");
|
|
2794
|
-
var meta = getQuickCommitActionMeta(action);
|
|
2795
2876
|
var disabled = !hasChanges || isQuickCommitOpInFlight();
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
'<div class="qc-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2877
|
+
// Busy panel — replaces the dock entirely while the request is in flight.
|
|
2878
|
+
if (state.quickCommitSubmitting) {
|
|
2879
|
+
var busyLabel = state.quickCommitAutoGenerating ? "AI 生成 + 提交中…" : "执行中…";
|
|
2880
|
+
return '<div class="qc-dock-wrap">' +
|
|
2881
|
+
'<div class="qc-dock-busy" role="status"><span class="qc-dock-busy-dot"></span>' + escapeHtml(busyLabel) + '</div>' +
|
|
2882
|
+
'</div>';
|
|
2883
|
+
}
|
|
2884
|
+
function chip(id, label) {
|
|
2885
|
+
return '<button type="button" class="qc-chip qc-chip--' + id + '"' +
|
|
2886
|
+
' data-chip="' + id + '"' + (disabled ? ' disabled' : '') + '>' +
|
|
2887
|
+
'<span class="qc-chip-dot" aria-hidden="true"></span>' +
|
|
2888
|
+
'<span class="qc-chip-label">' + label + '</span>' +
|
|
2889
|
+
'</button>';
|
|
2890
|
+
}
|
|
2891
|
+
var hint = disabled
|
|
2892
|
+
? (!hasChanges ? "工作区干净,无可提交" : "")
|
|
2893
|
+
: "拖一个去碰另一个会黏在一起 · 整串丢进 ▶ 执行组合 · 单击直接执行该项";
|
|
2894
|
+
return '<div class="qc-dock-wrap"' + (disabled ? ' data-disabled="1"' : '') + '>' +
|
|
2895
|
+
'<div id="qc-dock-stage" class="qc-dock-stage" data-action="commit" data-hot="0">' +
|
|
2896
|
+
'<div id="qc-dock-field" class="qc-dock-field">' +
|
|
2897
|
+
'<div id="qc-dock-cluster" class="qc-dock-cluster" aria-hidden="true"></div>' +
|
|
2898
|
+
chip("commit", "Commit") +
|
|
2899
|
+
chip("tag", "Tag") +
|
|
2900
|
+
chip("push", "Push") +
|
|
2804
2901
|
'</div>' +
|
|
2805
|
-
'<button id="
|
|
2806
|
-
'<span
|
|
2807
|
-
|
|
2902
|
+
'<button type="button" id="qc-dock-launch" class="qc-dock-launch"' + (disabled ? ' disabled' : '') + ' aria-label="执行提交">' +
|
|
2903
|
+
'<span class="qc-dock-launch-arrow" aria-hidden="true">' +
|
|
2904
|
+
'<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h12M13 6l6 6-6 6"/></svg>' +
|
|
2905
|
+
'</span>' +
|
|
2906
|
+
'<span id="qc-dock-launch-label" class="qc-dock-launch-label">提交</span>' +
|
|
2808
2907
|
'</button>' +
|
|
2809
2908
|
'</div>' +
|
|
2909
|
+
'<div class="qc-dock-hint">' + escapeHtml(hint) + '</div>' +
|
|
2810
2910
|
'</div>';
|
|
2811
2911
|
}
|
|
2812
2912
|
|
|
@@ -4040,6 +4140,10 @@
|
|
|
4040
4140
|
return window.innerWidth <= 768;
|
|
4041
4141
|
}
|
|
4042
4142
|
|
|
4143
|
+
function shouldShowSessionsBackdrop() {
|
|
4144
|
+
return !!state.sessionsDrawerOpen && (isMobileLayout() || !state.sidebarPinned);
|
|
4145
|
+
}
|
|
4146
|
+
|
|
4043
4147
|
function setFilePanelOpen(nextOpen) {
|
|
4044
4148
|
state.filePanelOpen = nextOpen;
|
|
4045
4149
|
try {
|
|
@@ -9722,7 +9826,7 @@
|
|
|
9722
9826
|
drawer.classList.toggle("open", state.sessionsDrawerOpen);
|
|
9723
9827
|
}
|
|
9724
9828
|
if (backdrop) {
|
|
9725
|
-
backdrop.classList.toggle("open",
|
|
9829
|
+
backdrop.classList.toggle("open", shouldShowSessionsBackdrop());
|
|
9726
9830
|
}
|
|
9727
9831
|
if (mainLayout) {
|
|
9728
9832
|
mainLayout.classList.toggle("sidebar-open", state.sessionsDrawerOpen);
|
|
@@ -9737,17 +9841,14 @@
|
|
|
9737
9841
|
function toggleSessionsDrawer() {
|
|
9738
9842
|
var isMobile = isMobileLayout();
|
|
9739
9843
|
if (!isMobile) {
|
|
9740
|
-
//
|
|
9741
|
-
|
|
9742
|
-
var willOpen = !state.sidebarPinned;
|
|
9743
|
-
state.sidebarPinned = willOpen;
|
|
9844
|
+
// 桌面:hamburger 只负责临时打开/关闭;锁定常驻由图钉按钮控制。
|
|
9845
|
+
var willOpen = state.sidebarPinned ? false : !state.sessionsDrawerOpen;
|
|
9744
9846
|
state.sessionsDrawerOpen = willOpen;
|
|
9745
9847
|
if (willOpen) {
|
|
9746
9848
|
// 桌面重新呼出默认回到全尺寸;窄条形态需用户主动点 collapse 按钮切换。
|
|
9747
9849
|
state.sidebarCollapsed = false;
|
|
9748
9850
|
writeStoredBoolean("wand-sidebar-collapsed", false);
|
|
9749
9851
|
}
|
|
9750
|
-
writeStoredBoolean("wand-sidebar-pinned", willOpen);
|
|
9751
9852
|
writeStoredBoolean("wand-sidebar-open", state.sessionsDrawerOpen);
|
|
9752
9853
|
updateLayoutState();
|
|
9753
9854
|
scheduleTerminalRefitAfterPaddingTransition();
|
|
@@ -9788,6 +9889,19 @@
|
|
|
9788
9889
|
updateLayoutState();
|
|
9789
9890
|
}
|
|
9790
9891
|
|
|
9892
|
+
function closeTransientSessionsDrawer() {
|
|
9893
|
+
if (isMobileLayout()) {
|
|
9894
|
+
closeSessionsDrawer();
|
|
9895
|
+
return;
|
|
9896
|
+
}
|
|
9897
|
+
if (state.sidebarPinned || state.sidebarCollapsed || !state.sessionsDrawerOpen) return;
|
|
9898
|
+
closeSwipedItem();
|
|
9899
|
+
state.sessionsDrawerOpen = false;
|
|
9900
|
+
writeStoredBoolean("wand-sidebar-open", false);
|
|
9901
|
+
updateLayoutState();
|
|
9902
|
+
scheduleTerminalRefitAfterPaddingTransition();
|
|
9903
|
+
}
|
|
9904
|
+
|
|
9791
9905
|
// 把"浮在内容上的 drawer/backdrop"关掉,但保留桌面常驻栏与窄条形态。
|
|
9792
9906
|
// 用法:从 input focus / send 按钮 / 选中会话 / 新建会话回调里调,这些场
|
|
9793
9907
|
// 景只想避免遮罩挡住内容,并不想撤掉用户主动开启的常驻侧栏。
|