@co0ontty/wand 1.35.1 → 1.36.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.
@@ -677,18 +677,18 @@
677
677
  display: flex;
678
678
  align-items: center;
679
679
  justify-content: space-between;
680
- padding: 14px 16px;
680
+ padding: 12px 14px;
681
681
  border-bottom: 1px solid var(--border-subtle);
682
682
  background: rgba(255, 251, 245, 0.8);
683
683
  flex-shrink: 0;
684
- min-height: 56px;
685
- gap: 12px;
684
+ min-height: 52px;
685
+ gap: 10px;
686
686
  }
687
687
 
688
688
  .sidebar-header-main {
689
689
  display: flex;
690
690
  align-items: center;
691
- gap: 10px;
691
+ gap: 9px;
692
692
  min-width: 0;
693
693
  flex: 1;
694
694
  }
@@ -696,10 +696,16 @@
696
696
  .sidebar-header-actions {
697
697
  display: flex;
698
698
  align-items: center;
699
- gap: 6px;
699
+ gap: 4px;
700
700
  flex-shrink: 0;
701
701
  }
702
702
 
703
+ /* On desktop pinned mode the close (X) button is redundant — the hamburger
704
+ toggle in the topbar already opens/closes the sidebar. Hide it to declutter. */
705
+ .sidebar.pinned .sidebar-header-actions .sidebar-close {
706
+ display: none;
707
+ }
708
+
703
709
  .sidebar-header-more {
704
710
  position: relative;
705
711
  }
@@ -1260,7 +1266,7 @@
1260
1266
  flex: 1;
1261
1267
  min-height: 0;
1262
1268
  overflow-y: auto;
1263
- padding: 12px;
1269
+ padding: 10px 10px 12px;
1264
1270
  }
1265
1271
 
1266
1272
  .sessions-list:empty::before {
@@ -1282,7 +1288,7 @@
1282
1288
  the "Liquid Glass — sidebar" section below. */
1283
1289
 
1284
1290
  .session-group-title {
1285
- padding: 8px 8px 12px;
1291
+ padding: 4px 6px 10px;
1286
1292
  font-size: 0.6875rem;
1287
1293
  font-weight: 700;
1288
1294
  letter-spacing: 0.08em;
@@ -1296,9 +1302,9 @@
1296
1302
  .session-group-title::before {
1297
1303
  content: '';
1298
1304
  width: 3px;
1299
- height: 14px;
1305
+ height: 12px;
1300
1306
  background: var(--accent);
1301
- opacity: 0.7;
1307
+ opacity: 0.65;
1302
1308
  border-radius: var(--radius-full);
1303
1309
  }
1304
1310
 
@@ -1408,17 +1414,21 @@
1408
1414
  z-index: 1;
1409
1415
  }
1410
1416
 
1417
+ /* Keep content transparent by default so it doesn't paint a second
1418
+ gradient inside the card (which created a visible "white box" in the
1419
+ middle). Only opaque when swiped, so the actions stay hidden behind. */
1411
1420
  .session-item-content {
1412
1421
  position: relative;
1413
1422
  z-index: 2;
1414
- background: inherit;
1423
+ background: transparent;
1415
1424
  border-radius: inherit;
1416
- transition: transform 0.3s var(--ease-out-expo);
1425
+ transition: transform 0.3s var(--ease-out-expo), background 0.18s ease;
1417
1426
  will-change: transform;
1418
1427
  }
1419
1428
 
1420
1429
  .session-item.swiped .session-item-content {
1421
1430
  transform: translateX(-72px);
1431
+ background: linear-gradient(180deg, rgba(255, 252, 247, 0.96) 0%, rgba(252, 246, 237, 0.94) 100%);
1422
1432
  }
1423
1433
 
1424
1434
  .session-manage-check {
@@ -1443,11 +1453,18 @@
1443
1453
  width: 18px;
1444
1454
  height: 18px;
1445
1455
  border-radius: 6px;
1446
- border: 1px solid var(--border-subtle);
1447
- background: var(--bg-surface);
1456
+ border: 1px solid rgba(125, 91, 57, 0.22);
1457
+ background: rgba(255, 251, 245, 0.55);
1458
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4);
1448
1459
  display: inline-flex;
1449
1460
  align-items: center;
1450
1461
  justify-content: center;
1462
+ transition: background 0.15s ease, border-color 0.15s ease;
1463
+ }
1464
+
1465
+ .session-manage-check:hover span {
1466
+ background: rgba(255, 251, 245, 0.8);
1467
+ border-color: rgba(125, 91, 57, 0.35);
1451
1468
  }
1452
1469
 
1453
1470
  .session-manage-check input:checked + span {
@@ -1504,10 +1521,11 @@
1504
1521
  }
1505
1522
 
1506
1523
  .session-main {
1524
+ flex: 1;
1507
1525
  min-width: 0;
1508
1526
  display: flex;
1509
1527
  flex-direction: column;
1510
- gap: 3px;
1528
+ gap: 4px;
1511
1529
  padding-right: 64px;
1512
1530
  }
1513
1531
 
@@ -2220,8 +2238,158 @@
2220
2238
  font-weight: 500;
2221
2239
  }
2222
2240
 
2241
+ /* ===== Sidebar: docked Claude history region =====
2242
+ Lives between .sidebar-body and .sidebar-footer. Collapsed by default —
2243
+ only a slim header row ("历史消息" + 数字气泡) is visible, so the main
2244
+ scrolling area focuses on recent / archived sessions. Expanding it
2245
+ grows the region with a 40% max-height cap so it can never eat the
2246
+ sessions list above. */
2247
+ .sidebar-history-region {
2248
+ flex-shrink: 0;
2249
+ display: flex;
2250
+ flex-direction: column;
2251
+ min-height: 0;
2252
+ max-height: 40%;
2253
+ border-top: 1px solid var(--border-subtle);
2254
+ background: rgba(255, 251, 245, 0.66);
2255
+ transition: max-height 0.28s var(--ease-out-expo);
2256
+ }
2257
+
2258
+ .sidebar-history-header {
2259
+ display: flex;
2260
+ align-items: center;
2261
+ justify-content: space-between;
2262
+ width: 100%;
2263
+ padding: 9px 14px;
2264
+ min-height: 38px;
2265
+ flex-shrink: 0;
2266
+ background: transparent;
2267
+ border: none;
2268
+ border-radius: 0;
2269
+ cursor: pointer;
2270
+ text-align: left;
2271
+ font-family: var(--font-sans);
2272
+ font-size: 0.75rem;
2273
+ font-weight: 600;
2274
+ letter-spacing: 0.005em;
2275
+ color: var(--text-secondary);
2276
+ transition: background var(--transition-fast), color var(--transition-fast);
2277
+ -webkit-tap-highlight-color: transparent;
2278
+ }
2279
+
2280
+ .sidebar-history-header:hover {
2281
+ background: rgba(150, 118, 85, 0.06);
2282
+ color: var(--text-primary);
2283
+ }
2284
+
2285
+ .sidebar-history-header:active {
2286
+ background: rgba(150, 118, 85, 0.1);
2287
+ }
2288
+
2289
+ .sidebar-history-header.expanded {
2290
+ background: rgba(255, 251, 245, 0.85);
2291
+ color: var(--text-primary);
2292
+ border-bottom: 1px solid var(--border-subtle);
2293
+ }
2294
+
2295
+ .sidebar-history-label {
2296
+ display: inline-flex;
2297
+ align-items: center;
2298
+ gap: 6px;
2299
+ }
2300
+
2301
+ .sidebar-history-right {
2302
+ display: inline-flex;
2303
+ align-items: center;
2304
+ gap: 8px;
2305
+ flex-shrink: 0;
2306
+ }
2307
+
2308
+ /* Count bubble — pill shape, tabular numerals, accent-tinted when there
2309
+ are items, muted when empty/loading. */
2310
+ .history-bubble {
2311
+ display: inline-flex;
2312
+ align-items: center;
2313
+ justify-content: center;
2314
+ min-width: 22px;
2315
+ height: 18px;
2316
+ padding: 0 7px;
2317
+ border-radius: 999px;
2318
+ background: var(--accent-muted);
2319
+ color: var(--accent);
2320
+ font-size: 0.6875rem;
2321
+ font-weight: 700;
2322
+ font-variant-numeric: tabular-nums;
2323
+ line-height: 1;
2324
+ letter-spacing: 0;
2325
+ }
2326
+
2327
+ .history-bubble.empty {
2328
+ background: var(--bg-tertiary);
2329
+ color: var(--text-muted);
2330
+ opacity: 0.65;
2331
+ }
2332
+
2333
+ .history-bubble.loading {
2334
+ background: transparent;
2335
+ color: var(--text-muted);
2336
+ letter-spacing: 0.1em;
2337
+ padding: 0 4px;
2338
+ font-weight: 600;
2339
+ }
2340
+
2341
+ .sidebar-history-chevron {
2342
+ flex-shrink: 0;
2343
+ color: var(--text-muted);
2344
+ transition: transform 0.22s var(--ease-out-expo), color var(--transition-fast);
2345
+ }
2346
+
2347
+ .sidebar-history-header.expanded .sidebar-history-chevron {
2348
+ transform: rotate(180deg);
2349
+ color: var(--text-secondary);
2350
+ }
2351
+
2352
+ /* Expanded body — scrollable, capped via parent max-height. */
2353
+ .sidebar-history-body {
2354
+ flex: 1;
2355
+ min-height: 0;
2356
+ overflow-y: auto;
2357
+ padding: 6px 8px 10px;
2358
+ display: flex;
2359
+ flex-direction: column;
2360
+ gap: 4px;
2361
+ animation: historyBodyFadeIn 0.22s var(--ease-out-expo);
2362
+ }
2363
+
2364
+ @keyframes historyBodyFadeIn {
2365
+ from { opacity: 0; transform: translateY(-2px); }
2366
+ to { opacity: 1; transform: translateY(0); }
2367
+ }
2368
+
2369
+ .sidebar-history-toolbar {
2370
+ display: flex;
2371
+ justify-content: flex-end;
2372
+ padding: 2px 4px 6px;
2373
+ flex-shrink: 0;
2374
+ }
2375
+
2376
+ .sidebar-history-clear {
2377
+ color: var(--text-muted);
2378
+ font-weight: 500;
2379
+ }
2380
+ .sidebar-history-clear:hover {
2381
+ color: var(--danger);
2382
+ background: var(--danger-muted);
2383
+ }
2384
+
2385
+ .sidebar-history-scroll {
2386
+ display: flex;
2387
+ flex-direction: column;
2388
+ gap: 2px;
2389
+ }
2390
+
2223
2391
  .sidebar-footer {
2224
- padding: 14px;
2392
+ padding: 12px 12px 14px;
2225
2393
  border-top: 1px solid var(--border-subtle);
2226
2394
  display: flex;
2227
2395
  flex-direction: column;
@@ -2229,10 +2397,13 @@
2229
2397
  background: rgba(255, 251, 245, 0.7);
2230
2398
  }
2231
2399
 
2400
+ /* Auto-fit grid: 3 buttons stretch to fill, extra buttons (PWA install
2401
+ / switch server) drop in without breaking the row. minmax(56px,1fr)
2402
+ guarantees touch-friendly width while not leaving big empty cells. */
2232
2403
  .sidebar-footer-actions {
2233
2404
  display: grid;
2234
- grid-template-columns: repeat(4, 1fr);
2235
- gap: 6px;
2405
+ grid-template-columns: repeat(auto-fit, minmax(56px, 1fr));
2406
+ gap: 4px;
2236
2407
  }
2237
2408
 
2238
2409
  .sidebar-footer-actions .btn {
@@ -2240,19 +2411,22 @@
2240
2411
  flex-direction: column;
2241
2412
  align-items: center;
2242
2413
  justify-content: center;
2243
- gap: 3px;
2414
+ gap: 4px;
2244
2415
  font-size: 0.625rem;
2416
+ font-weight: 500;
2245
2417
  color: var(--text-muted);
2246
- padding: 8px 4px;
2247
- min-height: 48px;
2248
- border-radius: var(--radius-sm);
2249
- transition: all var(--transition-fast);
2418
+ padding: 7px 4px;
2419
+ min-height: 46px;
2420
+ border-radius: 9px;
2421
+ transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
2250
2422
  }
2251
2423
 
2252
2424
  .sidebar-footer-actions .btn svg {
2253
2425
  width: 16px;
2254
2426
  height: 16px;
2255
2427
  flex-shrink: 0;
2428
+ opacity: 0.85;
2429
+ transition: opacity var(--transition-fast);
2256
2430
  }
2257
2431
 
2258
2432
  .sidebar-footer-actions .btn:hover {
@@ -2261,6 +2435,10 @@
2261
2435
  transform: translateY(-1px);
2262
2436
  }
2263
2437
 
2438
+ .sidebar-footer-actions .btn:hover svg {
2439
+ opacity: 1;
2440
+ }
2441
+
2264
2442
  .sidebar-footer-actions .btn:active {
2265
2443
  transform: scale(0.95);
2266
2444
  transition-duration: 0.1s;
@@ -2270,6 +2448,30 @@
2270
2448
  display: none;
2271
2449
  }
2272
2450
 
2451
+ /* Subtle visual separation for the destructive "退出" so it doesn't
2452
+ sit visually equal to "文件 / 设置". A hairline divider on the left
2453
+ (collapses gracefully if it lands at the start of a wrapped row). */
2454
+ .sidebar-footer-actions .sidebar-logout {
2455
+ position: relative;
2456
+ }
2457
+ .sidebar-footer-actions .sidebar-logout::before {
2458
+ content: "";
2459
+ position: absolute;
2460
+ left: -3px;
2461
+ top: 22%;
2462
+ bottom: 22%;
2463
+ width: 1px;
2464
+ background: var(--border-subtle);
2465
+ pointer-events: none;
2466
+ }
2467
+ .sidebar-footer-actions .sidebar-logout:hover {
2468
+ color: var(--danger);
2469
+ background: var(--danger-muted);
2470
+ }
2471
+ .sidebar-footer-actions .sidebar-logout:hover svg {
2472
+ color: var(--danger);
2473
+ }
2474
+
2273
2475
  .sidebar-meta {
2274
2476
  display: flex;
2275
2477
  flex-direction: row;
@@ -15688,4 +15890,191 @@
15688
15890
  }
15689
15891
  .working-dir-indicator-icon > svg { display: block; }
15690
15892
 
15893
+ /* ===== 终端悬浮摇杆遥控器(手机端 PTY 遥控) ===== */
15894
+ .wand-joystick-root {
15895
+ position: fixed;
15896
+ inset: 0;
15897
+ z-index: 40;
15898
+ pointer-events: none;
15899
+ opacity: 0;
15900
+ visibility: hidden;
15901
+ transition: opacity 0.2s ease;
15902
+ }
15903
+ .wand-joystick-root.visible {
15904
+ opacity: 1;
15905
+ visibility: visible;
15906
+ }
15907
+ .wand-joystick-backdrop {
15908
+ position: absolute;
15909
+ inset: 0;
15910
+ background: rgba(20, 15, 12, 0);
15911
+ pointer-events: none;
15912
+ transition: background 0.2s ease;
15913
+ }
15914
+ .wand-joystick-backdrop.active {
15915
+ background: rgba(20, 15, 12, 0.28);
15916
+ pointer-events: auto;
15917
+ }
15918
+ .wand-joystick-ball {
15919
+ position: fixed;
15920
+ right: 18px;
15921
+ bottom: 96px;
15922
+ width: 52px;
15923
+ height: 52px;
15924
+ border-radius: 50%;
15925
+ display: flex;
15926
+ align-items: center;
15927
+ justify-content: center;
15928
+ color: rgba(245, 235, 225, 0.95);
15929
+ background: rgba(32, 25, 21, 0.78);
15930
+ border: 1px solid rgba(197, 101, 61, 0.34);
15931
+ box-shadow:
15932
+ 0 6px 20px rgba(0, 0, 0, 0.36),
15933
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
15934
+ backdrop-filter: blur(8px);
15935
+ -webkit-backdrop-filter: blur(8px);
15936
+ pointer-events: auto;
15937
+ touch-action: none;
15938
+ -webkit-tap-highlight-color: transparent;
15939
+ user-select: none;
15940
+ -webkit-user-select: none;
15941
+ z-index: 43;
15942
+ cursor: grab;
15943
+ transition: transform 0.18s var(--ease-spring), background 0.2s ease, border-color 0.2s ease;
15944
+ }
15945
+ .wand-joystick-ball:hover { border-color: rgba(197, 101, 61, 0.55); }
15946
+ .wand-joystick-ball:active { background: rgba(44, 34, 28, 0.88); }
15947
+ .wand-joystick-ball.dragging {
15948
+ transform: scale(1.12);
15949
+ cursor: grabbing;
15950
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.42);
15951
+ }
15952
+ /* 环形菜单:圆心运行期由 JS 对齐球球中心 */
15953
+ .wand-joystick-ring {
15954
+ position: fixed;
15955
+ left: 0;
15956
+ top: 0;
15957
+ width: 0;
15958
+ height: 0;
15959
+ z-index: 42;
15960
+ pointer-events: none;
15961
+ opacity: 0;
15962
+ transform: scale(0.6);
15963
+ transition: opacity 0.18s var(--ease-out-expo), transform 0.22s var(--ease-spring);
15964
+ }
15965
+ .wand-joystick-ring.active {
15966
+ opacity: 1;
15967
+ transform: scale(1);
15968
+ }
15969
+ .wjr-svg {
15970
+ position: absolute;
15971
+ left: 0;
15972
+ top: 0;
15973
+ transform: translate(-50%, -50%);
15974
+ overflow: visible;
15975
+ pointer-events: none;
15976
+ filter: drop-shadow(0 10px 30px rgba(0, 0, 0, 0.5));
15977
+ }
15978
+ /* 底盘:所有扇区之下的玻璃圆盘,扇区细缝与外缘透出它,统一成一颗整盘 */
15979
+ .wjr-base {
15980
+ fill: rgba(18, 13, 10, 0.8);
15981
+ stroke: rgba(245, 235, 225, 0.14);
15982
+ stroke-width: 1;
15983
+ }
15984
+ .wjr-svg text {
15985
+ text-anchor: middle;
15986
+ dominant-baseline: central;
15987
+ font-size: 10.5px;
15988
+ font-weight: 600;
15989
+ fill: #f6ede3;
15990
+ /* 描边垫底 → 标签在任意扇区色/穿透的终端字上都清晰 */
15991
+ paint-order: stroke;
15992
+ stroke: rgba(10, 7, 5, 0.55);
15993
+ stroke-width: 2.2px;
15994
+ stroke-linejoin: round;
15995
+ pointer-events: none;
15996
+ }
15997
+ .wjr-inner text { font-size: 16px; fill: #fff; }
15998
+ .wjr-svg .wjr-2line { font-size: 9.5px; }
15999
+ .wjr-sector path {
16000
+ fill: rgba(74, 61, 53, 0.9); /* 功能圈:暖玻璃面,明显高于底盘与终端背景 */
16001
+ stroke: none;
16002
+ transition: fill 0.12s ease;
16003
+ }
16004
+ .wjr-inner path { fill: rgba(56, 45, 39, 0.92); } /* 方向圈略深,与功能圈区分层次 */
16005
+ .wjr-sector.is-repeating path,
16006
+ .wjr-sector.is-hover path { fill: var(--accent); }
16007
+ .wjr-sector.is-repeating text,
16008
+ .wjr-sector.is-hover text { fill: #fff; stroke: rgba(120, 42, 18, 0.5); }
16009
+ .wjr-sector.is-repeating,
16010
+ .wjr-sector.is-hover { filter: drop-shadow(0 0 9px rgba(197, 101, 61, 0.6)); }
16011
+ .wjr-hub {
16012
+ fill: rgba(14, 10, 8, 0.96);
16013
+ stroke: rgba(245, 235, 225, 0.22);
16014
+ stroke-width: 1.5;
16015
+ }
16016
+ text.wjr-hub-label { font-size: 12px; font-weight: 700; fill: #f6ede3; stroke: none; }
16017
+ .wand-joystick-ball.is-ringing { opacity: 0; }
16018
+ /* 钉住面板 */
16019
+ .wand-joystick-panel {
16020
+ position: fixed;
16021
+ right: 18px;
16022
+ bottom: 160px;
16023
+ z-index: 44;
16024
+ display: flex;
16025
+ flex-direction: column;
16026
+ gap: 8px;
16027
+ padding: 12px;
16028
+ border-radius: 16px;
16029
+ background: rgba(28, 22, 18, 0.92);
16030
+ border: 1px solid rgba(245, 235, 225, 0.14);
16031
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
16032
+ backdrop-filter: blur(10px);
16033
+ -webkit-backdrop-filter: blur(10px);
16034
+ pointer-events: none;
16035
+ opacity: 0;
16036
+ transform: translateY(8px) scale(0.96);
16037
+ transform-origin: bottom right;
16038
+ transition: opacity 0.18s var(--ease-out-expo), transform 0.22s var(--ease-spring);
16039
+ max-width: calc(100vw - 36px);
16040
+ }
16041
+ .wand-joystick-panel.active {
16042
+ pointer-events: auto;
16043
+ opacity: 1;
16044
+ transform: translateY(0) scale(1);
16045
+ }
16046
+ .wjp-title {
16047
+ font-size: 0.66rem;
16048
+ letter-spacing: 0.08em;
16049
+ text-transform: uppercase;
16050
+ color: rgba(245, 235, 225, 0.5);
16051
+ text-align: center;
16052
+ }
16053
+ .wjp-dpad { display: flex; flex-direction: column; align-items: center; gap: 4px; }
16054
+ .wjp-dpad-row { display: flex; gap: 4px; }
16055
+ .wjp-grid { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
16056
+ .wjp-fnkeys { max-width: 200px; }
16057
+ .wjp-key {
16058
+ min-width: 44px;
16059
+ height: 40px;
16060
+ padding: 0 8px;
16061
+ border-radius: 10px;
16062
+ font-size: 0.78rem;
16063
+ font-weight: 600;
16064
+ color: rgba(245, 235, 225, 0.92);
16065
+ background: rgba(255, 255, 255, 0.06);
16066
+ border: 1px solid rgba(245, 235, 225, 0.14);
16067
+ cursor: pointer;
16068
+ touch-action: manipulation;
16069
+ -webkit-tap-highlight-color: transparent;
16070
+ user-select: none;
16071
+ transition: transform 0.1s ease, background 0.15s ease;
16072
+ }
16073
+ .wjp-key:active { background: var(--accent-soft, rgba(197, 101, 61, 0.2)); transform: scale(0.94); }
16074
+ .wjp-key.wjp-mod.active {
16075
+ background: var(--accent);
16076
+ color: #fff;
16077
+ border-color: var(--accent);
16078
+ }
16079
+
15691
16080
  /* 结束标记 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "1.35.1",
3
+ "version": "1.36.0",
4
4
  "description": "A web terminal for local CLI tools like Claude.",
5
5
  "type": "module",
6
6
  "bin": {