@tt-a1i/openpi 0.5.0 → 0.6.1

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 (80) hide show
  1. package/README.md +30 -20
  2. package/SETUP.md +10 -4
  3. package/THIRD_PARTY_NOTICES.md +16 -0
  4. package/bin/openpi.js +25 -15
  5. package/extensions/ai-providers/LICENSE.upstream +23 -0
  6. package/extensions/ai-providers/README.md +65 -0
  7. package/extensions/ai-providers/antigravity/credentials.ts +52 -0
  8. package/extensions/ai-providers/antigravity/discovery.ts +130 -0
  9. package/extensions/ai-providers/antigravity/google-conversion.ts +455 -0
  10. package/extensions/ai-providers/antigravity/models.ts +84 -0
  11. package/extensions/ai-providers/antigravity/oauth.ts +700 -0
  12. package/extensions/ai-providers/antigravity/provider.ts +1116 -0
  13. package/extensions/ai-providers/antigravity/routing.ts +340 -0
  14. package/extensions/ai-providers/antigravity/with-resolvers.d.ts +19 -0
  15. package/extensions/ai-providers/cursor/constants.ts +5 -0
  16. package/extensions/ai-providers/cursor/credentials.ts +14 -0
  17. package/extensions/ai-providers/cursor/discovery.ts +291 -0
  18. package/extensions/ai-providers/cursor/input-images.ts +105 -0
  19. package/extensions/ai-providers/cursor/models.ts +45 -0
  20. package/extensions/ai-providers/cursor/oauth.ts +263 -0
  21. package/extensions/ai-providers/cursor/proto.ts +1271 -0
  22. package/extensions/ai-providers/cursor/protobuf.ts +1181 -0
  23. package/extensions/ai-providers/cursor/provider.ts +1431 -0
  24. package/extensions/ai-providers/cursor/proxy.ts +213 -0
  25. package/extensions/ai-providers/cursor/tool-bridge.ts +68 -0
  26. package/extensions/ai-providers/cursor/with-resolvers.d.ts +12 -0
  27. package/extensions/ai-providers/index.ts +86 -0
  28. package/extensions/ai-providers/oauth-adapter.ts +81 -0
  29. package/extensions/ai-providers/usage.ts +10 -0
  30. package/extensions/background-terminals/index.ts +8 -1
  31. package/extensions/background-terminals/src/manager.ts +3 -5
  32. package/extensions/background-terminals/src/result-delivery.ts +43 -23
  33. package/extensions/cron/index.ts +68 -27
  34. package/extensions/cron/schedule.ts +5 -1
  35. package/extensions/model-info/cache-diagnostics.ts +220 -0
  36. package/extensions/model-info/index.ts +45 -1
  37. package/extensions/plan-mode/index.ts +75 -4
  38. package/extensions/setup/index.ts +15 -3
  39. package/extensions/shared/child-session.ts +39 -5
  40. package/extensions/shared/completion-inbox.ts +193 -0
  41. package/extensions/shared/setup-config.ts +10 -1
  42. package/extensions/shared/structured-output.ts +154 -0
  43. package/extensions/subagents/index.ts +64 -7
  44. package/extensions/subagents/src/agent-types.ts +5 -17
  45. package/extensions/subagents/src/backends/pi.ts +130 -48
  46. package/extensions/subagents/src/backends/tool-preview.ts +29 -0
  47. package/extensions/subagents/src/domain.ts +16 -1
  48. package/extensions/subagents/src/manager.ts +7 -71
  49. package/extensions/subagents/src/prompt.ts +19 -5
  50. package/extensions/subagents/src/result-artifact.ts +32 -0
  51. package/extensions/subagents/src/result-delivery.ts +33 -14
  52. package/extensions/subagents/src/runtime.ts +10 -3
  53. package/extensions/ui-customization/footer.ts +16 -5
  54. package/extensions/user-input-fold/index.ts +42 -6
  55. package/extensions/web/index.ts +25 -2
  56. package/extensions/workflows/acceptance.ts +43 -19
  57. package/extensions/workflows/completion-projection.ts +3 -1
  58. package/extensions/workflows/dashboard.ts +147 -21
  59. package/extensions/workflows/index.ts +75 -20
  60. package/extensions/workflows/model.ts +5 -1
  61. package/extensions/workflows/progress-projection.ts +7 -1
  62. package/extensions/workflows/prompt.ts +4 -10
  63. package/extensions/workflows/result-delivery.ts +96 -22
  64. package/extensions/workflows/retention.ts +6 -0
  65. package/extensions/workflows/runner.ts +11 -233
  66. package/extensions/workflows/sandbox.ts +4 -0
  67. package/package.json +7 -7
  68. package/skills/subagents/REFERENCE.md +9 -9
  69. package/skills/subagents/SKILL.md +2 -1
  70. package/skills/workflows/REFERENCE.md +5 -3
  71. package/skills/workflows/SKILL.md +1 -1
  72. package/web/adapter/pi-adapter.ts +3 -0
  73. package/web/host/pi-coding-agent-entry.ts +162 -0
  74. package/web/host/web-host.ts +330 -50
  75. package/web/protocol/types.ts +5 -0
  76. package/web/runtime/pi-runtime.ts +240 -25
  77. package/web/runtime/types.ts +32 -1
  78. package/web/ui/app.js +343 -41
  79. package/web/ui/index.html +3 -0
  80. package/web/ui/styles.css +119 -37
package/web/ui/styles.css CHANGED
@@ -1,6 +1,8 @@
1
1
  :root {
2
2
  color-scheme: light;
3
3
  --page: #ffffff;
4
+ --page-grid: #faf7ed;
5
+ --grid-line: rgba(182, 165, 119, .2);
4
6
  --sidebar: #faf7ed;
5
7
  --sidebar-hover: #f3ead0;
6
8
  --sidebar-active: #eee9dc;
@@ -16,16 +18,84 @@
16
18
  --focus: #4c88cf;
17
19
  --healthy: #28835a;
18
20
  --error: #b42318;
21
+ --surface-hover: #fafbfc;
22
+ --surface-soft: #f1f3f5;
23
+ --surface-selected: #eef1f4;
24
+ --surface-code: #f5f6f7;
25
+ --secondary-text: #39434d;
26
+ --tertiary-text: #5f6973;
27
+ --placeholder: #7f8993;
28
+ --icon-muted: #9aa2aa;
29
+ --clear-muted: #737b83;
30
+ --danger-border: #f0c6c6;
31
+ --danger: #e55353;
32
+ --danger-hover: #fff3f3;
33
+ --inverse-text: #ffffff;
34
+ --warm-border: #d8cfae;
35
+ --reconnecting: #9a6700;
36
+ --input-surface: rgba(255, 255, 255, .48);
37
+ --hover-overlay: rgba(255, 255, 255, .72);
38
+ --header-surface: rgba(251, 250, 245, .76);
39
+ --details-hover: rgba(238, 241, 244, .72);
40
+ --details-surface: rgba(247, 248, 249, .82);
41
+ --dock-start: rgba(250, 247, 237, 0);
42
+ --dock-end: rgba(250, 247, 237, .94);
43
+ --link-underline: rgba(40, 103, 178, .35);
44
+ }
45
+
46
+ :root[data-theme="dark"] {
47
+ color-scheme: dark;
48
+ --page: #17191c;
49
+ --page-grid: #111315;
50
+ --grid-line: rgba(135, 144, 153, .12);
51
+ --sidebar: #1d2024;
52
+ --sidebar-hover: #292d32;
53
+ --sidebar-active: #30353b;
54
+ --border: #353a40;
55
+ --border-strong: #48515a;
56
+ --text: #edf0f2;
57
+ --muted: #a8b0b8;
58
+ --subtle: #7f8993;
59
+ --accent: #74a9e6;
60
+ --warm-accent: #303026;
61
+ --warm-accent-hover: #3b3a2d;
62
+ --warm-accent-disabled: #252722;
63
+ --focus: #78aee9;
64
+ --healthy: #62c795;
65
+ --error: #ff8c84;
66
+ --surface-hover: #25292e;
67
+ --surface-soft: #282d32;
68
+ --surface-selected: #30363d;
69
+ --surface-code: #20242a;
70
+ --secondary-text: #cbd1d7;
71
+ --tertiary-text: #b2bac2;
72
+ --placeholder: #929ba4;
73
+ --icon-muted: #858f98;
74
+ --clear-muted: #a1aab3;
75
+ --danger-border: #704240;
76
+ --danger: #ff8c84;
77
+ --danger-hover: #382322;
78
+ --inverse-text: #111315;
79
+ --warm-border: #615d49;
80
+ --reconnecting: #e5b64f;
81
+ --input-surface: rgba(17, 19, 21, .48);
82
+ --hover-overlay: rgba(255, 255, 255, .07);
83
+ --header-surface: rgba(29, 32, 36, .8);
84
+ --details-hover: rgba(255, 255, 255, .06);
85
+ --details-surface: rgba(32, 36, 42, .88);
86
+ --dock-start: rgba(17, 19, 21, 0);
87
+ --dock-end: rgba(17, 19, 21, .94);
88
+ --link-underline: rgba(116, 169, 230, .45);
19
89
  }
20
90
 
21
91
  * { box-sizing: border-box; }
22
92
  html, body { width: 100%; height: 100%; overflow: hidden; }
23
93
  body {
24
94
  margin: 0;
25
- background-color: #faf7ed;
95
+ background-color: var(--page-grid);
26
96
  background-image:
27
- linear-gradient(rgba(182, 165, 119, .2) 1px, transparent 1px),
28
- linear-gradient(90deg, rgba(182, 165, 119, .2) 1px, transparent 1px);
97
+ linear-gradient(var(--grid-line) 1px, transparent 1px),
98
+ linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
29
99
  background-size: 24px 24px;
30
100
  color: var(--text);
31
101
  font: 14px/1.5 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
@@ -75,7 +145,7 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
75
145
  flex-direction: column;
76
146
  padding: 8px 10px;
77
147
  overflow: hidden;
78
- border-right: 1px solid #e8ebee;
148
+ border-right: 1px solid var(--border);
79
149
  background: var(--sidebar);
80
150
  }
81
151
  .sidebar-brand {
@@ -135,7 +205,7 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
135
205
  color: var(--text);
136
206
  font-weight: 550;
137
207
  }
138
- .new-session-button:hover { background: #fafbfc; border-color: #b9c2ca; }
208
+ .new-session-button:hover { background: var(--surface-hover); border-color: var(--border-strong); }
139
209
  .new-session-button svg { width: 17px; height: 17px; flex: 0 0 auto; stroke-width: 1.7; }
140
210
 
141
211
  .workspace-heading {
@@ -158,20 +228,20 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
158
228
  width: 100%;
159
229
  height: 32px;
160
230
  padding: 0 30px 0 29px;
161
- border: 1px solid #dfe3e7;
231
+ border: 1px solid var(--border);
162
232
  border-radius: 16px;
163
233
  outline: 0;
164
- background: rgba(255, 255, 255, .48);
234
+ background: var(--input-surface);
165
235
  color: var(--text);
166
236
  font-size: 12px;
167
237
  }
168
- .session-search input::placeholder { color: #7f8993; }
169
- .session-search input:hover { border-color: #cfd5db; }
170
- .session-search input:focus { border-color: #cfd5db; background: var(--page); box-shadow: none; }
171
- .session-search-icon { position: absolute; top: 9px; left: 9px; z-index: 1; width: 14px; height: 14px; color: #9aa2aa; pointer-events: none; }
172
- .session-search-clear { position: absolute; top: 4px; right: 4px; display: grid; width: 24px; height: 24px; place-items: center; padding: 0; border: 0; border-radius: 50%; background: transparent; color: #737b83; }
238
+ .session-search input::placeholder { color: var(--placeholder); }
239
+ .session-search input:hover { border-color: var(--border-strong); }
240
+ .session-search input:focus { border-color: var(--border-strong); background: var(--page); box-shadow: none; }
241
+ .session-search-icon { position: absolute; top: 9px; left: 9px; z-index: 1; width: 14px; height: 14px; color: var(--icon-muted); pointer-events: none; }
242
+ .session-search-clear { position: absolute; top: 4px; right: 4px; display: grid; width: 24px; height: 24px; place-items: center; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--clear-muted); }
173
243
  .session-search-clear .icon { width: 14px; height: 14px; stroke-width: 2; }
174
- .session-search-clear:hover { background: #e9ecef; color: var(--text); }
244
+ .session-search-clear:hover { background: var(--surface-selected); color: var(--text); }
175
245
 
176
246
  .workspace-tree {
177
247
  min-height: 0;
@@ -193,7 +263,7 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
193
263
  gap: 4px;
194
264
  align-items: center;
195
265
  padding: 0 4px;
196
- color: #39434d;
266
+ color: var(--secondary-text);
197
267
  cursor: pointer;
198
268
  }
199
269
  .workspace-button:hover, .session:hover { background: var(--sidebar-hover); }
@@ -217,7 +287,7 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
217
287
  }
218
288
  .workspace-toggle { width: 20px; height: 28px; }
219
289
  .workspace-action { width: 24px; height: 28px; }
220
- .workspace-toggle:hover, .workspace-action:hover { background: rgba(255, 255, 255, .72); color: var(--text); }
290
+ .workspace-toggle:hover, .workspace-action:hover { background: var(--hover-overlay); color: var(--text); }
221
291
  .workspace-action .icon { width: 17px; height: 17px; }
222
292
  .workspace-row-actions { display: flex; width: 52px; align-items: center; justify-content: flex-end; gap: 2px; }
223
293
  .workspace-chevron { width: 12px; height: 12px; color: var(--subtle); transition: transform 140ms ease; }
@@ -238,7 +308,7 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
238
308
  gap: 8px;
239
309
  align-items: center;
240
310
  padding: 0 8px 0 29px;
241
- color: #5f6973;
311
+ color: var(--tertiary-text);
242
312
  }
243
313
  .session.active { background: var(--sidebar-active); color: var(--text); }
244
314
  .session-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -288,7 +358,7 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
288
358
  background: transparent;
289
359
  text-align: left;
290
360
  }
291
- .workspace-menu button:hover { background: #f1f3f5; }
361
+ .workspace-menu button:hover { background: var(--surface-soft); }
292
362
  .workspace-menu .danger-action { color: var(--error); }
293
363
  .workspace-delete-dialog { width: min(380px, calc(100% - 32px)); padding: 0; border: 0; border-radius: 24px; background: var(--page); box-shadow: 0 20px 60px rgba(31, 37, 44, .2); color: var(--text); }
294
364
  .workspace-delete-dialog::backdrop { background: rgba(20, 26, 32, .2); }
@@ -297,8 +367,8 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
297
367
  .workspace-delete-dialog p { margin: 0; color: var(--muted); font-size: 13px; line-height: 1.65; }
298
368
  .workspace-delete-dialog .dialog-actions { margin-top: 6px; }
299
369
  .workspace-delete-dialog .dialog-actions button { min-width: 64px; height: 36px; border-radius: 18px; }
300
- .workspace-delete-dialog .dialog-actions .danger-action { border-color: #f0c6c6; color: #e55353; background: transparent; }
301
- .workspace-delete-dialog .dialog-actions .danger-action:hover { background: #fff3f3; }
370
+ .workspace-delete-dialog .dialog-actions .danger-action { border-color: var(--danger-border); color: var(--danger); background: transparent; }
371
+ .workspace-delete-dialog .dialog-actions .danger-action:hover { background: var(--danger-hover); }
302
372
  .workspace-rename-dialog {
303
373
  width: min(360px, calc(100% - 32px));
304
374
  padding: 0;
@@ -313,7 +383,7 @@ body.sidebar-collapsed .app-shell { grid-template-columns: 56px minmax(0, 1fr);
313
383
  .workspace-rename-dialog input { width: 100%; height: 36px; padding: 0 10px; border: 1px solid var(--border-strong); border-radius: 5px; color: var(--text); }
314
384
  .dialog-actions { display: flex; justify-content: flex-end; gap: 8px; }
315
385
  .dialog-actions button { height: 32px; padding: 0 12px; border: 1px solid var(--border-strong); border-radius: 5px; background: var(--page); }
316
- .dialog-actions #save-workspace-name { border-color: var(--text); background: var(--text); color: #fff; }
386
+ .dialog-actions #save-workspace-name { border-color: var(--text); background: var(--text); color: var(--inverse-text); }
317
387
  body.sidebar-collapsed .session-sidebar { align-items: center; padding: 8px; }
318
388
  body.sidebar-collapsed .sidebar-brand { position: relative; width: 40px; justify-content: center; padding: 0; }
319
389
  body.sidebar-collapsed .brand-word, body.sidebar-collapsed .new-session-button span,
@@ -355,7 +425,7 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
355
425
  gap: 12px;
356
426
  padding: 0 20px;
357
427
  border-bottom: 1px solid var(--border);
358
- background: rgba(251, 250, 245, .76);
428
+ background: var(--header-surface);
359
429
  backdrop-filter: blur(8px);
360
430
  -webkit-backdrop-filter: blur(8px);
361
431
  }
@@ -367,7 +437,7 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
367
437
  .session-header small { color: var(--muted); font-size: 11px; }
368
438
  .connection-state { display: inline-flex; align-items: center; gap: 6px; color: var(--healthy); font-size: 11px; }
369
439
  .connection-state::before { width: 6px; height: 6px; border-radius: 50%; background: currentColor; content: ""; }
370
- .connection-state.reconnecting { color: #9a6700; }
440
+ .connection-state.reconnecting { color: var(--reconnecting); }
371
441
 
372
442
  .conversation { min-height: 0; overflow-y: auto; scroll-behavior: smooth; }
373
443
  .landing .conversation { display: grid; place-items: center; }
@@ -393,7 +463,7 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
393
463
  .message-content { min-width: 0; max-width: min(78%, 560px); }
394
464
  .message-row.assistant .message-content { width: 100%; max-width: none; }
395
465
  .message-row.assistant .message-details { width: min(760px, calc(100% - 4px)); margin-right: auto; margin-left: auto; }
396
- .message-body { color: #252c33; font-size: 14px; line-height: 1.7; overflow-wrap: anywhere; white-space: pre-wrap; }
466
+ .message-body { color: var(--text); font-size: 14px; line-height: 1.7; overflow-wrap: anywhere; white-space: pre-wrap; }
397
467
  .message-row.user .message-body { padding: 10px 14px; border-radius: 18px 18px 4px 18px; background: var(--sidebar-active); color: var(--text); }
398
468
  .message-body.markdown { white-space: normal; }
399
469
  .message-body.markdown > :first-child { margin-top: 0; }
@@ -413,24 +483,24 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
413
483
  .message-body.markdown li + li { margin-top: 4px; }
414
484
  .message-body.markdown blockquote { margin: 0 0 12px; padding: 2px 14px; border-left: 3px solid var(--border-strong); color: var(--muted); }
415
485
  .message-body.markdown hr { margin: 18px 0; border: 0; border-top: 1px solid var(--border); }
416
- .message-body.markdown a { color: var(--accent); text-decoration: underline; text-decoration-color: rgba(40, 103, 178, .35); text-underline-offset: 2px; }
417
- .message-body.markdown code { padding: 2px 5px; border-radius: 4px; background: #eef1f4; color: #39434d; font: .9em ui-monospace, SFMono-Regular, Menlo, monospace; }
418
- .message-body.markdown pre { margin: 0 0 14px; overflow-x: auto; padding: 12px 14px; border: 1px solid var(--border); border-radius: 8px; background: #f5f6f7; }
486
+ .message-body.markdown a { color: var(--accent); text-decoration: underline; text-decoration-color: var(--link-underline); text-underline-offset: 2px; }
487
+ .message-body.markdown code { padding: 2px 5px; border-radius: 4px; background: var(--surface-selected); color: var(--secondary-text); font: .9em ui-monospace, SFMono-Regular, Menlo, monospace; }
488
+ .message-body.markdown pre { margin: 0 0 14px; overflow-x: auto; padding: 12px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-code); }
419
489
  .message-body.markdown pre code { padding: 0; background: transparent; color: var(--text); font-size: 12px; white-space: pre; }
420
490
  .message-body.markdown table { width: 100%; margin: 0 0 14px; border-collapse: collapse; font-size: .95em; }
421
491
  .message-body.markdown th, .message-body.markdown td { padding: 7px 9px; border: 1px solid var(--border); text-align: left; vertical-align: top; }
422
- .message-body.markdown th { background: #f4f5f6; font-weight: 650; }
492
+ .message-body.markdown th { background: var(--surface-soft); font-weight: 650; }
423
493
  .message-body.markdown input[type="checkbox"] { margin-right: 7px; accent-color: var(--accent); }
424
494
  .message-details { width: min(760px, calc(100% - 48px)); margin: 4px auto; color: var(--muted); }
425
495
  .message-details summary { display: flex; min-height: 34px; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 7px; cursor: pointer; list-style: none; font-size: 13px; }
426
496
  .message-details summary::-webkit-details-marker { display: none; }
427
- .message-details summary:hover { background: rgba(238, 241, 244, .72); }
497
+ .message-details summary:hover { background: var(--details-hover); }
428
498
  .details-mark { width: 8px; height: 8px; flex: 0 0 auto; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); transition: transform 140ms ease; }
429
499
  .message-details[open] .details-mark { transform: rotate(45deg); }
430
500
  .details-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
431
501
  .assistant-detail { margin: 2px 0 4px; }
432
502
  .assistant-detail .details-body { max-height: 280px; }
433
- .details-body { max-height: 360px; margin: 2px 0 0 24px; overflow: auto; padding: 12px 14px; border: 1px solid var(--border); border-radius: 8px; background: rgba(247, 248, 249, .82); }
503
+ .details-body { max-height: 360px; margin: 2px 0 0 24px; overflow: auto; padding: 12px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--details-surface); }
434
504
  .tool-evidence { color: var(--muted); font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; white-space: pre-wrap; }
435
505
 
436
506
  .composer-dock {
@@ -439,7 +509,7 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
439
509
  align-items: center;
440
510
  gap: 8px;
441
511
  padding: 12px 24px 22px;
442
- background: linear-gradient(to bottom, rgba(250, 247, 237, 0), rgba(250, 247, 237, .94) 18px);
512
+ background: linear-gradient(to bottom, var(--dock-start), var(--dock-end) 18px);
443
513
  }
444
514
  .composer {
445
515
  position: relative;
@@ -454,9 +524,9 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
454
524
  background: var(--page);
455
525
  box-shadow: 0 8px 26px rgba(53, 78, 117, .1);
456
526
  }
457
- .composer:focus-within { border-color: #d8cfae; box-shadow: 0 0 0 2px rgba(216, 207, 174, .28), 0 8px 26px rgba(86, 76, 48, .1); }
527
+ .composer:focus-within { border-color: var(--warm-border); box-shadow: 0 0 0 2px color-mix(in srgb, var(--warm-border) 28%, transparent), 0 8px 26px rgba(0, 0, 0, .14); }
458
528
  .composer.dormant { border-style: dashed; box-shadow: none; cursor: pointer; }
459
- .composer.dormant:hover { border-color: #8d98a3; }
529
+ .composer.dormant:hover { border-color: var(--border-strong); }
460
530
  .composer.dormant textarea { cursor: pointer; }
461
531
  .composer textarea { width: 100%; min-width: 0; min-height: 52px; max-height: 220px; flex: 0 0 auto; padding: 0 2px; resize: none; overflow-y: hidden; border: 0; outline: 0; background: transparent; color: var(--text); font-size: 14px; line-height: 1.55; scrollbar-width: thin; scrollbar-color: rgba(125, 132, 138, .45) transparent; }
462
532
  .composer textarea::placeholder { color: var(--subtle); }
@@ -472,7 +542,7 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
472
542
  .model-picker-wrap { position: relative; min-width: 0; max-width: 48%; }
473
543
  .model-picker { display: inline-flex; min-width: 150px; max-width: 100%; height: 34px; align-items: center; justify-content: space-between; gap: 8px; margin-right: 0; padding: 0 9px 0 10px; border: 1px solid transparent; border-radius: 8px; outline: 0; background: transparent; color: var(--muted); font-size: 13px; text-align: left; }
474
544
  .model-picker:not(:disabled) { cursor: pointer; }
475
- .model-picker:not(:disabled):hover, .model-picker[aria-expanded="true"] { border-color: var(--border); background: #f7f8f9; color: var(--text); }
545
+ .model-picker:not(:disabled):hover, .model-picker[aria-expanded="true"] { border-color: var(--border); background: var(--surface-hover); color: var(--text); }
476
546
  .model-picker:disabled { color: var(--subtle); cursor: default; }
477
547
  .model-picker-value { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
478
548
  .model-picker-chevron { width: 14px; height: 14px; flex: 0 0 auto; color: var(--subtle); transition: transform 140ms ease; }
@@ -480,7 +550,7 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
480
550
  .model-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 8; width: 240px; max-height: 300px; overflow-y: auto; padding: 5px; border: 1px solid var(--border); border-radius: 10px; background: var(--page); box-shadow: 0 12px 28px rgba(31, 37, 44, .16); scrollbar-width: thin; scrollbar-color: rgba(125, 132, 138, .45) transparent; }
481
551
  .model-menu[hidden] { display: none; }
482
552
  .model-menu button { display: flex; width: 100%; min-height: 34px; align-items: center; justify-content: space-between; gap: 10px; padding: 0 9px; border: 0; border-radius: 7px; background: transparent; color: var(--text); font-size: 13px; text-align: left; }
483
- .model-menu button:hover, .model-menu button[aria-selected="true"] { background: #eef1f4; }
553
+ .model-menu button:hover, .model-menu button[aria-selected="true"] { background: var(--surface-selected); }
484
554
  .model-menu-check { visibility: hidden; color: var(--text); font-size: 15px; }
485
555
  .model-menu button[aria-selected="true"] .model-menu-check { visibility: visible; }
486
556
  .workspace-tree::-webkit-scrollbar, .model-menu::-webkit-scrollbar, .composer textarea::-webkit-scrollbar { width: 6px; height: 6px; }
@@ -488,7 +558,7 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
488
558
  .workspace-tree::-webkit-scrollbar-thumb, .model-menu::-webkit-scrollbar-thumb, .composer textarea::-webkit-scrollbar-thumb { border-radius: 999px; background: rgba(125, 132, 138, .45); }
489
559
  .workspace-picker-row { display: flex; width: min(780px, 100%); min-width: 0; align-items: center; margin: 0 auto; padding-left: 15px; }
490
560
  .workspace-picker { position: relative; display: inline-flex; width: fit-content; max-width: 100%; min-width: 0; height: 36px; align-items: center; justify-content: center; gap: 0; padding: 0 10px 0 0; padding-right: 28px; padding-left: 28px; border: 1px solid transparent; border-radius: 18px; background: transparent; color: var(--text); font-size: 13px; line-height: 1; text-align: center; transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease; }
491
- .workspace-picker:hover, .workspace-picker[aria-expanded="true"] { border-color: #d8cfae; background: var(--sidebar-active); box-shadow: 0 3px 10px rgba(86, 76, 48, .08); }
561
+ .workspace-picker:hover, .workspace-picker[aria-expanded="true"] { border-color: var(--warm-border); background: var(--sidebar-active); box-shadow: 0 3px 10px rgba(0, 0, 0, .1); }
492
562
  .workspace-picker span { min-width: 0; overflow: hidden; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
493
563
  .workspace-symbol { position: absolute; left: 8px; width: 15px; height: 15px; }
494
564
  .context-chevron { position: absolute; right: 8px; width: 13px; height: 13px; }
@@ -496,8 +566,8 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
496
566
  .workspace-picker-menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 5; width: 225px; padding: 5px; border: 1px solid var(--border); border-radius: 12px; background: var(--page); box-shadow: 0 12px 28px rgba(31, 37, 44, .16); }
497
567
  .workspace-picker-menu[hidden] { display: none; }
498
568
  .workspace-picker-menu button { display: flex; width: 100%; height: 38px; align-items: center; gap: 8px; padding: 0 10px; border: 0; border-radius: 8px; background: transparent; color: var(--text); font-size: 12px; text-align: left; }
499
- .workspace-picker-menu button:hover { background: #f1f3f5; }
500
- .workspace-picker-menu button[aria-selected="true"] { background: #f4f5f6; }
569
+ .workspace-picker-menu button:hover { background: var(--surface-soft); }
570
+ .workspace-picker-menu button[aria-selected="true"] { background: var(--surface-soft); }
501
571
  .workspace-menu-icon { width: 16px; height: 16px; flex: 0 0 auto; color: var(--muted); }
502
572
  .workspace-picker-menu .workspace-menu-check { visibility: hidden; margin-left: auto; font-size: 16px; }
503
573
  .workspace-picker-menu button[aria-selected="true"] .workspace-menu-check { visibility: visible; }
@@ -506,8 +576,16 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
506
576
  .send-button:hover { background: var(--warm-accent-hover); }
507
577
  .send-button:disabled { background: var(--warm-accent-disabled); color: var(--subtle); }
508
578
  .send-button svg { width: 17px; height: 17px; stroke-width: 2; }
579
+ .stop-button { display: grid; width: 34px; height: 34px; flex: 0 0 auto; place-items: center; border: 1px solid #d6cbc1; border-radius: 50%; background: #f7eee8; color: #8a3f32; }
580
+ .stop-button:hover { border-color: #c8b3a5; background: #f1e2d9; }
581
+ .stop-button:disabled { border-color: var(--border); background: #f3f1ed; color: var(--subtle); }
582
+ .stop-button[hidden] { display: none; }
583
+ .stop-button svg { width: 16px; height: 16px; fill: currentColor; stroke: none; }
509
584
  .composer-hint { display: none; }
585
+ .composer-hint.status, .composer-hint.error, .composer-hint.connection { display: block; margin: 7px 2px 0; color: var(--muted); font-size: 11px; line-height: 1.35; }
586
+ .composer-hint.receipt { display: block; color: var(--subtle); }
510
587
  .composer-hint.error { color: var(--error); }
588
+ .composer-hint.connection { color: #9a6700; }
511
589
  .sidebar-scrim { display: none; }
512
590
 
513
591
  @media (max-width: 760px) {
@@ -551,6 +629,8 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
551
629
  .conversation { scroll-behavior: auto; }
552
630
  }
553
631
 
632
+ .composer-hint.status, .composer-hint.error, .composer-hint.connection { display: block; }
633
+
554
634
  /* The conversation view should start with the actual messages. On narrow
555
635
  screens keep only the sidebar trigger as an overlay so navigation remains
556
636
  available without restoring the session header. */
@@ -567,6 +647,8 @@ body.sidebar-collapsed .icon-button { width: 36px; height: 36px; }
567
647
  padding: 0;
568
648
  border: 0;
569
649
  background: transparent;
650
+ backdrop-filter: none;
651
+ -webkit-backdrop-filter: none;
570
652
  pointer-events: none;
571
653
  }
572
654
  .workbench-header .session-header,