clay-server 3.3.2-beta.3 → 3.4.0-beta.10

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 (77) hide show
  1. package/lib/daemon-projects.js +3 -3
  2. package/lib/daemon.js +1 -1
  3. package/lib/project-connection.js +20 -5
  4. package/lib/project-debate.js +4 -0
  5. package/lib/project-file-watch.js +77 -16
  6. package/lib/project-mate-interaction.js +21 -1
  7. package/lib/project-memory.js +3 -0
  8. package/lib/project-shell-command.js +160 -0
  9. package/lib/project-user-message.js +10 -0
  10. package/lib/project.js +19 -4
  11. package/lib/public/antigravity-avatar.png +0 -0
  12. package/lib/public/app.js +28 -0
  13. package/lib/public/copilot-avatar.svg +5 -0
  14. package/lib/public/css/command-palette.css +22 -2
  15. package/lib/public/css/icon-strip.css +29 -13
  16. package/lib/public/css/input.css +79 -0
  17. package/lib/public/css/mates.css +7 -0
  18. package/lib/public/css/menus.css +48 -14
  19. package/lib/public/css/messages.css +9 -0
  20. package/lib/public/css/pane.css +4 -0
  21. package/lib/public/css/pwa-mobile.css +17 -0
  22. package/lib/public/css/title-bar.css +19 -0
  23. package/lib/public/grok-avatar.svg +4 -0
  24. package/lib/public/index.html +43 -4
  25. package/lib/public/junie-avatar.svg +11 -0
  26. package/lib/public/kimi-avatar.svg +4 -0
  27. package/lib/public/modules/app-header.js +4 -0
  28. package/lib/public/modules/app-messages.js +28 -5
  29. package/lib/public/modules/app-panels.js +37 -5
  30. package/lib/public/modules/app-projects.js +3 -1
  31. package/lib/public/modules/app-rendering.js +22 -1
  32. package/lib/public/modules/input.js +58 -28
  33. package/lib/public/modules/mate-sidebar.js +17 -3
  34. package/lib/public/modules/notifications.js +7 -1
  35. package/lib/public/modules/pane-bridge.js +11 -0
  36. package/lib/public/modules/pane-links.js +23 -0
  37. package/lib/public/modules/project-switcher.js +7 -6
  38. package/lib/public/modules/shell-command.js +148 -0
  39. package/lib/public/modules/sidebar-mates.js +7 -1
  40. package/lib/public/modules/sidebar-mobile.js +2 -1
  41. package/lib/public/modules/sidebar-projects.js +34 -43
  42. package/lib/public/modules/sidebar-sessions.js +6 -6
  43. package/lib/public/modules/split-pair-ui.js +3 -2
  44. package/lib/public/modules/tools.js +12 -1
  45. package/lib/public/modules/vendor-priority.js +14 -0
  46. package/lib/public/modules/vendor-selection.js +20 -0
  47. package/lib/public/modules/worktree-location.js +17 -0
  48. package/lib/public/opencode-avatar.svg +4 -0
  49. package/lib/public/qwen-avatar.svg +4 -0
  50. package/lib/public/style.css +3 -2
  51. package/lib/sdk-bridge.js +59 -19
  52. package/lib/sdk-message-processor.js +10 -1
  53. package/lib/session-notes-mcp-server.js +7 -1
  54. package/lib/worktree.js +9 -4
  55. package/lib/ws-schema.js +3 -0
  56. package/lib/yoke/acp-agent-profiles.js +238 -0
  57. package/lib/yoke/acp-driver-runtime.js +50 -0
  58. package/lib/yoke/acp-event-normalizer.js +179 -0
  59. package/lib/yoke/acp-process-manager.js +264 -0
  60. package/lib/yoke/acp-query-handle.js +487 -0
  61. package/lib/yoke/adapters/acp.js +317 -0
  62. package/lib/yoke/adapters/antigravity.js +417 -0
  63. package/lib/yoke/adapters/codex.js +98 -3
  64. package/lib/yoke/adapters/copilot.js +7 -0
  65. package/lib/yoke/adapters/grok.js +7 -0
  66. package/lib/yoke/adapters/junie.js +7 -0
  67. package/lib/yoke/adapters/kimi.js +7 -0
  68. package/lib/yoke/adapters/kiro.js +4 -4
  69. package/lib/yoke/adapters/opencode.js +7 -0
  70. package/lib/yoke/adapters/qwen.js +7 -0
  71. package/lib/yoke/codex-app-server.js +25 -8
  72. package/lib/yoke/index.js +81 -13
  73. package/lib/yoke/instructions.js +3 -0
  74. package/lib/yoke/interface.js +2 -0
  75. package/lib/yoke/kiro-acp-server.js +30 -276
  76. package/lib/yoke/vendor-registry.js +77 -0
  77. package/package.json +1 -1
package/lib/public/app.js CHANGED
@@ -51,6 +51,7 @@ import { initTooltips, registerTooltip } from './modules/tooltip.js';
51
51
  import { initMateWizard, openMateWizard, closeMateWizard, handleMateCreated } from './modules/mate-wizard.js';
52
52
  import { initCommandPalette, handlePaletteSessionSwitch, setPaletteVersion } from './modules/command-palette.js';
53
53
  import { initLongPress } from './modules/longpress.js';
54
+ import { initShellCommand } from './modules/shell-command.js';
54
55
  import { initConnection, connect as _connConnect, setStatus as _connSetStatus, scheduleReconnect as _connScheduleReconnect, cancelReconnect as _connCancelReconnect } from './modules/app-connection.js';
55
56
  import { processMessage as _msgProcessMessage } from './modules/app-messages.js';
56
57
  import { getWs as _getWsRef, setWs as _setWsRef } from './modules/ws-ref.js';
@@ -294,6 +295,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
294
295
  slashCommands: [],
295
296
  processing: false,
296
297
  activeSessionId: null,
298
+ sessionVendorBound: false,
297
299
  cliSessionId: null,
298
300
  isHeadlessMode: false,
299
301
  savedMainSlug: null,
@@ -308,6 +310,9 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
308
310
  returningFromMateDm: false,
309
311
  pendingMateInterview: null,
310
312
  pendingTermCommand: null,
313
+ shellCommandMode: false,
314
+ shellCommandRunning: false,
315
+ pendingShellCommandId: null,
311
316
  mateProjectSlug: null,
312
317
  myUserId: null,
313
318
  isMultiUserMode: false,
@@ -552,6 +557,22 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
552
557
  var newMsgBtnDefault = "\u2193 Latest";
553
558
  var newMsgBtnActivity = "\u2193 New activity";
554
559
 
560
+ // The composer grows for mobile tabs, safe areas, multiline input, and the
561
+ // keyboard. Keep the jump button immediately above its real height instead
562
+ // of relying on one fixed bottom offset.
563
+ function positionNewMsgButton() {
564
+ var inputArea = $("input-area");
565
+ if (!inputArea) return;
566
+ newMsgBtn.style.bottom = (inputArea.offsetHeight + 12) + "px";
567
+ }
568
+ var inputAreaForNewMsgBtn = $("input-area");
569
+ if (inputAreaForNewMsgBtn && window.ResizeObserver) {
570
+ new ResizeObserver(positionNewMsgButton).observe(inputAreaForNewMsgBtn);
571
+ } else {
572
+ window.addEventListener("resize", positionNewMsgButton);
573
+ }
574
+ positionNewMsgButton();
575
+
555
576
  messagesEl.addEventListener("scroll", function () {
556
577
  // While sticky-bottom is armed (e.g. just after history_done or a "New
557
578
  // activity" click), suppress "user scrolled up" detection. Growth-induced
@@ -793,6 +814,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
793
814
  },
794
815
  });
795
816
 
817
+ initShellCommand();
818
+
796
819
  // --- @Mention module ---
797
820
  initMention({
798
821
  get ws() { return _getWsRef(); },
@@ -879,6 +902,10 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
879
902
  if (termBtn) termBtn.style.display = "none";
880
903
  var termSideBtn = document.getElementById("terminal-sidebar-btn");
881
904
  if (termSideBtn) termSideBtn.style.display = "none";
905
+ var shellCommandBtn = document.getElementById("shell-command-btn");
906
+ if (shellCommandBtn) shellCommandBtn.style.display = "none";
907
+ var mobileShellCommandBtn = document.getElementById("input-more-shell");
908
+ if (mobileShellCommandBtn) mobileShellCommandBtn.style.display = "none";
882
909
  }
883
910
  if (!_perms.fileBrowser) {
884
911
  var fbBtn = document.getElementById("file-browser-btn");
@@ -922,6 +949,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
922
949
  messagesEl: messagesEl,
923
950
  sessionListEl: sessionListEl,
924
951
  scrollToBottom: scrollToBottom,
952
+ forceScrollToBottom: forceScrollToBottom,
925
953
  basePath: basePath,
926
954
  toggleUsagePanel: toggleUsagePanel,
927
955
  toggleStatusPanel: toggleStatusPanel,
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="GitHub Copilot CLI">
2
+ <rect width="64" height="64" rx="14" fill="#24292f"/>
3
+ <path d="M15 25c0-8 7-14 17-14s17 6 17 14v15c0 8-7 13-17 13s-17-5-17-13zm8 1v13c0 4 4 7 9 7s9-3 9-7V26c0-4-4-7-9-7s-9 3-9 7z" fill="#fff"/>
4
+ <circle cx="27" cy="30" r="3" fill="#24292f"/><circle cx="37" cy="30" r="3" fill="#24292f"/>
5
+ </svg>
@@ -434,6 +434,7 @@
434
434
  on hover/active, and a 4-direction drop-shadow + white glow on the
435
435
  emoji img for readability on either background. */
436
436
  .project-switcher-item .cmd-palette-item-icon {
437
+ position: relative;
437
438
  width: 44px;
438
439
  height: 44px;
439
440
  font-size: 28px;
@@ -447,6 +448,26 @@
447
448
  flex-shrink: 0;
448
449
  transition: background 0.15s, color 0.15s;
449
450
  }
451
+ .project-switcher-external-badge {
452
+ position: absolute;
453
+ right: -5px;
454
+ bottom: -5px;
455
+ width: 17px;
456
+ height: 17px;
457
+ display: flex;
458
+ align-items: center;
459
+ justify-content: center;
460
+ border: 2px solid var(--bg);
461
+ border-radius: 50%;
462
+ background: var(--warning);
463
+ color: var(--bg);
464
+ pointer-events: none;
465
+ }
466
+ .project-switcher-item .cmd-palette-item-icon .project-switcher-external-badge .lucide {
467
+ width: 9px;
468
+ height: 9px;
469
+ stroke-width: 2.8;
470
+ }
450
471
  .project-switcher-item .cmd-palette-item-icon .lucide {
451
472
  width: 22px;
452
473
  height: 22px;
@@ -515,8 +536,7 @@
515
536
  letter-spacing: 0.5px;
516
537
  }
517
538
 
518
- /* Disabled tile (e.g. worktree with worktreeAccessible: false). Not a
519
- valid switch target, so skip highlight, skip click, visually dim. */
539
+ /* Disabled tiles are skipped by keyboard and pointer selection. */
520
540
  .project-switcher-item.disabled {
521
541
  opacity: 0.35;
522
542
  cursor: not-allowed;
@@ -1257,20 +1257,27 @@
1257
1257
  z-index: 1;
1258
1258
  }
1259
1259
 
1260
- /* Disabled/inaccessible worktree */
1261
- .icon-strip-wt-item.wt-disabled {
1262
- opacity: 0.35;
1263
- cursor: not-allowed;
1264
- }
1265
-
1266
- .icon-strip-wt-item.wt-disabled::after {
1267
- content: "\1F6AB";
1260
+ /* Worktree registered outside the main project folder. It remains usable;
1261
+ the badge communicates location without treating it as an error. */
1262
+ .worktree-external-badge {
1268
1263
  position: absolute;
1269
- font-size: 14px;
1264
+ right: 5px;
1265
+ bottom: 1px;
1266
+ width: 14px;
1267
+ height: 14px;
1268
+ display: flex;
1269
+ align-items: center;
1270
+ justify-content: center;
1271
+ border-radius: 50%;
1272
+ border: 2px solid var(--sidebar-bg);
1273
+ background: var(--warning);
1274
+ color: var(--bg);
1270
1275
  z-index: 3;
1271
- filter: grayscale(0.3);
1276
+ pointer-events: none;
1272
1277
  }
1273
1278
 
1279
+ .worktree-external-badge .lucide { width: 8px; height: 8px; stroke-width: 2.8; }
1280
+
1274
1281
  /* Group add button */
1275
1282
  .icon-strip-group-add {
1276
1283
  width: 30px;
@@ -1420,11 +1427,20 @@ select.wt-modal-input {
1420
1427
  opacity: 0.85;
1421
1428
  }
1422
1429
 
1423
- .mobile-project-item.wt-disabled {
1424
- opacity: 0.35;
1425
- cursor: not-allowed;
1430
+ .mobile-worktree-external-badge {
1431
+ width: 20px;
1432
+ height: 20px;
1433
+ display: inline-flex;
1434
+ align-items: center;
1435
+ justify-content: center;
1436
+ border-radius: 7px;
1437
+ background: color-mix(in srgb, var(--warning) 14%, transparent);
1438
+ color: var(--warning);
1439
+ flex-shrink: 0;
1426
1440
  }
1427
1441
 
1442
+ .mobile-worktree-external-badge .lucide { width: 12px; height: 12px; stroke-width: 2.4; }
1443
+
1428
1444
  .mobile-folder-chevron {
1429
1445
  font-size: 8px;
1430
1446
  color: var(--text-dimmer);
@@ -790,6 +790,7 @@
790
790
  opacity: 0.35;
791
791
  cursor: default;
792
792
  }
793
+ .vendor-toggle-btn.disabled:not(.active) { display: none; }
793
794
  .vendor-toggle-icon {
794
795
  width: 16px;
795
796
  height: 16px;
@@ -799,6 +800,21 @@
799
800
  .vendor-toggle-label {
800
801
  pointer-events: none;
801
802
  }
803
+ .vendor-toggle-btn.experimental::after,
804
+ .vendor-experimental-badge {
805
+ content: "🧪";
806
+ font-size: 10px;
807
+ line-height: 1;
808
+ font-weight: 400;
809
+ filter: saturate(0.85);
810
+ }
811
+ .vendor-experimental-badge {
812
+ margin-left: auto;
813
+ }
814
+ @media (min-width: 901px) {
815
+ .vendor-toggle-btn:not(.active) .vendor-toggle-label { display: none; }
816
+ .vendor-toggle-btn:not(.active) { padding: 0 8px; }
817
+ }
802
818
  @media (max-width: 900px) {
803
819
  .vendor-toggle-label { display: none; }
804
820
  .vendor-toggle-btn { padding: 0 8px; }
@@ -822,6 +838,7 @@
822
838
 
823
839
  #attach-file-btn,
824
840
  #attach-image-btn,
841
+ #shell-command-btn,
825
842
  #schedule-btn,
826
843
  #input-more-btn {
827
844
  width: 36px;
@@ -840,14 +857,76 @@
840
857
 
841
858
  #attach-file-btn .lucide,
842
859
  #attach-image-btn .lucide,
860
+ #shell-command-btn .lucide,
843
861
  #schedule-btn .lucide,
844
862
  #input-more-btn .lucide { width: 20px; height: 20px; flex-shrink: 0; }
845
863
 
846
864
  #attach-file-btn:hover,
847
865
  #attach-image-btn:hover,
866
+ #shell-command-btn:hover,
848
867
  #schedule-btn:hover,
849
868
  #input-more-btn:hover { background: rgba(var(--overlay-rgb), 0.06); color: var(--text); }
850
869
 
870
+ #shell-command-btn.active {
871
+ background: var(--accent-12);
872
+ color: var(--accent);
873
+ }
874
+
875
+ #input-row.shell-command-mode {
876
+ box-shadow: 0 0 0 1px var(--accent);
877
+ }
878
+
879
+ #input-row.shell-command-mode #input {
880
+ font-family: var(--font-mono, "SFMono-Regular", Consolas, monospace);
881
+ }
882
+
883
+ .shell-command-card {
884
+ width: min(760px, calc(100% - 24px));
885
+ margin: 10px auto;
886
+ border: 1px solid var(--border);
887
+ border-radius: 8px;
888
+ background: var(--input-bg);
889
+ overflow: hidden;
890
+ }
891
+
892
+ .shell-command-card.error { border-color: rgba(239, 68, 68, 0.45); }
893
+
894
+ .shell-command-header {
895
+ display: flex;
896
+ align-items: center;
897
+ gap: 8px;
898
+ padding: 9px 12px;
899
+ border-bottom: 1px solid var(--border);
900
+ color: var(--text-secondary);
901
+ font-size: 12px;
902
+ }
903
+
904
+ .shell-command-header code {
905
+ min-width: 0;
906
+ flex: 1;
907
+ overflow: hidden;
908
+ text-overflow: ellipsis;
909
+ white-space: nowrap;
910
+ color: var(--text);
911
+ }
912
+
913
+ .shell-command-icon { display: inline-flex; }
914
+ .shell-command-icon .lucide { width: 16px; height: 16px; }
915
+ .shell-command-status { flex-shrink: 0; color: var(--text-muted); }
916
+
917
+ .shell-command-card.running .shell-command-status { color: var(--accent); }
918
+
919
+ .shell-command-output {
920
+ max-height: 320px;
921
+ margin: 0;
922
+ padding: 12px;
923
+ overflow: auto;
924
+ color: var(--text-secondary);
925
+ font: 12px/1.5 var(--font-mono, "SFMono-Regular", Consolas, monospace);
926
+ white-space: pre-wrap;
927
+ word-break: break-word;
928
+ }
929
+
851
930
  #ask-mate-btn {
852
931
  width: 36px;
853
932
  height: 36px;
@@ -682,6 +682,13 @@
682
682
  .mate-vendor-label {
683
683
  pointer-events: none;
684
684
  }
685
+ .mate-vendor-btn.experimental::after {
686
+ content: "🧪";
687
+ font-size: 9px;
688
+ line-height: 1;
689
+ font-weight: 400;
690
+ }
691
+ .mate-vendor-btn:not(.active) .mate-vendor-label { display: none; }
685
692
 
686
693
  /* Collapse button inside mate header: white to match header style */
687
694
  .mate-sidebar-header .sidebar-collapse-btn {
@@ -44,29 +44,64 @@
44
44
  #header-rename-btn .lucide { width: 13px; height: 13px; }
45
45
 
46
46
  #header-add-worker-btn {
47
- display: flex;
47
+ display: inline-flex;
48
48
  align-items: center;
49
49
  justify-content: center;
50
- width: 24px;
51
- height: 24px;
52
- border: 1px solid transparent;
53
- background: none;
54
- color: var(--text-dimmer);
50
+ gap: 7px;
51
+ width: auto;
52
+ height: 28px;
53
+ border: 1px solid color-mix(in srgb, var(--accent2) 28%, var(--border));
54
+ background: var(--accent2-8);
55
+ color: var(--accent2);
55
56
  cursor: pointer;
56
57
  border-radius: 8px;
57
58
  flex-shrink: 0;
58
- padding: 0;
59
- margin-left: 4px;
59
+ padding: 0 9px 0 7px;
60
+ margin-left: 0;
61
+ font-family: inherit;
62
+ font-size: 11px;
63
+ font-weight: 700;
64
+ line-height: 1;
65
+ white-space: nowrap;
60
66
  transition: color 0.15s, background 0.15s, border-color 0.15s;
61
67
  }
62
- #header-add-worker-btn:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.04); border-color: var(--border); }
63
- #header-add-worker-btn .lucide { width: 13px; height: 13px; }
68
+ #header-add-worker-btn:hover {
69
+ color: var(--accent2-hover);
70
+ background: var(--accent2-15);
71
+ border-color: color-mix(in srgb, var(--accent2) 48%, var(--border));
72
+ }
73
+ .header-worker-icon {
74
+ position: relative;
75
+ display: inline-flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ width: 16px;
79
+ height: 16px;
80
+ flex-shrink: 0;
81
+ }
82
+ .header-worker-icon > .lucide { width: 15px; height: 15px; }
83
+ .header-worker-add-badge {
84
+ position: absolute;
85
+ right: -4px;
86
+ bottom: -3px;
87
+ display: inline-flex;
88
+ align-items: center;
89
+ justify-content: center;
90
+ width: 9px;
91
+ height: 9px;
92
+ border-radius: 50%;
93
+ background: var(--accent2);
94
+ color: var(--bg);
95
+ box-shadow: 0 0 0 2px var(--bg);
96
+ }
97
+ .header-worker-add-badge .lucide { width: 7px; height: 7px; stroke-width: 3; }
98
+ .header-worker-label { letter-spacing: 0.01em; }
64
99
  #header-add-worker-btn.hidden { display: none; }
65
100
  body.dm-mode #header-add-worker-btn { display: none; }
66
101
 
67
- /* "Close terminal" button: sits just left of the rename pencil during a live
68
- TUI session. Matches the rename button's chrome; reds out on hover since it
69
- stops the running claude (the session stays resumable). */
102
+ /* "Close terminal" button for a live TUI session. Matches the session-control
103
+ chrome; reds out on hover since it stops the running agent while preserving
104
+ the resumable session. */
70
105
  #header-tui-close-btn {
71
106
  display: flex;
72
107
  align-items: center;
@@ -980,4 +1015,3 @@ body.dm-mode #header-add-worker-btn { display: none; }
980
1015
  #config-chip .config-chip-icon { display: inline; width: 14px; height: 14px; }
981
1016
  #config-chip-label { display: none; }
982
1017
  }
983
-
@@ -5,12 +5,21 @@
5
5
  #messages {
6
6
  flex: 1;
7
7
  overflow-y: auto;
8
+ overflow-x: hidden;
8
9
  -webkit-overflow-scrolling: touch;
9
10
  overscroll-behavior-y: contain;
10
11
  padding: 20px 0 12px;
11
12
  position: relative;
12
13
  }
13
14
 
15
+ /* Rich message content can contain wide tables, diagrams, or generated HTML.
16
+ Keep that content inside the chat scroller; nested code blocks still own
17
+ their intentional horizontal scrolling. */
18
+ #messages > * {
19
+ min-width: 0;
20
+ max-width: 100%;
21
+ }
22
+
14
23
  /* --- Remote cursors (Figma-style) --- */
15
24
  .remote-cursor {
16
25
  pointer-events: none;
@@ -23,6 +23,10 @@ body.pane-mode #sticky-notes-container {
23
23
  display: none !important;
24
24
  }
25
25
 
26
+ body.pane-mode .notif-banner-container {
27
+ display: none !important;
28
+ }
29
+
26
30
  body.pane-mode #main-area {
27
31
  border: 0;
28
32
  border-radius: 0;
@@ -0,0 +1,17 @@
1
+ /* In an iOS Home Screen app, a 100%-tall root can be measured against the
2
+ shortened safe-area viewport. Use the physical viewport for the root while
3
+ retaining safe-area padding on controls inside the app. */
4
+ @media (max-width: 768px) {
5
+ html.pwa-standalone,
6
+ html.pwa-standalone body {
7
+ height: 100vh;
8
+ }
9
+ }
10
+
11
+ @media (max-width: 768px) and (display-mode: standalone),
12
+ (max-width: 768px) and (display-mode: fullscreen) {
13
+ html,
14
+ body {
15
+ height: 100vh;
16
+ }
17
+ }
@@ -324,6 +324,25 @@
324
324
  display: none !important;
325
325
  }
326
326
 
327
+ .title-bar-content {
328
+ height: calc(48px + var(--safe-top));
329
+ padding: var(--safe-top) 16px 0;
330
+ }
331
+
332
+ /* The inline title editor must own the header while the keyboard is open.
333
+ Leaving the other controls visible made its usable width nearly zero. */
334
+ .title-bar-content.session-renaming .status,
335
+ .title-bar-content.session-renaming #header-left > :not(.header-rename-input) {
336
+ display: none !important;
337
+ }
338
+
339
+ .title-bar-content.session-renaming .header-rename-input {
340
+ flex: 1 1 100%;
341
+ width: 100%;
342
+ min-height: 36px;
343
+ font-size: 16px;
344
+ }
345
+
327
346
  #sidebar-column {
328
347
  width: 0 !important;
329
348
  min-width: 0 !important;
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Grok Build">
2
+ <rect width="64" height="64" rx="14" fill="#111"/>
3
+ <path d="M45 17A21 21 0 1 0 49 42H35v-9h22v4A25 25 0 1 1 51 13z" fill="#fff"/>
4
+ </svg>
@@ -30,7 +30,7 @@
30
30
  (function(){try{var k="clay-theme-vars",v=localStorage.getItem(k),r=document.documentElement;if(v){var o=JSON.parse(v),p;for(p in o)r.style.setProperty(p,o[p]);var vt=localStorage.getItem(k.replace("-vars","-variant"));if(vt==="light"){r.classList.add("light-theme");r.classList.remove("dark-theme")}else{r.classList.add("dark-theme");r.classList.remove("light-theme")}var m=document.querySelector('meta[name="theme-color"]');if(m&&o["--bg"])m.setAttribute("content",o["--bg"])}else{var sl=window.matchMedia&&window.matchMedia("(prefers-color-scheme: light)").matches;if(sl){r.classList.add("light-theme");r.classList.remove("dark-theme")}}}catch(e){}})();
31
31
  </script>
32
32
  <script>if(window.navigator.standalone||window.matchMedia("(display-mode:standalone)").matches){document.documentElement.classList.add("pwa-standalone")}</script>
33
- <link rel="stylesheet" href="style.css?v=20260407">
33
+ <link rel="stylesheet" href="style.css?v=20260824f">
34
34
  <style>
35
35
  @media(max-width:768px){
36
36
  /* User messages: vertical stack, avatar on top, right-aligned */
@@ -373,12 +373,11 @@
373
373
  </div>
374
374
  <button id="hamburger-btn" aria-label="Toggle sidebar" title="Toggle sidebar"><i data-lucide="menu"></i></button>
375
375
  <span class="header-title" id="header-title">Connecting...</span>
376
+ <button id="header-rename-btn" type="button" title="Rename session"><i data-lucide="pencil"></i></button>
376
377
  <button id="header-info-btn" type="button" title="Session info"><i data-lucide="info"></i></button>
377
378
  <button id="header-full-access-btn" type="button" class="session-full-access hidden" role="switch" aria-checked="false" title="Skip Permissions is off — permission prompts are on">
378
379
  <span class="session-full-access-label">Skip Permissions</span><span class="session-full-access-track" aria-hidden="true"><span></span></span>
379
380
  </button>
380
- <button id="header-rename-btn" type="button" title="Rename session"><i data-lucide="pencil"></i></button>
381
- <button id="header-add-worker-btn" type="button" title="Add Worker — this session becomes the Driver of a pair"><i data-lucide="user-plus"></i></button>
382
381
  <button type="button" id="header-tui-close-btn" class="header-tui-close-btn hidden" title="Close terminal (keeps history, resume anytime)" aria-label="Close terminal"><i data-lucide="power"></i></button>
383
382
  <div id="mate-mobile-title" class="mate-mobile-title hidden">
384
383
  <img id="mate-mobile-avatar" class="mate-mobile-avatar" alt="">
@@ -389,6 +388,13 @@
389
388
  <div id="ralph-sticky" class="hidden"></div>
390
389
  <div id="debate-sticky" class="hidden"></div>
391
390
  <div class="status">
391
+ <button id="header-add-worker-btn" type="button" aria-label="Add AI Worker" title="Add an AI Worker — this session becomes the Driver of a pair">
392
+ <span class="header-worker-icon" aria-hidden="true">
393
+ <i data-lucide="bot"></i>
394
+ <span class="header-worker-add-badge"><i data-lucide="plus"></i></span>
395
+ </span>
396
+ <span class="header-worker-label">Add Worker</span>
397
+ </button>
392
398
  <button type="button" id="header-tui-font-btn" class="header-tui-font-btn hidden" title="Terminal font" aria-label="Terminal font">
393
399
  <i data-lucide="type"></i>
394
400
  </button>
@@ -505,6 +511,7 @@
505
511
  <button id="input-more-btn" type="button" aria-label="More options" title="More options" class="mobile-only"><i data-lucide="plus"></i></button>
506
512
  <button id="attach-file-btn" type="button" aria-label="Attach file" title="Attach file" class="desktop-only"><i data-lucide="paperclip"></i></button>
507
513
  <button id="attach-image-btn" type="button" aria-label="Attach image" title="Attach image" class="desktop-only"><i data-lucide="image"></i></button>
514
+ <button id="shell-command-btn" type="button" aria-label="Run shell command" aria-pressed="false" title="Run a shell command and add its output to the next agent message" class="desktop-only"><i data-lucide="square-terminal"></i></button>
508
515
  <button id="stt-btn" type="button" aria-label="Voice input" title="Voice input"><i data-lucide="mic"></i></button>
509
516
  <button id="schedule-btn" type="button" aria-label="Schedule message" title="Schedule message"><i data-lucide="clock"></i></button>
510
517
  <button id="ask-mate-btn" type="button" aria-label="Ask Mate" title="Ask a Mate for advice on this session"><i data-lucide="at-sign"></i></button>
@@ -527,6 +534,34 @@
527
534
  <img src="/codex-avatar.png" class="vendor-toggle-icon" alt="Codex">
528
535
  <span class="vendor-toggle-label">Codex</span>
529
536
  </button>
537
+ <button id="vendor-btn-antigravity" class="vendor-toggle-btn" data-vendor="antigravity">
538
+ <img src="/antigravity-avatar.png" class="vendor-toggle-icon" alt="Antigravity">
539
+ <span class="vendor-toggle-label">Antigravity CLI</span>
540
+ </button>
541
+ <button id="vendor-btn-opencode" class="vendor-toggle-btn" data-vendor="opencode">
542
+ <img src="/opencode-avatar.svg" class="vendor-toggle-icon" alt="OpenCode">
543
+ <span class="vendor-toggle-label">OpenCode</span>
544
+ </button>
545
+ <button id="vendor-btn-kimi" class="vendor-toggle-btn" data-vendor="kimi">
546
+ <img src="/kimi-avatar.svg" class="vendor-toggle-icon" alt="Kimi">
547
+ <span class="vendor-toggle-label">Kimi Code</span>
548
+ </button>
549
+ <button id="vendor-btn-grok" class="vendor-toggle-btn" data-vendor="grok">
550
+ <img src="/grok-avatar.svg" class="vendor-toggle-icon" alt="Grok">
551
+ <span class="vendor-toggle-label">Grok Build</span>
552
+ </button>
553
+ <button id="vendor-btn-copilot" class="vendor-toggle-btn" data-vendor="copilot">
554
+ <img src="/copilot-avatar.svg" class="vendor-toggle-icon" alt="GitHub Copilot">
555
+ <span class="vendor-toggle-label">GitHub Copilot CLI</span>
556
+ </button>
557
+ <button id="vendor-btn-qwen" class="vendor-toggle-btn" data-vendor="qwen">
558
+ <img src="/qwen-avatar.svg" class="vendor-toggle-icon" alt="Qwen">
559
+ <span class="vendor-toggle-label">Qwen Code</span>
560
+ </button>
561
+ <button id="vendor-btn-junie" class="vendor-toggle-btn" data-vendor="junie">
562
+ <img src="/junie-avatar.svg" class="vendor-toggle-icon" alt="Junie">
563
+ <span class="vendor-toggle-label">Junie CLI</span>
564
+ </button>
530
565
  <button id="vendor-btn-kiro" class="vendor-toggle-btn" data-vendor="kiro">
531
566
  <img src="/kiro-avatar.svg" class="vendor-toggle-icon" alt="Kiro">
532
567
  <span class="vendor-toggle-label">Kiro CLI</span>
@@ -607,6 +642,10 @@
607
642
  <i data-lucide="image"></i>
608
643
  <span>Image</span>
609
644
  </button>
645
+ <button class="input-more-action" id="input-more-shell">
646
+ <i data-lucide="square-terminal"></i>
647
+ <span>Shell command</span>
648
+ </button>
610
649
  </div>
611
650
  <div class="input-more-divider"></div>
612
651
  <div class="input-more-section-label">
@@ -2325,7 +2364,7 @@
2325
2364
  <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0/lib/addon-fit.min.js"></script>
2326
2365
  <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-web-links@0/lib/addon-web-links.min.js"></script>
2327
2366
  <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-webgl@0/lib/addon-webgl.min.js"></script>
2328
- <script type="module" src="app.js"></script>
2367
+ <script type="module" src="app.js?v=20260824g"></script>
2329
2368
  <div id="pwa-install-modal" class="pwa-modal hidden">
2330
2369
  <div class="pwa-modal-backdrop"></div>
2331
2370
  <div class="pwa-modal-card">
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Junie">
2
+ <defs>
3
+ <linearGradient id="junie-gradient" x1="8" y1="8" x2="56" y2="56" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#8B5CF6"/>
5
+ <stop offset="1" stop-color="#F97316"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect width="64" height="64" rx="15" fill="url(#junie-gradient)"/>
9
+ <path d="M39 15v26c0 7.7-5.4 12-13.2 12-5.3 0-9.4-2.2-12-6.4l7.1-5c1.3 2 2.7 3 4.6 3 2.5 0 4-1.4 4-4.4V15H39Z" fill="#fff"/>
10
+ <circle cx="47.5" cy="17.5" r="4.5" fill="#fff" fill-opacity=".9"/>
11
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Kimi Code">
2
+ <rect width="64" height="64" rx="14" fill="#1769ff"/>
3
+ <path d="M18 14h9v15l13-15h11L36 31l16 19H40L27 34v16h-9z" fill="#fff"/>
4
+ </svg>
@@ -93,6 +93,8 @@ export function initHeader() {
93
93
  input.type = "text";
94
94
  input.className = "header-rename-input";
95
95
  input.value = currentText;
96
+ var titleBar = headerTitleEl.closest(".title-bar-content");
97
+ if (titleBar) titleBar.classList.add("session-renaming");
96
98
  headerTitleEl.style.display = "none";
97
99
  headerRenameBtn.style.display = "none";
98
100
  headerTitleEl.parentNode.insertBefore(input, headerTitleEl.nextSibling);
@@ -117,6 +119,7 @@ export function initHeader() {
117
119
  }
118
120
  }
119
121
  input.remove();
122
+ if (titleBar) titleBar.classList.remove("session-renaming");
120
123
  headerTitleEl.style.display = "";
121
124
  headerRenameBtn.style.display = "";
122
125
  }
@@ -126,6 +129,7 @@ export function initHeader() {
126
129
  if (e.key === "Escape") {
127
130
  e.preventDefault();
128
131
  input.remove();
132
+ if (titleBar) titleBar.classList.remove("session-renaming");
129
133
  headerTitleEl.style.display = "";
130
134
  headerRenameBtn.style.display = "";
131
135
  }