@oratis/lisa 0.11.1 → 0.14.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.
Files changed (142) hide show
  1. package/dist/agent.d.ts +2 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +20 -1
  4. package/dist/agent.js.map +1 -1
  5. package/dist/agents/pty.d.ts.map +1 -1
  6. package/dist/agents/pty.js +13 -2
  7. package/dist/agents/pty.js.map +1 -1
  8. package/dist/autonomy/state.d.ts +14 -0
  9. package/dist/autonomy/state.d.ts.map +1 -0
  10. package/dist/autonomy/state.js +54 -0
  11. package/dist/autonomy/state.js.map +1 -0
  12. package/dist/cli/mail.d.ts +2 -0
  13. package/dist/cli/mail.d.ts.map +1 -0
  14. package/dist/cli/mail.js +209 -0
  15. package/dist/cli/mail.js.map +1 -0
  16. package/dist/cli/pair.d.ts +15 -0
  17. package/dist/cli/pair.d.ts.map +1 -0
  18. package/dist/cli/pair.js +152 -0
  19. package/dist/cli/pair.js.map +1 -0
  20. package/dist/cli.js +22 -14
  21. package/dist/cli.js.map +1 -1
  22. package/dist/consent/store.d.ts +2 -2
  23. package/dist/consent/store.d.ts.map +1 -1
  24. package/dist/consent/store.js +3 -2
  25. package/dist/consent/store.js.map +1 -1
  26. package/dist/edition.d.ts +24 -0
  27. package/dist/edition.d.ts.map +1 -0
  28. package/dist/edition.js +19 -0
  29. package/dist/edition.js.map +1 -0
  30. package/dist/heartbeat/runner.d.ts.map +1 -1
  31. package/dist/heartbeat/runner.js +8 -0
  32. package/dist/heartbeat/runner.js.map +1 -1
  33. package/dist/idle/runner.d.ts.map +1 -1
  34. package/dist/idle/runner.js +7 -0
  35. package/dist/idle/runner.js.map +1 -1
  36. package/dist/mail/accounts.d.ts +20 -0
  37. package/dist/mail/accounts.d.ts.map +1 -0
  38. package/dist/mail/accounts.js +113 -0
  39. package/dist/mail/accounts.js.map +1 -0
  40. package/dist/mail/alerts.d.ts +29 -0
  41. package/dist/mail/alerts.d.ts.map +1 -0
  42. package/dist/mail/alerts.js +40 -0
  43. package/dist/mail/alerts.js.map +1 -0
  44. package/dist/mail/classify.d.ts +26 -0
  45. package/dist/mail/classify.d.ts.map +1 -0
  46. package/dist/mail/classify.js +191 -0
  47. package/dist/mail/classify.js.map +1 -0
  48. package/dist/mail/connectors/gmail.d.ts +55 -0
  49. package/dist/mail/connectors/gmail.d.ts.map +1 -0
  50. package/dist/mail/connectors/gmail.js +87 -0
  51. package/dist/mail/connectors/gmail.js.map +1 -0
  52. package/dist/mail/connectors/imap.d.ts +13 -0
  53. package/dist/mail/connectors/imap.d.ts.map +1 -0
  54. package/dist/mail/connectors/imap.js +136 -0
  55. package/dist/mail/connectors/imap.js.map +1 -0
  56. package/dist/mail/digest.d.ts +21 -0
  57. package/dist/mail/digest.d.ts.map +1 -0
  58. package/dist/mail/digest.js +89 -0
  59. package/dist/mail/digest.js.map +1 -0
  60. package/dist/mail/google-oauth.d.ts +50 -0
  61. package/dist/mail/google-oauth.d.ts.map +1 -0
  62. package/dist/mail/google-oauth.js +74 -0
  63. package/dist/mail/google-oauth.js.map +1 -0
  64. package/dist/mail/hosts.d.ts +3 -0
  65. package/dist/mail/hosts.d.ts.map +1 -0
  66. package/dist/mail/hosts.js +19 -0
  67. package/dist/mail/hosts.js.map +1 -0
  68. package/dist/mail/scheduler.d.ts +9 -0
  69. package/dist/mail/scheduler.d.ts.map +1 -0
  70. package/dist/mail/scheduler.js +21 -0
  71. package/dist/mail/scheduler.js.map +1 -0
  72. package/dist/mail/service.d.ts +32 -0
  73. package/dist/mail/service.d.ts.map +1 -0
  74. package/dist/mail/service.js +129 -0
  75. package/dist/mail/service.js.map +1 -0
  76. package/dist/mail/store.d.ts +7 -0
  77. package/dist/mail/store.d.ts.map +1 -0
  78. package/dist/mail/store.js +58 -0
  79. package/dist/mail/store.js.map +1 -0
  80. package/dist/mail/types.d.ts +114 -0
  81. package/dist/mail/types.d.ts.map +1 -0
  82. package/dist/mail/types.js +26 -0
  83. package/dist/mail/types.js.map +1 -0
  84. package/dist/providers/anthropic.d.ts.map +1 -1
  85. package/dist/providers/anthropic.js +43 -21
  86. package/dist/providers/anthropic.js.map +1 -1
  87. package/dist/providers/gemini.d.ts.map +1 -1
  88. package/dist/providers/gemini.js +67 -64
  89. package/dist/providers/gemini.js.map +1 -1
  90. package/dist/providers/openai.d.ts.map +1 -1
  91. package/dist/providers/openai.js +77 -71
  92. package/dist/providers/openai.js.map +1 -1
  93. package/dist/providers/registry.d.ts +10 -0
  94. package/dist/providers/registry.d.ts.map +1 -1
  95. package/dist/providers/registry.js +26 -0
  96. package/dist/providers/registry.js.map +1 -1
  97. package/dist/providers/stream-retry.d.ts +37 -0
  98. package/dist/providers/stream-retry.d.ts.map +1 -0
  99. package/dist/providers/stream-retry.js +92 -0
  100. package/dist/providers/stream-retry.js.map +1 -0
  101. package/dist/providers/types.d.ts +3 -0
  102. package/dist/providers/types.d.ts.map +1 -1
  103. package/dist/subagent.d.ts +2 -0
  104. package/dist/subagent.d.ts.map +1 -1
  105. package/dist/subagent.js +1 -0
  106. package/dist/subagent.js.map +1 -1
  107. package/dist/web/cloudAuth.d.ts +57 -0
  108. package/dist/web/cloudAuth.d.ts.map +1 -0
  109. package/dist/web/cloudAuth.js +139 -0
  110. package/dist/web/cloudAuth.js.map +1 -0
  111. package/dist/web/island.d.ts.map +1 -1
  112. package/dist/web/island.js +1 -0
  113. package/dist/web/island.js.map +1 -1
  114. package/dist/web/lisa-client.d.ts +1 -1
  115. package/dist/web/lisa-client.d.ts.map +1 -1
  116. package/dist/web/lisa-client.js +703 -40
  117. package/dist/web/lisa-client.js.map +1 -1
  118. package/dist/web/lisa-css.d.ts +1 -1
  119. package/dist/web/lisa-css.d.ts.map +1 -1
  120. package/dist/web/lisa-css.js +568 -43
  121. package/dist/web/lisa-css.js.map +1 -1
  122. package/dist/web/lisa-html.d.ts +1 -1
  123. package/dist/web/lisa-html.d.ts.map +1 -1
  124. package/dist/web/lisa-html.js +71 -21
  125. package/dist/web/lisa-html.js.map +1 -1
  126. package/dist/web/pairing.d.ts +37 -0
  127. package/dist/web/pairing.d.ts.map +1 -0
  128. package/dist/web/pairing.js +79 -0
  129. package/dist/web/pairing.js.map +1 -0
  130. package/dist/web/push.d.ts +91 -0
  131. package/dist/web/push.d.ts.map +1 -1
  132. package/dist/web/push.js +250 -9
  133. package/dist/web/push.js.map +1 -1
  134. package/dist/web/qr-svg.d.ts +11 -0
  135. package/dist/web/qr-svg.d.ts.map +1 -0
  136. package/dist/web/qr-svg.js +41 -0
  137. package/dist/web/qr-svg.js.map +1 -0
  138. package/dist/web/server.d.ts +1 -1
  139. package/dist/web/server.d.ts.map +1 -1
  140. package/dist/web/server.js +378 -14
  141. package/dist/web/server.js.map +1 -1
  142. package/package.json +4 -1
@@ -16,6 +16,10 @@ export const MAIN_CSS = ` :root {
16
16
  --accent: #6ad4ff;
17
17
  --accent-soft: rgba(106, 212, 255, 0.13);
18
18
  --accent-glow: rgba(106, 212, 255, 0.27);
19
+ /* Proactive / autonomy "live" accent (green) — the console's watching state. */
20
+ --proactive: #3ddc97;
21
+ --proactive-soft: rgba(61, 220, 151, 0.13);
22
+ --proactive-glow: rgba(61, 220, 151, 0.30);
19
23
  --warm: #ffd066;
20
24
  --dream: #b487ff;
21
25
  --claude: #ff8c42;
@@ -66,7 +70,7 @@ export const MAIN_CSS = ` :root {
66
70
  height: 100vh;
67
71
  width: 100vw;
68
72
  display: grid;
69
- grid-template-columns: 280px 1fr;
73
+ grid-template-columns: 300px 1fr;
70
74
  grid-template-rows: 36px 1fr;
71
75
  grid-template-areas:
72
76
  "titlebar titlebar"
@@ -115,15 +119,18 @@ export const MAIN_CSS = ` :root {
115
119
  letter-spacing: 0;
116
120
  }
117
121
 
118
- /* ── Sidebar ───────────────────────────────────────────────── */
122
+ /* ── Sidebar (floating panel — Claude-Code-style detached card) ──── */
119
123
  .sidebar {
120
124
  grid-area: sidebar;
121
- background: rgba(7, 9, 26, 0.4);
125
+ margin: 8px 6px 10px 10px;
126
+ background: linear-gradient(180deg, rgba(18, 23, 48, 0.62), rgba(10, 13, 33, 0.6));
122
127
  backdrop-filter: blur(30px);
123
128
  -webkit-backdrop-filter: blur(30px);
124
- border-right: 1px solid var(--border-new);
129
+ border: 1px solid var(--border-new);
130
+ border-radius: 16px;
131
+ box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
125
132
  overflow-y: auto;
126
- padding: 20px 16px 16px;
133
+ padding: 18px 14px 14px;
127
134
  display: flex;
128
135
  flex-direction: column;
129
136
  gap: 18px;
@@ -242,6 +249,11 @@ export const MAIN_CSS = ` :root {
242
249
  border-color: rgba(255, 208, 102, 0.22);
243
250
  background: linear-gradient(180deg, rgba(255, 208, 102, 0.07), rgba(255, 208, 102, 0.02));
244
251
  }
252
+ .card.tint-mail {
253
+ border-color: rgba(106, 212, 255, 0.20);
254
+ background: linear-gradient(180deg, rgba(106, 212, 255, 0.06), rgba(106, 212, 255, 0.02));
255
+ }
256
+ .card.tint-mail .h .left { color: var(--brand, #6ad4ff); }
245
257
  .card .h {
246
258
  display: flex;
247
259
  justify-content: space-between;
@@ -365,40 +377,55 @@ export const MAIN_CSS = ` :root {
365
377
  background: rgba(0,0,0,0.25);
366
378
  color: var(--fg);
367
379
  }
368
- /* "Delegate a task" composer at the top of the agents card. */
369
- .delegate {
370
- display: flex;
371
- gap: 6px;
380
+ /* "Delegate a task" a single full-width button that opens a modal. */
381
+ .delegate-btn {
382
+ width: 100%;
372
383
  margin: 2px 0 8px;
373
- }
374
- .delegate input {
375
- flex: 1;
376
- font-size: 11px;
377
- padding: 4px 8px;
378
- border-radius: 7px;
379
- border: 1px solid var(--border);
380
- background: rgba(0,0,0,0.25);
381
- color: var(--fg);
382
- }
383
- .delegate select {
384
- font-size: 10.5px;
385
- padding: 3px 4px;
386
- border-radius: 7px;
387
- border: 1px solid var(--border);
388
- background: rgba(0,0,0,0.25);
389
- color: var(--fg-2);
390
- cursor: pointer;
391
- }
392
- .delegate button {
393
- font-size: 11px;
394
- padding: 4px 10px;
395
- border-radius: 7px;
384
+ font-size: 11.5px;
385
+ padding: 6px 10px;
386
+ border-radius: 8px;
396
387
  border: 1px solid var(--claude, #ff8c42);
397
- background: rgba(255,140,66,0.16);
388
+ background: rgba(255,140,66,0.14);
398
389
  color: var(--claude, #ff8c42);
399
390
  cursor: pointer;
400
- }
401
- .delegate button:hover { background: rgba(255,140,66,0.28); }
391
+ transition: background 0.12s ease;
392
+ }
393
+ .delegate-btn:hover { background: rgba(255,140,66,0.26); }
394
+ /* Delegate dialog (rendered in the shared modal). */
395
+ .delegate-modal { display: flex; flex-direction: column; gap: 8px; }
396
+ .delegate-modal .dm-label {
397
+ font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
398
+ color: var(--fg-2); margin-top: 4px;
399
+ }
400
+ .delegate-modal .dm-kind,
401
+ .delegate-modal .dm-task {
402
+ width: 100%; box-sizing: border-box;
403
+ font-size: 13px; padding: 8px 10px; border-radius: 8px;
404
+ border: 1px solid var(--border); background: rgba(0,0,0,0.25); color: var(--fg);
405
+ }
406
+ .delegate-modal .dm-task { resize: vertical; min-height: 88px; font-family: inherit; }
407
+ .delegate-modal .dm-actions { display: flex; justify-content: flex-end; margin-top: 4px; }
408
+ .delegate-modal .dm-start {
409
+ font-size: 13px; padding: 8px 16px; border-radius: 8px;
410
+ border: 1px solid var(--brand, #6ad4ff); background: rgba(106,212,255,0.16);
411
+ color: var(--brand, #6ad4ff); cursor: pointer;
412
+ }
413
+ .delegate-modal .dm-start:hover { background: rgba(106,212,255,0.28); }
414
+ .delegate-modal .dm-start:disabled { opacity: 0.5; cursor: default; }
415
+ .delegate-modal .dm-err { color: var(--err-color, #ff5577); font-size: 12px; white-space: pre-wrap; }
416
+ .delegate-modal .dm-note { font-size: 11px; color: var(--fg-faint); line-height: 1.4; margin-top: 2px; }
417
+ /* Mail card body */
418
+ #sbMailBody { margin: 2px 0 6px; }
419
+ .mail-summary { font-size: 11.5px; color: var(--fg-2); line-height: 1.45; margin-bottom: 6px; }
420
+ .mail-row { display: flex; gap: 6px; align-items: baseline; padding: 1px 0; }
421
+ .mail-bang { color: var(--brand, #6ad4ff); font-weight: 700; font-size: 11px; flex: none; }
422
+ .mail-bang.urgent { color: var(--err-color, #ff5577); }
423
+ .mail-subj { font-size: 11.5px; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
424
+ .mail-sweep {
425
+ margin-top: 6px; font-size: 10.5px; background: none; border: none;
426
+ color: var(--brand, #6ad4ff); cursor: pointer; padding: 2px 0;
427
+ }
428
+ .mail-sweep:hover { text-decoration: underline; }
402
429
  .session-empty {
403
430
  color: var(--fg-faint);
404
431
  font-size: 11.5px;
@@ -488,16 +515,356 @@ export const MAIN_CSS = ` :root {
488
515
  flex-shrink: 0;
489
516
  }
490
517
 
518
+ /* ── Primary nav (vertical list in the sidebar) ────────────── */
519
+ .nav-list { display: flex; flex-direction: column; gap: 2px; }
520
+ .nav-item {
521
+ position: relative;
522
+ display: flex;
523
+ align-items: center;
524
+ gap: 10px;
525
+ width: 100%;
526
+ padding: 8px 11px;
527
+ border: 0;
528
+ border-radius: 9px;
529
+ background: transparent;
530
+ color: var(--fg-2);
531
+ font-family: inherit;
532
+ font-size: 12.5px;
533
+ font-weight: 600;
534
+ letter-spacing: 0.01em;
535
+ text-align: left;
536
+ cursor: pointer;
537
+ transition: background 120ms ease, color 120ms ease;
538
+ }
539
+ .nav-item .nav-ico { width: 18px; font-size: 15px; text-align: center; flex-shrink: 0; opacity: 0.9; }
540
+ .nav-item:hover { background: var(--bg-card); color: var(--fg); }
541
+ .nav-item.active { background: var(--accent-soft); color: var(--accent); }
542
+ .nav-item.active::before {
543
+ content: "";
544
+ position: absolute;
545
+ left: 0;
546
+ top: 50%;
547
+ transform: translateY(-50%);
548
+ width: 3px;
549
+ height: 18px;
550
+ border-radius: 0 3px 3px 0;
551
+ background: var(--accent);
552
+ }
553
+ .nav-item .nav-tag {
554
+ margin-left: auto;
555
+ font-size: 9.5px;
556
+ font-weight: 700;
557
+ font-variant-numeric: tabular-nums;
558
+ color: var(--fg);
559
+ background: var(--bg-3);
560
+ border-radius: 999px;
561
+ padding: 1px 7px;
562
+ min-width: 18px;
563
+ text-align: center;
564
+ }
565
+ .nav-item.active .nav-tag { background: var(--accent); color: #06141b; }
566
+
567
+ /* ── Proactive toggle (sidebar footer area) ────────────────── */
568
+ .proactive-toggle {
569
+ display: flex;
570
+ align-items: center;
571
+ gap: 9px;
572
+ padding: 9px 11px;
573
+ background: var(--bg-card);
574
+ border: 1px solid var(--border-new);
575
+ border-radius: 11px;
576
+ cursor: pointer;
577
+ user-select: none;
578
+ transition: border-color 140ms ease, background 140ms ease;
579
+ }
580
+ .proactive-toggle .pt-label {
581
+ font-size: 11px;
582
+ font-weight: 700;
583
+ letter-spacing: 0.06em;
584
+ text-transform: uppercase;
585
+ color: var(--fg-3);
586
+ transition: color 140ms ease;
587
+ }
588
+ .proactive-toggle .pt-track {
589
+ margin-left: auto;
590
+ width: 34px;
591
+ height: 18px;
592
+ border-radius: 999px;
593
+ background: var(--bg-3);
594
+ border: 1px solid var(--border-new);
595
+ position: relative;
596
+ flex-shrink: 0;
597
+ transition: background 140ms ease, border-color 140ms ease;
598
+ }
599
+ .proactive-toggle .pt-knob {
600
+ position: absolute;
601
+ top: 1px;
602
+ left: 1px;
603
+ width: 14px;
604
+ height: 14px;
605
+ border-radius: 50%;
606
+ background: var(--fg-3);
607
+ transition: transform 140ms ease, background 140ms ease;
608
+ }
609
+ .proactive-toggle.on { border-color: var(--proactive-glow); background: var(--proactive-soft); }
610
+ .proactive-toggle.on .pt-label { color: var(--proactive); }
611
+ .proactive-toggle.on .pt-track { background: var(--proactive-soft); border-color: var(--proactive-glow); }
612
+ .proactive-toggle.on .pt-knob { transform: translateX(16px); background: var(--proactive); }
613
+
491
614
  /* ── Main pane ─────────────────────────────────────────────── */
615
+ /* The main pane is a view stack: each .view fills the pane and only the
616
+ active one is shown. Chat is the default; it keeps its original
617
+ log / attachPreview / form 3-row grid (moved onto #viewChat). */
492
618
  .main {
493
619
  grid-area: main;
494
- display: grid;
495
- grid-template-rows: 1fr auto auto;
620
+ position: relative;
496
621
  overflow: hidden;
497
622
  background:
498
623
  radial-gradient(ellipse at 50% -30%, rgba(106, 212, 255, 0.06) 0%, transparent 60%),
499
624
  linear-gradient(180deg, transparent, rgba(106, 212, 255, 0.015));
500
625
  }
626
+ .view { display: none; }
627
+ .view.active {
628
+ position: absolute;
629
+ inset: 0;
630
+ display: flex;
631
+ flex-direction: column;
632
+ }
633
+ #viewChat.view.active {
634
+ display: grid;
635
+ grid-template-rows: auto 1fr auto auto;
636
+ }
637
+
638
+ /* ── Console views (dashboard / control / reve / sense / memory) ── */
639
+ .view-head {
640
+ display: flex;
641
+ align-items: center;
642
+ justify-content: space-between;
643
+ gap: 12px;
644
+ padding: 16px 24px;
645
+ border-bottom: 1px solid var(--border-new);
646
+ }
647
+ .view-head h2 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: 0.02em; color: var(--fg); }
648
+ .view-head .vh-sub { margin: 2px 0 0; font-size: 11.5px; color: var(--fg-3); }
649
+ .view-act {
650
+ flex-shrink: 0;
651
+ font-family: inherit;
652
+ font-size: 12px;
653
+ font-weight: 600;
654
+ color: #06140d;
655
+ background: var(--accent);
656
+ border: 0;
657
+ border-radius: 9px;
658
+ padding: 8px 13px;
659
+ cursor: pointer;
660
+ display: inline-flex;
661
+ align-items: center;
662
+ gap: 6px;
663
+ transition: filter 120ms ease, transform 120ms ease;
664
+ }
665
+ .view-act:hover { filter: brightness(1.08); }
666
+ .view-act:active { transform: translateY(1px); }
667
+ .view-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 24px 26px; }
668
+ .view-empty { color: var(--fg-faint); font-size: 12.5px; font-style: italic; padding: 18px 4px; }
669
+ .view-sec-label {
670
+ font-size: 11px;
671
+ font-weight: 700;
672
+ text-transform: uppercase;
673
+ letter-spacing: 0.10em;
674
+ color: var(--fg-3);
675
+ margin: 4px 0 8px;
676
+ }
677
+
678
+ /* Stat bar */
679
+ .stat-bar { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
680
+ .stat {
681
+ flex: 1;
682
+ min-width: 92px;
683
+ background: var(--bg-card);
684
+ border: 1px solid var(--border-new);
685
+ border-radius: 12px;
686
+ padding: 11px 13px;
687
+ }
688
+ .stat .n { font-size: 21px; font-weight: 700; color: var(--fg); font-variant-numeric: tabular-nums; line-height: 1.1; }
689
+ .stat .k {
690
+ margin-top: 3px;
691
+ font-size: 10px;
692
+ text-transform: uppercase;
693
+ letter-spacing: 0.08em;
694
+ color: var(--fg-3);
695
+ }
696
+
697
+ /* Green "proactive — watching" panel */
698
+ .proactive-panel {
699
+ border: 1px solid var(--proactive-glow);
700
+ background: linear-gradient(180deg, var(--proactive-soft), transparent);
701
+ border-radius: 14px;
702
+ padding: 13px 15px;
703
+ margin-bottom: 16px;
704
+ }
705
+ .proactive-panel .pp-head { display: flex; align-items: center; gap: 10px; }
706
+ .proactive-panel .pp-dot {
707
+ width: 9px;
708
+ height: 9px;
709
+ border-radius: 50%;
710
+ background: var(--proactive);
711
+ box-shadow: 0 0 8px var(--proactive-glow);
712
+ flex-shrink: 0;
713
+ }
714
+ .proactive-panel.off .pp-dot { background: var(--fg-faint); box-shadow: none; }
715
+ .proactive-panel .pp-title { font-size: 13px; font-weight: 700; color: var(--fg); }
716
+ .proactive-panel .pp-title b { color: var(--proactive); font-weight: 700; }
717
+ .proactive-panel.off .pp-title b { color: var(--fg-3); }
718
+ .proactive-panel .pp-desc { margin: 2px 0 0; font-size: 11.5px; color: var(--fg-2); }
719
+ /* .pp-tags / .pp-tag are reused outside the panel (Control policy chips),
720
+ so they are not scoped to .proactive-panel. */
721
+ .pp-tags { display: flex; flex-wrap: wrap; gap: 6px; }
722
+ .proactive-panel .pp-tags { margin-top: 10px; }
723
+ .pp-tag {
724
+ font-size: 10.5px;
725
+ color: var(--fg-3);
726
+ background: rgba(255, 255, 255, 0.05);
727
+ border: 1px solid var(--border-new);
728
+ border-radius: 999px;
729
+ padding: 2px 9px;
730
+ }
731
+ .pp-tag.warn { color: var(--warm); }
732
+
733
+ /* "Focus" big card (current desire / objective analog) */
734
+ .focus-card {
735
+ background: var(--bg-card);
736
+ border: 1px solid var(--border-new);
737
+ border-radius: 14px;
738
+ padding: 15px;
739
+ margin-bottom: 18px;
740
+ }
741
+ .focus-card .fc-top { display: flex; align-items: flex-start; gap: 10px; }
742
+ .focus-card .fc-title { font-size: 14.5px; font-weight: 700; color: var(--fg); }
743
+ .focus-card .fc-desc { margin: 4px 0 0; font-size: 12px; color: var(--fg-2); line-height: 1.5; }
744
+ .focus-card .fc-pill {
745
+ margin-left: auto;
746
+ flex-shrink: 0;
747
+ font-size: 10.5px;
748
+ color: var(--proactive);
749
+ border: 1px solid var(--proactive-glow);
750
+ border-radius: 999px;
751
+ padding: 2px 10px;
752
+ }
753
+ .focus-card .fc-meta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 11px; font-size: 11px; color: var(--fg-3); }
754
+
755
+ /* Horizontally-scrolling agent / task cards */
756
+ .card-scroll {
757
+ display: flex;
758
+ gap: 12px;
759
+ overflow-x: auto;
760
+ padding-bottom: 6px;
761
+ margin-bottom: 18px;
762
+ scroll-snap-type: x proximity;
763
+ }
764
+ .ac {
765
+ flex: 0 0 232px;
766
+ scroll-snap-align: start;
767
+ background: var(--bg-card);
768
+ border: 1px solid var(--border-new);
769
+ border-radius: 13px;
770
+ padding: 13px;
771
+ }
772
+ .ac .ac-top { display: flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--fg-3); margin-bottom: 8px; }
773
+ .ac .ac-status { margin-left: auto; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
774
+ .ac .ac-status.working { color: var(--accent); }
775
+ .ac .ac-status.waiting { color: var(--warm); }
776
+ .ac .ac-status.error { color: var(--err-color); }
777
+ .ac .ac-status.done { color: var(--proactive); }
778
+ .ac .ac-title { font-size: 13px; font-weight: 600; color: var(--fg); margin-bottom: 3px; word-break: break-word; }
779
+ .ac .ac-desc { font-size: 11.5px; color: var(--fg-2); line-height: 1.45; }
780
+ .ac .ac-meta {
781
+ margin-top: 9px;
782
+ padding-top: 7px;
783
+ border-top: 1px solid var(--border-new);
784
+ font-size: 10px;
785
+ color: var(--fg-3);
786
+ font-family: ui-monospace, "SF Mono", Menlo, monospace;
787
+ }
788
+
789
+ /* Simple list rows / cards used by Reve / Sense / Memory */
790
+ .v-card {
791
+ background: var(--bg-card);
792
+ border: 1px solid var(--border-new);
793
+ border-radius: 12px;
794
+ padding: 12px 14px;
795
+ margin-bottom: 10px;
796
+ }
797
+ .v-card h3 {
798
+ margin: 0 0 6px;
799
+ font-size: 11px;
800
+ font-weight: 700;
801
+ text-transform: uppercase;
802
+ letter-spacing: 0.08em;
803
+ color: var(--fg-3);
804
+ }
805
+ .v-pre {
806
+ margin: 0;
807
+ white-space: pre-wrap;
808
+ word-break: break-word;
809
+ font-size: 12px;
810
+ line-height: 1.55;
811
+ color: var(--fg-2);
812
+ font-family: ui-monospace, "SF Mono", Menlo, monospace;
813
+ }
814
+ .v-row {
815
+ display: flex;
816
+ align-items: center;
817
+ gap: 10px;
818
+ padding: 11px 0;
819
+ border-top: 1px solid var(--border-new);
820
+ }
821
+ .v-row:first-child { border-top: 0; }
822
+ .v-row .v-main { min-width: 0; flex: 1; }
823
+ .v-row .v-name { font-size: 12.5px; font-weight: 600; color: var(--fg); }
824
+ .v-row .v-sub { font-size: 11px; color: var(--fg-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
825
+ .v-toggle {
826
+ font-family: inherit;
827
+ font-size: 11px;
828
+ font-weight: 600;
829
+ cursor: pointer;
830
+ border-radius: 7px;
831
+ padding: 4px 10px;
832
+ border: 1px solid var(--border-new);
833
+ background: var(--bg-3);
834
+ color: var(--fg-3);
835
+ flex-shrink: 0;
836
+ }
837
+ .v-toggle.on { color: var(--proactive); border-color: var(--proactive-glow); background: var(--proactive-soft); }
838
+ .v-sel {
839
+ font-family: inherit;
840
+ font-size: 12px;
841
+ color: var(--fg);
842
+ background: var(--bg-3);
843
+ border: 1px solid var(--border-new);
844
+ border-radius: 8px;
845
+ padding: 5px 8px;
846
+ }
847
+ .mem-btn {
848
+ width: 100%;
849
+ text-align: left;
850
+ font-family: inherit;
851
+ font-size: 13px;
852
+ font-weight: 600;
853
+ color: var(--fg);
854
+ background: var(--bg-card);
855
+ border: 1px solid var(--border-new);
856
+ border-radius: 11px;
857
+ padding: 13px 15px;
858
+ margin-bottom: 9px;
859
+ cursor: pointer;
860
+ display: flex;
861
+ align-items: center;
862
+ gap: 10px;
863
+ transition: background 120ms ease, border-color 120ms ease;
864
+ }
865
+ .mem-btn:hover { background: var(--bg-card-strong); border-color: var(--border-strong); }
866
+ .mem-btn .mem-ico { font-size: 16px; width: 20px; text-align: center; }
867
+ .mem-btn .mem-sub { margin-left: auto; font-size: 11px; color: var(--fg-3); font-weight: 400; }
501
868
 
502
869
  #log {
503
870
  overflow-y: auto;
@@ -608,6 +975,44 @@ export const MAIN_CSS = ` :root {
608
975
  font-size: 12px;
609
976
  padding: 6px 2px;
610
977
  }
978
+ /* Failed-turn block: error detail + retry button (replaces the old bare
979
+ [error] line so the user can read what happened and re-run the turn). */
980
+ .err-block {
981
+ background: linear-gradient(180deg, rgba(255, 85, 119, 0.10), rgba(255, 85, 119, 0.02));
982
+ border: 1px solid rgba(255, 85, 119, 0.30);
983
+ border-radius: 14px;
984
+ padding: 10px 12px;
985
+ margin: 6px 0;
986
+ }
987
+ .err-block .err-head {
988
+ color: var(--err-color);
989
+ font-size: 12px;
990
+ font-weight: 600;
991
+ letter-spacing: 0.03em;
992
+ margin-bottom: 4px;
993
+ }
994
+ .err-block .err-detail {
995
+ color: var(--err-color);
996
+ font-size: 12px;
997
+ line-height: 1.45;
998
+ word-break: break-word;
999
+ white-space: pre-wrap;
1000
+ opacity: 0.9;
1001
+ }
1002
+ .err-block .err-retry {
1003
+ margin-top: 8px;
1004
+ padding: 4px 12px;
1005
+ font-size: 12px;
1006
+ font-weight: 600;
1007
+ color: var(--accent);
1008
+ background: var(--accent-soft);
1009
+ border: 1px solid rgba(106, 212, 255, 0.40);
1010
+ border-radius: 8px;
1011
+ cursor: pointer;
1012
+ }
1013
+ .err-block .err-retry:hover {
1014
+ background: var(--accent-glow);
1015
+ }
611
1016
 
612
1017
  /* Idle pulse + while-you-were-away banner injected into #log */
613
1018
  .idle-pulse {
@@ -684,12 +1089,12 @@ export const MAIN_CSS = ` :root {
684
1089
  -webkit-backdrop-filter: blur(30px);
685
1090
  border-top: 1px solid var(--border-new);
686
1091
  display: grid;
687
- grid-template-columns: 36px 36px 36px 1fr 96px;
1092
+ grid-template-columns: 36px 36px 1fr 96px;
688
1093
  gap: 10px;
689
1094
  align-items: end;
690
1095
  }
691
1096
 
692
- #attachBtn, #captureBtn, #recordBtn {
1097
+ #plusBtn, #recordBtn {
693
1098
  align-self: stretch;
694
1099
  display: flex;
695
1100
  align-items: center;
@@ -704,8 +1109,56 @@ export const MAIN_CSS = ` :root {
704
1109
  min-height: 44px;
705
1110
  padding: 0;
706
1111
  }
707
- #attachBtn:hover, #captureBtn:hover, #recordBtn:hover { background: var(--bg-card); color: var(--fg); }
708
- #captureBtn.flash { background: var(--accent); color: var(--bg-deep); }
1112
+ #plusBtn { font-size: 22px; }
1113
+ #plusBtn:hover, #recordBtn:hover { background: var(--bg-card); color: var(--fg); }
1114
+ #plusBtn.flash { background: var(--accent); color: var(--bg-deep); }
1115
+
1116
+ /* + composer menu (merged attach + screenshot) */
1117
+ .plus-wrap { position: relative; align-self: stretch; display: flex; }
1118
+ .plus-menu {
1119
+ display: none;
1120
+ position: absolute;
1121
+ left: 0;
1122
+ bottom: calc(100% + 8px);
1123
+ min-width: 168px;
1124
+ background: var(--bg-deep, #0c1024);
1125
+ border: 1px solid var(--border-new, rgba(255,255,255,.1));
1126
+ border-radius: 11px;
1127
+ padding: 5px;
1128
+ box-shadow: 0 14px 34px rgba(0,0,0,.5);
1129
+ z-index: 30;
1130
+ }
1131
+ .plus-menu.open { display: block; }
1132
+ .plus-menu button {
1133
+ display: flex; align-items: center; gap: 9px; width: 100%;
1134
+ background: transparent; border: 0; color: var(--fg); font-size: 13px;
1135
+ padding: 9px 10px; border-radius: 8px; cursor: pointer; text-align: left;
1136
+ }
1137
+ .plus-menu button:hover { background: var(--bg-card); }
1138
+ .plus-menu .g { width: 18px; text-align: center; }
1139
+
1140
+ /* Top icon function bar (功能区) inside #viewChat */
1141
+ .fnbar {
1142
+ display: flex; align-items: center; gap: 6px;
1143
+ padding: 7px 16px;
1144
+ border-bottom: 1px solid var(--border-new, rgba(255,255,255,.08));
1145
+ background: rgba(255,255,255,.02);
1146
+ }
1147
+ .fbtn {
1148
+ width: 34px; height: 34px; flex: none;
1149
+ display: flex; align-items: center; justify-content: center;
1150
+ background: transparent; border: 1px solid transparent; border-radius: 9px;
1151
+ color: var(--fg-2); cursor: pointer;
1152
+ transition: background 120ms ease, color 120ms ease;
1153
+ }
1154
+ .fbtn:hover { background: var(--bg-card, rgba(255,255,255,.06)); color: var(--fg); }
1155
+ .fbtn svg { width: 19px; height: 19px; display: block; }
1156
+ .fbar-spacer { flex: 1; }
1157
+ .fn-find {
1158
+ height: 28px; width: 150px; font-size: 12px; padding: 0 9px;
1159
+ border-radius: 8px; border: 1px solid var(--border-strong, rgba(255,255,255,.14));
1160
+ background: rgba(0,0,0,.3); color: var(--fg);
1161
+ }
709
1162
  /* Pulsing red while recording. */
710
1163
  #recordBtn.recording {
711
1164
  background: var(--err-color);
@@ -784,7 +1237,12 @@ export const MAIN_CSS = ` :root {
784
1237
  }
785
1238
  .frame {
786
1239
  grid-template-columns: 1fr;
787
- grid-template-rows: auto 1fr auto;
1240
+ /* titlebar · sidebar (capped, scrolls) · main view-stack (fills rest) */
1241
+ grid-template-rows: auto auto 1fr;
1242
+ grid-template-areas:
1243
+ "titlebar"
1244
+ "sidebar"
1245
+ "main";
788
1246
  }
789
1247
  .sidebar {
790
1248
  max-height: 38vh;
@@ -792,12 +1250,30 @@ export const MAIN_CSS = ` :root {
792
1250
  gap: 14px;
793
1251
  }
794
1252
  #form {
795
- grid-template-columns: 36px 36px 36px 1fr 84px;
1253
+ grid-template-columns: 36px 36px 1fr 84px;
796
1254
  padding: 10px 14px 14px;
797
1255
  }
798
1256
  #input { font-size: 16px; /* prevents iOS Safari auto-zoom */ }
799
1257
  }
800
1258
 
1259
+ /* ── Forced compact / "sidebar mode" ─────────────────────────────
1260
+ Same stacked layout as the narrow breakpoint, but toggled on at ANY
1261
+ width (persisted client-side) so Lisa can be docked as a skinny panel. */
1262
+ body.force-compact .frame {
1263
+ grid-template-columns: 1fr;
1264
+ grid-template-rows: auto auto 1fr;
1265
+ grid-template-areas:
1266
+ "titlebar"
1267
+ "sidebar"
1268
+ "main";
1269
+ }
1270
+ body.force-compact .sidebar {
1271
+ max-height: 38vh;
1272
+ padding: 14px 14px 12px;
1273
+ gap: 14px;
1274
+ }
1275
+ body.force-compact #form { grid-template-columns: 36px 36px 1fr 84px; }
1276
+
801
1277
  /* ===================================================================
802
1278
  Modal panel (skills / memory / tools / soul) — unchanged from the
803
1279
  legacy pixel-art shell. Uses the legacy CSS vars declared above.
@@ -878,6 +1354,55 @@ export const MAIN_CSS = ` :root {
878
1354
  font-size: 12px;
879
1355
  }
880
1356
  .modal-body .desc { color: var(--fg-3); margin-top: 2px; }
1357
+ .modal-body .pair-qr {
1358
+ display: flex;
1359
+ justify-content: center;
1360
+ margin: 4px 0 14px;
1361
+ }
1362
+ .modal-body .pair-qr svg {
1363
+ width: 200px;
1364
+ height: 200px;
1365
+ background: #fff;
1366
+ padding: 10px;
1367
+ border-radius: 12px;
1368
+ }
1369
+ .modal-body .pair-row {
1370
+ display: flex;
1371
+ align-items: center;
1372
+ gap: 8px;
1373
+ padding: 7px 0;
1374
+ border-bottom: 1px solid var(--line, rgba(255,255,255,0.07));
1375
+ }
1376
+ .modal-body .pair-row:last-child { border: none; }
1377
+ .modal-body .pair-label {
1378
+ flex: 0 0 52px;
1379
+ color: var(--fg-3);
1380
+ font-size: 11px;
1381
+ text-transform: uppercase;
1382
+ letter-spacing: 0.04em;
1383
+ }
1384
+ .modal-body .pair-val {
1385
+ flex: 1 1 auto;
1386
+ min-width: 0;
1387
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1388
+ font-size: 11.5px;
1389
+ color: var(--fg-1, #e8e8ea);
1390
+ overflow-wrap: anywhere;
1391
+ user-select: all;
1392
+ }
1393
+ .modal-body .pair-copy {
1394
+ flex: 0 0 auto;
1395
+ font-family: inherit;
1396
+ font-size: 11px;
1397
+ font-weight: 700;
1398
+ color: var(--fg-2);
1399
+ background: var(--btn-bg, rgba(255,255,255,0.08));
1400
+ border: 1px solid var(--line, rgba(255,255,255,0.12));
1401
+ border-radius: 6px;
1402
+ padding: 3px 9px;
1403
+ cursor: pointer;
1404
+ }
1405
+ .modal-body .pair-copy:hover { filter: brightness(1.12); }
881
1406
  .modal-body .plan-select {
882
1407
  margin-top: 6px;
883
1408
  font-family: inherit;