@co0ontty/wand 1.22.0 → 1.23.0
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/cli.js +111 -2
- package/dist/pidfile.d.ts +38 -0
- package/dist/pidfile.js +117 -0
- package/dist/tui/attach.d.ts +18 -0
- package/dist/tui/attach.js +306 -0
- package/dist/tui/commands.d.ts +60 -0
- package/dist/tui/commands.js +505 -0
- package/dist/tui/index.js +171 -3
- package/dist/tui/ipc-client.d.ts +27 -0
- package/dist/tui/ipc-client.js +153 -0
- package/dist/tui/ipc-protocol.d.ts +50 -0
- package/dist/tui/ipc-protocol.js +7 -0
- package/dist/tui/ipc-server.d.ts +17 -0
- package/dist/tui/ipc-server.js +100 -0
- package/dist/tui/layout.d.ts +44 -0
- package/dist/tui/layout.js +365 -11
- package/dist/tui/service-panel.d.ts +19 -0
- package/dist/tui/service-panel.js +108 -0
- package/dist/tui/snapshot.d.ts +26 -0
- package/dist/tui/snapshot.js +58 -0
- package/dist/web-ui/content/scripts.js +40 -9
- package/dist/web-ui/content/styles.css +95 -30
- package/package.json +1 -1
|
@@ -1423,15 +1423,22 @@
|
|
|
1423
1423
|
'<div class="composer-top-row">' +
|
|
1424
1424
|
'<div id="todo-progress" class="todo-progress hidden">' +
|
|
1425
1425
|
'<div class="todo-progress-header" id="todo-progress-toggle">' +
|
|
1426
|
-
'<
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1426
|
+
'<div class="todo-progress-left">' +
|
|
1427
|
+
'<span class="todo-progress-ring" id="todo-progress-ring" aria-hidden="true" style="--progress:0">' +
|
|
1428
|
+
'<svg width="16" height="16" viewBox="0 0 36 36">' +
|
|
1429
|
+
'<circle class="todo-ring-track" cx="18" cy="18" r="15.5" fill="none" stroke-width="4"/>' +
|
|
1430
|
+
'<circle class="todo-ring-fill" cx="18" cy="18" r="15.5" fill="none" stroke-width="4" stroke-linecap="round"/>' +
|
|
1431
|
+
'</svg>' +
|
|
1432
|
+
'</span>' +
|
|
1433
|
+
'<span class="todo-progress-counter" id="todo-progress-counter"></span>' +
|
|
1434
|
+
'<span class="todo-progress-task" id="todo-progress-task"></span>' +
|
|
1435
|
+
'</div>' +
|
|
1436
|
+
'<svg class="todo-progress-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 15 12 9 18 15"/></svg>' +
|
|
1433
1437
|
'</div>' +
|
|
1434
1438
|
'</div>' +
|
|
1439
|
+
'<div class="todo-progress-body hidden" id="todo-progress-body">' +
|
|
1440
|
+
'<ul class="todo-progress-list" id="todo-progress-list"></ul>' +
|
|
1441
|
+
'</div>' +
|
|
1435
1442
|
'</div>' +
|
|
1436
1443
|
'<div class="input-composer">' +
|
|
1437
1444
|
'<button id="prompt-optimize-btn" class="prompt-optimize-btn" type="button" title="提示词优化(AI)" aria-label="提示词优化">' +
|
|
@@ -7588,6 +7595,14 @@
|
|
|
7588
7595
|
// Reset todo progress bar
|
|
7589
7596
|
var todoEl = document.getElementById("todo-progress");
|
|
7590
7597
|
if (todoEl) todoEl.classList.add("hidden");
|
|
7598
|
+
// 同时清掉上一会话残留的 "回复中 N.Ns" 状态条以及它的计时器/glow。
|
|
7599
|
+
// 不清就会出现:切到新建的空会话,底部仍显示前一会话的 todolist + 回复中。
|
|
7600
|
+
var staleStatusBar = document.querySelector(".structured-status-bar");
|
|
7601
|
+
if (staleStatusBar) staleStatusBar.remove();
|
|
7602
|
+
if (_statusBarTimerId) { clearInterval(_statusBarTimerId); _statusBarTimerId = null; }
|
|
7603
|
+
_statusBarStartTime = 0;
|
|
7604
|
+
var staleComposer = document.querySelector(".input-composer");
|
|
7605
|
+
if (staleComposer) staleComposer.classList.remove("in-flight");
|
|
7591
7606
|
var session = foundSession;
|
|
7592
7607
|
state.preferredCommand = getPreferredTool();
|
|
7593
7608
|
state.chatMode = getSafeModeForTool("claude", session && session.mode ? session.mode : state.chatMode);
|
|
@@ -13795,6 +13810,10 @@
|
|
|
13795
13810
|
state.lastRenderedEmpty = "empty";
|
|
13796
13811
|
state.lastRenderedMsgCount = 0;
|
|
13797
13812
|
}
|
|
13813
|
+
// 空会话进入空状态前,把上一会话残留的状态条 / todo 进度条清掉。
|
|
13814
|
+
// 这里是 selectSession 之外的兜底:WS init 等异步路径也会落到这条空分支。
|
|
13815
|
+
renderStructuredStatusBar(null, selectedSession);
|
|
13816
|
+
updateTodoProgress([]);
|
|
13798
13817
|
return;
|
|
13799
13818
|
}
|
|
13800
13819
|
|
|
@@ -14132,10 +14151,10 @@
|
|
|
14132
14151
|
if (prog && body) {
|
|
14133
14152
|
if (todoExpanded) {
|
|
14134
14153
|
prog.classList.add("expanded");
|
|
14135
|
-
body.classList.
|
|
14154
|
+
body.classList.add("expanded");
|
|
14136
14155
|
} else {
|
|
14137
14156
|
prog.classList.remove("expanded");
|
|
14138
|
-
body.classList.
|
|
14157
|
+
body.classList.remove("expanded");
|
|
14139
14158
|
}
|
|
14140
14159
|
}
|
|
14141
14160
|
});
|
|
@@ -14157,14 +14176,17 @@
|
|
|
14157
14176
|
}
|
|
14158
14177
|
|
|
14159
14178
|
var container = document.getElementById("todo-progress");
|
|
14179
|
+
var bodyEl = document.getElementById("todo-progress-body");
|
|
14160
14180
|
if (!container) return;
|
|
14161
14181
|
|
|
14162
14182
|
if (!todos || todos.length === 0) {
|
|
14163
14183
|
container.classList.add("hidden");
|
|
14184
|
+
if (bodyEl) bodyEl.classList.add("hidden");
|
|
14164
14185
|
return;
|
|
14165
14186
|
}
|
|
14166
14187
|
|
|
14167
14188
|
container.classList.remove("hidden");
|
|
14189
|
+
if (bodyEl) bodyEl.classList.remove("hidden");
|
|
14168
14190
|
|
|
14169
14191
|
var completed = 0;
|
|
14170
14192
|
var inProgress = 0;
|
|
@@ -14186,6 +14208,7 @@
|
|
|
14186
14208
|
if (allDone) {
|
|
14187
14209
|
// Hide todo when all tasks are completed
|
|
14188
14210
|
container.classList.add("hidden");
|
|
14211
|
+
if (bodyEl) bodyEl.classList.add("hidden");
|
|
14189
14212
|
return;
|
|
14190
14213
|
} else {
|
|
14191
14214
|
container.classList.remove("all-done");
|
|
@@ -14197,6 +14220,14 @@
|
|
|
14197
14220
|
var task = document.getElementById("todo-progress-task");
|
|
14198
14221
|
if (task) task.textContent = activeTask;
|
|
14199
14222
|
|
|
14223
|
+
// Drive the circular progress ring with the honest "completed / total" fraction
|
|
14224
|
+
// (counter text shows the 1-indexed current step, ring shows actual done ratio).
|
|
14225
|
+
var ring = document.getElementById("todo-progress-ring");
|
|
14226
|
+
if (ring) {
|
|
14227
|
+
var ratio = todos.length > 0 ? completed / todos.length : 0;
|
|
14228
|
+
ring.style.setProperty("--progress", ratio.toFixed(3));
|
|
14229
|
+
}
|
|
14230
|
+
|
|
14200
14231
|
// Render expanded list
|
|
14201
14232
|
var list = document.getElementById("todo-progress-list");
|
|
14202
14233
|
if (list) {
|
|
@@ -5345,10 +5345,12 @@
|
|
|
5345
5345
|
.input-label { font-size: 0.6875rem; color: var(--text-muted); font-weight: 500; }
|
|
5346
5346
|
.input-textarea-wrap { position: relative; width: 100%; }
|
|
5347
5347
|
|
|
5348
|
-
/* Composer top row: holds todo collapse bar (left) + reply status bar (right) on one line
|
|
5348
|
+
/* Composer top row: holds todo collapse bar (left) + reply status bar (right) on one line.
|
|
5349
|
+
position: relative anchors the upward-floating .todo-progress-body to the full row width. */
|
|
5349
5350
|
.composer-top-row {
|
|
5351
|
+
position: relative;
|
|
5350
5352
|
display: flex;
|
|
5351
|
-
align-items:
|
|
5353
|
+
align-items: center;
|
|
5352
5354
|
gap: 8px;
|
|
5353
5355
|
min-width: 0;
|
|
5354
5356
|
}
|
|
@@ -5391,31 +5393,52 @@
|
|
|
5391
5393
|
min-width: 0;
|
|
5392
5394
|
flex: 1;
|
|
5393
5395
|
}
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5396
|
+
/* Circular progress ring (replaces the old plain spinner) */
|
|
5397
|
+
.todo-progress-ring {
|
|
5398
|
+
position: relative;
|
|
5399
|
+
display: inline-flex;
|
|
5400
|
+
align-items: center;
|
|
5401
|
+
justify-content: center;
|
|
5402
|
+
width: 16px;
|
|
5403
|
+
height: 16px;
|
|
5404
|
+
min-width: 16px;
|
|
5405
|
+
flex-shrink: 0;
|
|
5402
5406
|
}
|
|
5403
|
-
.todo-progress
|
|
5404
|
-
|
|
5407
|
+
.todo-progress-ring svg {
|
|
5408
|
+
width: 100%;
|
|
5409
|
+
height: 100%;
|
|
5410
|
+
transform: rotate(-90deg);
|
|
5405
5411
|
}
|
|
5406
|
-
.todo-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5412
|
+
.todo-ring-track {
|
|
5413
|
+
stroke: rgba(197, 101, 61, 0.18);
|
|
5414
|
+
}
|
|
5415
|
+
.todo-ring-fill {
|
|
5416
|
+
stroke: var(--accent);
|
|
5417
|
+
/* circumference = 2 * π * 15.5 ≈ 97.39 */
|
|
5418
|
+
stroke-dasharray: 97.39;
|
|
5419
|
+
stroke-dashoffset: calc(97.39 * (1 - var(--progress, 0)));
|
|
5420
|
+
transition: stroke-dashoffset 0.35s ease;
|
|
5421
|
+
}
|
|
5422
|
+
.todo-progress-ring::after {
|
|
5423
|
+
content: "";
|
|
5424
|
+
position: absolute;
|
|
5425
|
+
width: 4px;
|
|
5426
|
+
height: 4px;
|
|
5427
|
+
border-radius: 50%;
|
|
5428
|
+
background: var(--accent);
|
|
5429
|
+
opacity: 0.6;
|
|
5430
|
+
animation: ringPulse 1.4s ease-in-out infinite;
|
|
5431
|
+
}
|
|
5432
|
+
@keyframes ringPulse {
|
|
5433
|
+
0%, 100% { opacity: 0.35; transform: scale(0.85); }
|
|
5434
|
+
50% { opacity: 0.95; transform: scale(1.05); }
|
|
5413
5435
|
}
|
|
5414
5436
|
.todo-progress-counter {
|
|
5415
5437
|
font-size: 0.75rem;
|
|
5416
5438
|
font-weight: 600;
|
|
5417
5439
|
color: var(--text-primary);
|
|
5418
5440
|
white-space: nowrap;
|
|
5441
|
+
font-variant-numeric: tabular-nums;
|
|
5419
5442
|
}
|
|
5420
5443
|
.todo-progress-task {
|
|
5421
5444
|
font-size: 0.75rem;
|
|
@@ -5432,44 +5455,84 @@
|
|
|
5432
5455
|
.todo-progress.expanded .todo-progress-chevron {
|
|
5433
5456
|
transform: rotate(180deg);
|
|
5434
5457
|
}
|
|
5458
|
+
|
|
5459
|
+
/* Expanded body floats UPWARD above the composer, spans the full row width,
|
|
5460
|
+
and is decoupled from the flex row so the status bar on the right does not
|
|
5461
|
+
animate together with the expansion. */
|
|
5435
5462
|
.todo-progress-body {
|
|
5436
|
-
|
|
5437
|
-
|
|
5463
|
+
position: absolute;
|
|
5464
|
+
left: 0;
|
|
5465
|
+
right: 0;
|
|
5466
|
+
bottom: calc(100% + 6px);
|
|
5467
|
+
background: rgba(255, 251, 246, 0.98);
|
|
5468
|
+
border: 1px solid var(--border-default);
|
|
5469
|
+
border-radius: 12px;
|
|
5470
|
+
padding: 8px 10px;
|
|
5471
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08), 0 2px 6px rgba(0, 0, 0, 0.04);
|
|
5472
|
+
backdrop-filter: blur(8px);
|
|
5473
|
+
-webkit-backdrop-filter: blur(8px);
|
|
5474
|
+
max-height: 320px;
|
|
5475
|
+
overflow-y: auto;
|
|
5476
|
+
z-index: 30;
|
|
5477
|
+
opacity: 0;
|
|
5478
|
+
transform: translateY(6px);
|
|
5479
|
+
pointer-events: none;
|
|
5480
|
+
transition: opacity 0.18s ease, transform 0.18s ease;
|
|
5438
5481
|
}
|
|
5439
5482
|
.todo-progress-body.hidden { display: none; }
|
|
5483
|
+
.todo-progress-body.expanded {
|
|
5484
|
+
opacity: 1;
|
|
5485
|
+
transform: translateY(0);
|
|
5486
|
+
pointer-events: auto;
|
|
5487
|
+
}
|
|
5440
5488
|
.todo-progress-list {
|
|
5441
5489
|
list-style: none;
|
|
5442
5490
|
margin: 0;
|
|
5443
5491
|
padding: 0;
|
|
5444
5492
|
display: flex;
|
|
5445
5493
|
flex-direction: column;
|
|
5446
|
-
gap:
|
|
5494
|
+
gap: 1px;
|
|
5447
5495
|
}
|
|
5448
5496
|
.todo-progress-item {
|
|
5449
5497
|
display: flex;
|
|
5450
5498
|
align-items: center;
|
|
5451
|
-
gap:
|
|
5452
|
-
padding:
|
|
5453
|
-
border-radius:
|
|
5454
|
-
font-size: 0.
|
|
5499
|
+
gap: 10px;
|
|
5500
|
+
padding: 6px 8px;
|
|
5501
|
+
border-radius: 8px;
|
|
5502
|
+
font-size: 0.8125rem;
|
|
5455
5503
|
color: var(--text-secondary);
|
|
5504
|
+
line-height: 1.35;
|
|
5456
5505
|
transition: background var(--transition-fast);
|
|
5457
5506
|
}
|
|
5507
|
+
.todo-progress-item + .todo-progress-item {
|
|
5508
|
+
border-top: 1px solid var(--border-subtle);
|
|
5509
|
+
border-radius: 0;
|
|
5510
|
+
}
|
|
5511
|
+
.todo-progress-item:first-child { border-top-left-radius: 8px; border-top-right-radius: 8px; }
|
|
5512
|
+
.todo-progress-item:last-child { border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; }
|
|
5458
5513
|
.todo-progress-item.active {
|
|
5459
5514
|
color: var(--text-primary);
|
|
5460
5515
|
font-weight: 500;
|
|
5461
|
-
background: rgba(197, 101, 61, 0.
|
|
5516
|
+
background: rgba(197, 101, 61, 0.07);
|
|
5462
5517
|
}
|
|
5463
5518
|
.todo-progress-item.done {
|
|
5464
5519
|
color: var(--text-muted);
|
|
5465
5520
|
text-decoration: line-through;
|
|
5466
5521
|
text-decoration-color: var(--text-muted);
|
|
5467
5522
|
}
|
|
5523
|
+
.todo-progress-item > span:last-child {
|
|
5524
|
+
flex: 1;
|
|
5525
|
+
min-width: 0;
|
|
5526
|
+
overflow: hidden;
|
|
5527
|
+
text-overflow: ellipsis;
|
|
5528
|
+
white-space: nowrap;
|
|
5529
|
+
}
|
|
5468
5530
|
.todo-item-icon {
|
|
5469
5531
|
width: 16px;
|
|
5470
5532
|
min-width: 16px;
|
|
5471
5533
|
text-align: center;
|
|
5472
|
-
font-size: 0.
|
|
5534
|
+
font-size: 0.75rem;
|
|
5535
|
+
flex-shrink: 0;
|
|
5473
5536
|
}
|
|
5474
5537
|
.todo-item-icon.pending { color: var(--text-muted); }
|
|
5475
5538
|
.todo-item-icon.active { color: var(--accent); }
|
|
@@ -12015,7 +12078,9 @@
|
|
|
12015
12078
|
100% { background-position: 100% center; }
|
|
12016
12079
|
}
|
|
12017
12080
|
|
|
12018
|
-
/* ── 结构化会话状态条(与 todo 折叠栏共处一行,靠右) ──
|
|
12081
|
+
/* ── 结构化会话状态条(与 todo 折叠栏共处一行,靠右) ──
|
|
12082
|
+
Only opacity/color transition — `transition: all` would cause this bar to
|
|
12083
|
+
animate together with the todo bar's expansion, which looks broken. */
|
|
12019
12084
|
.structured-status-bar {
|
|
12020
12085
|
display: flex;
|
|
12021
12086
|
align-items: center;
|
|
@@ -12028,7 +12093,7 @@
|
|
|
12028
12093
|
border: none;
|
|
12029
12094
|
font-size: 0.6875rem;
|
|
12030
12095
|
color: var(--text-muted);
|
|
12031
|
-
transition:
|
|
12096
|
+
transition: opacity 0.3s ease, color 0.3s ease;
|
|
12032
12097
|
overflow: hidden;
|
|
12033
12098
|
flex-shrink: 0;
|
|
12034
12099
|
}
|