bosun 0.28.2 → 0.28.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +68 -0
- package/README.md +1 -1
- package/agent-prompts.mjs +12 -6
- package/agent-work-analyzer.mjs +39 -15
- package/cli.mjs +4 -1
- package/codex-config.mjs +7 -0
- package/monitor.mjs +83 -24
- package/package.json +2 -1
- package/preflight.mjs +3 -1
- package/primary-agent.mjs +5 -1
- package/pwsh-runtime.mjs +62 -0
- package/setup.mjs +70 -3
- package/task-executor.mjs +125 -2
- package/telegram-bot.mjs +45 -8
- package/ui/app.js +2 -16
- package/ui/components/workspace-switcher.js +25 -32
- package/ui/modules/settings-schema.js +7 -0
- package/ui/styles/base.css +3 -28
- package/ui/styles/components.css +309 -73
- package/ui/styles/kanban.css +10 -16
- package/ui/styles/layout.css +81 -101
- package/ui/styles/sessions.css +27 -32
- package/ui/styles/variables.css +8 -8
- package/ui/styles/workspace-switcher.css +2 -4
- package/ui/tabs/control.js +40 -71
- package/ui/tabs/settings.js +207 -0
- package/ui/tabs/tasks.js +116 -129
- package/ui-server.mjs +487 -0
- package/workspace-manager.mjs +57 -11
package/ui/styles/layout.css
CHANGED
|
@@ -5,43 +5,29 @@
|
|
|
5
5
|
display: flex;
|
|
6
6
|
align-items: center;
|
|
7
7
|
justify-content: space-between;
|
|
8
|
-
height: var(--
|
|
8
|
+
height: calc(44px + var(--content-safe-top));
|
|
9
9
|
padding-top: var(--content-safe-top);
|
|
10
|
-
padding-left: calc(
|
|
11
|
-
padding-right: calc(
|
|
12
|
-
background: var(--
|
|
10
|
+
padding-left: calc(16px + var(--safe-left));
|
|
11
|
+
padding-right: calc(16px + var(--safe-right));
|
|
12
|
+
background: var(--bg-primary);
|
|
13
13
|
border-bottom: 1px solid var(--border);
|
|
14
|
-
box-shadow: var(--shadow-sm);
|
|
15
|
-
backdrop-filter: var(--glass-blur);
|
|
16
|
-
-webkit-backdrop-filter: var(--glass-blur);
|
|
17
14
|
flex-shrink: 0;
|
|
18
15
|
z-index: 10;
|
|
19
16
|
position: relative;
|
|
17
|
+
min-width: 0;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
.app-header::after {
|
|
23
|
-
|
|
24
|
-
position: absolute;
|
|
25
|
-
bottom: 0;
|
|
26
|
-
left: 0;
|
|
27
|
-
right: 0;
|
|
28
|
-
height: 1px;
|
|
29
|
-
background: linear-gradient(
|
|
30
|
-
90deg,
|
|
31
|
-
transparent 0%,
|
|
32
|
-
rgba(59, 130, 246, 0.4) 30%,
|
|
33
|
-
rgba(139, 92, 246, 0.35) 60%,
|
|
34
|
-
transparent 100%
|
|
35
|
-
);
|
|
36
|
-
pointer-events: none;
|
|
21
|
+
display: none;
|
|
37
22
|
}
|
|
38
23
|
|
|
39
24
|
.app-header-left {
|
|
40
25
|
display: flex;
|
|
41
26
|
align-items: center;
|
|
42
|
-
gap:
|
|
27
|
+
gap: 8px;
|
|
43
28
|
min-width: 0;
|
|
44
29
|
flex: 1;
|
|
30
|
+
overflow: hidden;
|
|
45
31
|
}
|
|
46
32
|
|
|
47
33
|
.app-header-brand {
|
|
@@ -199,10 +185,7 @@
|
|
|
199
185
|
overflow-y: auto;
|
|
200
186
|
overflow-x: hidden;
|
|
201
187
|
scrollbar-gutter: stable;
|
|
202
|
-
padding
|
|
203
|
-
padding-right: calc(16px + var(--safe-right));
|
|
204
|
-
padding-bottom: calc(var(--nav-height, 60px) + var(--safe-bottom, 0px) + 24px);
|
|
205
|
-
padding-left: calc(16px + var(--safe-left));
|
|
188
|
+
padding: 12px calc(12px + var(--safe-right)) calc(var(--nav-height, 56px) + var(--safe-bottom, 0px) + 16px) calc(12px + var(--safe-left));
|
|
206
189
|
-webkit-overflow-scrolling: touch;
|
|
207
190
|
scroll-behavior: smooth;
|
|
208
191
|
touch-action: pan-y;
|
|
@@ -246,33 +229,31 @@
|
|
|
246
229
|
to { opacity: 1; transform: translateY(0); }
|
|
247
230
|
}
|
|
248
231
|
|
|
249
|
-
/* ─── Bottom Navigation —
|
|
232
|
+
/* ─── Bottom Navigation — Clean pill bar ─── */
|
|
250
233
|
.bottom-nav {
|
|
251
234
|
position: fixed;
|
|
252
|
-
bottom: calc(
|
|
253
|
-
left: calc(
|
|
254
|
-
right: calc(
|
|
235
|
+
bottom: calc(8px + var(--safe-bottom));
|
|
236
|
+
left: calc(12px + var(--safe-left));
|
|
237
|
+
right: calc(12px + var(--safe-right));
|
|
255
238
|
height: var(--nav-height);
|
|
256
|
-
background: var(--
|
|
257
|
-
border: 1px solid var(--
|
|
239
|
+
background: var(--bg-primary);
|
|
240
|
+
border: 1px solid var(--border);
|
|
258
241
|
border-radius: var(--radius-xl);
|
|
259
242
|
display: flex;
|
|
260
243
|
align-items: center;
|
|
261
244
|
justify-content: space-around;
|
|
262
245
|
z-index: 500;
|
|
263
|
-
box-shadow:
|
|
264
|
-
|
|
265
|
-
-webkit-backdrop-filter: var(--glass-blur);
|
|
266
|
-
animation: navSlideUp 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s both;
|
|
246
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.25);
|
|
247
|
+
animation: navSlideUp 0.3s cubic-bezier(0.25, 1, 0.5, 1) 0.15s both;
|
|
267
248
|
padding-bottom: 0;
|
|
268
249
|
pointer-events: auto;
|
|
269
250
|
}
|
|
270
251
|
|
|
271
252
|
.bottom-nav.compact {
|
|
272
|
-
height: calc(var(--nav-height) -
|
|
273
|
-
padding:
|
|
253
|
+
height: calc(var(--nav-height) - 4px);
|
|
254
|
+
padding: 2px 6px;
|
|
274
255
|
justify-content: space-between;
|
|
275
|
-
gap:
|
|
256
|
+
gap: 2px;
|
|
276
257
|
}
|
|
277
258
|
|
|
278
259
|
@keyframes navSlideUp {
|
|
@@ -655,6 +636,10 @@
|
|
|
655
636
|
}
|
|
656
637
|
|
|
657
638
|
@media (min-width: 1200px) {
|
|
639
|
+
:root {
|
|
640
|
+
--sidebar-width: 220px;
|
|
641
|
+
}
|
|
642
|
+
|
|
658
643
|
body {
|
|
659
644
|
overflow: hidden;
|
|
660
645
|
}
|
|
@@ -691,9 +676,10 @@
|
|
|
691
676
|
background: var(--bg-secondary);
|
|
692
677
|
border: 1px solid var(--border);
|
|
693
678
|
border-radius: var(--radius-lg);
|
|
694
|
-
padding: 16px
|
|
695
|
-
gap:
|
|
679
|
+
padding: 18px 16px;
|
|
680
|
+
gap: 14px;
|
|
696
681
|
box-shadow: var(--shadow-sm);
|
|
682
|
+
min-width: 0;
|
|
697
683
|
}
|
|
698
684
|
|
|
699
685
|
.session-rail {
|
|
@@ -738,9 +724,7 @@
|
|
|
738
724
|
margin-bottom: var(--space-md);
|
|
739
725
|
position: sticky;
|
|
740
726
|
top: 0;
|
|
741
|
-
background: var(--
|
|
742
|
-
backdrop-filter: var(--glass-blur);
|
|
743
|
-
-webkit-backdrop-filter: var(--glass-blur);
|
|
727
|
+
background: var(--bg-primary);
|
|
744
728
|
z-index: 5;
|
|
745
729
|
}
|
|
746
730
|
|
|
@@ -809,9 +793,7 @@
|
|
|
809
793
|
.drawer-overlay {
|
|
810
794
|
position: fixed;
|
|
811
795
|
inset: 0;
|
|
812
|
-
background: rgba(0, 0, 0, 0.
|
|
813
|
-
backdrop-filter: blur(4px);
|
|
814
|
-
-webkit-backdrop-filter: blur(4px);
|
|
796
|
+
background: rgba(0, 0, 0, 0.5);
|
|
815
797
|
z-index: 900;
|
|
816
798
|
animation: fadeIn 0.18s ease-out;
|
|
817
799
|
}
|
|
@@ -889,9 +871,7 @@
|
|
|
889
871
|
gap: 8px;
|
|
890
872
|
padding: 6px 16px;
|
|
891
873
|
align-items: center;
|
|
892
|
-
background: var(--
|
|
893
|
-
backdrop-filter: var(--glass-blur);
|
|
894
|
-
-webkit-backdrop-filter: var(--glass-blur);
|
|
874
|
+
background: var(--bg-primary);
|
|
895
875
|
border-bottom: 1px solid var(--border);
|
|
896
876
|
}
|
|
897
877
|
|
|
@@ -922,11 +902,12 @@
|
|
|
922
902
|
}
|
|
923
903
|
|
|
924
904
|
/* ─── Sidebar styling ─── */
|
|
925
|
-
.sidebar-brand {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
905
|
+
.sidebar-brand {
|
|
906
|
+
display: flex;
|
|
907
|
+
align-items: center;
|
|
908
|
+
gap: 10px;
|
|
909
|
+
min-width: 0;
|
|
910
|
+
}
|
|
930
911
|
|
|
931
912
|
.sidebar-logo {
|
|
932
913
|
width: 40px;
|
|
@@ -946,71 +927,70 @@
|
|
|
946
927
|
height: 20px;
|
|
947
928
|
}
|
|
948
929
|
|
|
949
|
-
.sidebar-title {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
930
|
+
.sidebar-title {
|
|
931
|
+
font-size: 15px;
|
|
932
|
+
font-weight: 600;
|
|
933
|
+
color: var(--text-bright);
|
|
934
|
+
white-space: nowrap;
|
|
935
|
+
overflow: hidden;
|
|
936
|
+
text-overflow: ellipsis;
|
|
937
|
+
}
|
|
954
938
|
|
|
955
939
|
.sidebar-subtitle {
|
|
956
940
|
font-size: 11px;
|
|
957
941
|
color: var(--text-secondary);
|
|
958
942
|
}
|
|
959
943
|
|
|
960
|
-
.sidebar-actions {
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
.sidebar-nav {
|
|
967
|
-
display: flex;
|
|
968
|
-
flex-direction: column;
|
|
969
|
-
gap: 6px;
|
|
970
|
-
flex: 1;
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
.sidebar-nav-item {
|
|
974
|
-
display: flex;
|
|
975
|
-
flex-direction: column;
|
|
976
|
-
align-items: center;
|
|
977
|
-
justify-content: center;
|
|
978
|
-
gap: 4px;
|
|
979
|
-
padding: 10px 6px;
|
|
980
|
-
border-radius: 14px;
|
|
981
|
-
background: transparent;
|
|
982
|
-
border: none;
|
|
983
|
-
color: var(--text-secondary);
|
|
984
|
-
font-size: 10px;
|
|
985
|
-
font-weight: 600;
|
|
986
|
-
cursor: pointer;
|
|
987
|
-
transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
.sidebar-nav-item svg {
|
|
991
|
-
width: 20px;
|
|
992
|
-
height: 20px;
|
|
993
|
-
}
|
|
944
|
+
.sidebar-actions {
|
|
945
|
+
display: flex;
|
|
946
|
+
flex-direction: column;
|
|
947
|
+
gap: 8px;
|
|
948
|
+
}
|
|
994
949
|
|
|
995
|
-
.sidebar-nav
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
950
|
+
.sidebar-nav {
|
|
951
|
+
display: flex;
|
|
952
|
+
flex-direction: column;
|
|
953
|
+
gap: 6px;
|
|
954
|
+
flex: 1;
|
|
955
|
+
min-width: 0;
|
|
956
|
+
}
|
|
999
957
|
|
|
1000
|
-
@media (min-width: 1200px) {
|
|
1001
958
|
.sidebar-nav-item {
|
|
959
|
+
display: flex;
|
|
1002
960
|
flex-direction: row;
|
|
961
|
+
align-items: center;
|
|
1003
962
|
justify-content: flex-start;
|
|
1004
|
-
padding: 10px 12px;
|
|
1005
963
|
gap: 10px;
|
|
964
|
+
padding: 10px 12px;
|
|
965
|
+
border-radius: 12px;
|
|
966
|
+
background: transparent;
|
|
967
|
+
border: none;
|
|
968
|
+
color: var(--text-secondary);
|
|
1006
969
|
font-size: 12px;
|
|
970
|
+
font-weight: 600;
|
|
971
|
+
cursor: pointer;
|
|
972
|
+
transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
|
|
973
|
+
width: 100%;
|
|
974
|
+
text-align: left;
|
|
975
|
+
min-width: 0;
|
|
976
|
+
overflow: hidden;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.sidebar-nav-item svg {
|
|
980
|
+
width: 18px;
|
|
981
|
+
height: 18px;
|
|
982
|
+
flex-shrink: 0;
|
|
1007
983
|
}
|
|
1008
984
|
|
|
1009
985
|
.sidebar-nav-item span {
|
|
1010
986
|
font-size: 12px;
|
|
1011
987
|
letter-spacing: 0.01em;
|
|
988
|
+
white-space: nowrap;
|
|
989
|
+
overflow: hidden;
|
|
990
|
+
text-overflow: ellipsis;
|
|
991
|
+
flex: 1;
|
|
992
|
+
min-width: 0;
|
|
1012
993
|
}
|
|
1013
|
-
}
|
|
1014
994
|
|
|
1015
995
|
.sidebar-nav-item:hover {
|
|
1016
996
|
background: var(--accent-subtle);
|
package/ui/styles/sessions.css
CHANGED
|
@@ -110,8 +110,8 @@
|
|
|
110
110
|
.session-detail-tabs {
|
|
111
111
|
display: flex;
|
|
112
112
|
gap: 2px;
|
|
113
|
-
background: var(--
|
|
114
|
-
border: 1px solid var(--
|
|
113
|
+
background: var(--bg-card);
|
|
114
|
+
border: 1px solid var(--border);
|
|
115
115
|
border-radius: var(--radius-md);
|
|
116
116
|
padding: 3px;
|
|
117
117
|
margin-bottom: var(--space-md);
|
|
@@ -133,13 +133,12 @@
|
|
|
133
133
|
|
|
134
134
|
.session-detail-tab:hover {
|
|
135
135
|
color: var(--text-primary);
|
|
136
|
-
background: var(--
|
|
136
|
+
background: var(--bg-card-hover);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
.session-detail-tab.active {
|
|
140
|
-
background: var(--
|
|
140
|
+
background: var(--accent);
|
|
141
141
|
color: var(--accent-text);
|
|
142
|
-
box-shadow: var(--shadow-glow-sm);
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
/* Back button (mobile) */
|
|
@@ -151,7 +150,7 @@
|
|
|
151
150
|
display: flex;
|
|
152
151
|
align-items: center;
|
|
153
152
|
padding: 0;
|
|
154
|
-
border-bottom: 1px solid var(--border, var(--
|
|
153
|
+
border-bottom: 1px solid var(--border, var(--border));
|
|
155
154
|
background: var(--bg-primary);
|
|
156
155
|
flex-shrink: 0;
|
|
157
156
|
}
|
|
@@ -507,7 +506,7 @@
|
|
|
507
506
|
|
|
508
507
|
.chat-header {
|
|
509
508
|
padding: 12px 16px;
|
|
510
|
-
border-bottom: 1px solid var(--
|
|
509
|
+
border-bottom: 1px solid var(--border);
|
|
511
510
|
flex-shrink: 0;
|
|
512
511
|
display: flex;
|
|
513
512
|
align-items: center;
|
|
@@ -679,8 +678,8 @@
|
|
|
679
678
|
}
|
|
680
679
|
|
|
681
680
|
.chat-filter-chip {
|
|
682
|
-
border: 1px solid var(--
|
|
683
|
-
background: var(--
|
|
681
|
+
border: 1px solid var(--border);
|
|
682
|
+
background: var(--bg-card);
|
|
684
683
|
color: var(--text-secondary);
|
|
685
684
|
font-size: 11px;
|
|
686
685
|
padding: 4px 10px;
|
|
@@ -796,7 +795,7 @@
|
|
|
796
795
|
justify-content: center;
|
|
797
796
|
padding: var(--space-lg);
|
|
798
797
|
gap: var(--space-sm);
|
|
799
|
-
border: 1px dashed var(--
|
|
798
|
+
border: 1px dashed var(--border);
|
|
800
799
|
border-radius: var(--radius-md);
|
|
801
800
|
background: rgba(8, 12, 20, 0.35);
|
|
802
801
|
text-align: center;
|
|
@@ -962,7 +961,7 @@
|
|
|
962
961
|
|
|
963
962
|
.md-blockquote {
|
|
964
963
|
border-left: 3px solid var(--accent);
|
|
965
|
-
background: var(--
|
|
964
|
+
background: var(--bg-card);
|
|
966
965
|
padding: 6px 12px;
|
|
967
966
|
margin: 4px 0;
|
|
968
967
|
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
|
|
@@ -1003,8 +1002,8 @@ ul.md-list li::before {
|
|
|
1003
1002
|
}
|
|
1004
1003
|
|
|
1005
1004
|
.md-inline-code {
|
|
1006
|
-
background: var(--
|
|
1007
|
-
border: 1px solid var(--
|
|
1005
|
+
background: var(--bg-card);
|
|
1006
|
+
border: 1px solid var(--border);
|
|
1008
1007
|
padding: 1px 6px;
|
|
1009
1008
|
border-radius: 10px;
|
|
1010
1009
|
font-family: "SF Mono", "Fira Code", "Consolas", monospace;
|
|
@@ -1013,7 +1012,7 @@ ul.md-list li::before {
|
|
|
1013
1012
|
|
|
1014
1013
|
.md-hr {
|
|
1015
1014
|
border: none;
|
|
1016
|
-
border-top: 1px solid var(--
|
|
1015
|
+
border-top: 1px solid var(--border);
|
|
1017
1016
|
margin: 8px 0;
|
|
1018
1017
|
}
|
|
1019
1018
|
|
|
@@ -1088,10 +1087,8 @@ ul.md-list li::before {
|
|
|
1088
1087
|
|
|
1089
1088
|
/* ═══ Diff Viewer ═══ */
|
|
1090
1089
|
.diff-viewer {
|
|
1091
|
-
background: var(--
|
|
1092
|
-
|
|
1093
|
-
-webkit-backdrop-filter: blur(12px);
|
|
1094
|
-
border: 1px solid var(--glass-border);
|
|
1090
|
+
background: var(--bg-card);
|
|
1091
|
+
border: 1px solid var(--border);
|
|
1095
1092
|
border-radius: var(--radius-lg);
|
|
1096
1093
|
overflow: hidden;
|
|
1097
1094
|
min-height: 200px;
|
|
@@ -1120,8 +1117,8 @@ ul.md-list li::before {
|
|
|
1120
1117
|
font-size: 13px;
|
|
1121
1118
|
font-weight: 500;
|
|
1122
1119
|
color: var(--text-primary);
|
|
1123
|
-
border-bottom: 1px solid var(--
|
|
1124
|
-
background: var(--
|
|
1120
|
+
border-bottom: 1px solid var(--border);
|
|
1121
|
+
background: var(--bg-card);
|
|
1125
1122
|
}
|
|
1126
1123
|
|
|
1127
1124
|
.diff-stat-add {
|
|
@@ -1256,8 +1253,8 @@ ul.md-list li::before {
|
|
|
1256
1253
|
right: 0;
|
|
1257
1254
|
max-height: 240px;
|
|
1258
1255
|
overflow-y: auto;
|
|
1259
|
-
background: var(--bg-card, var(--
|
|
1260
|
-
border: 1px solid var(--border, var(--
|
|
1256
|
+
background: var(--bg-card, var(--bg-card));
|
|
1257
|
+
border: 1px solid var(--border, var(--border));
|
|
1261
1258
|
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
|
1262
1259
|
box-shadow: var(--shadow-lg, 0 4px 24px rgba(0,0,0,.35));
|
|
1263
1260
|
z-index: 50;
|
|
@@ -1307,10 +1304,8 @@ ul.md-list li::before {
|
|
|
1307
1304
|
padding: 32px;
|
|
1308
1305
|
text-align: center;
|
|
1309
1306
|
gap: 16px;
|
|
1310
|
-
background: var(--
|
|
1311
|
-
|
|
1312
|
-
-webkit-backdrop-filter: var(--glass-blur);
|
|
1313
|
-
border: 1px solid var(--glass-border);
|
|
1307
|
+
background: var(--bg-card);
|
|
1308
|
+
border: 1px solid var(--border);
|
|
1314
1309
|
border-radius: var(--radius-lg);
|
|
1315
1310
|
}
|
|
1316
1311
|
|
|
@@ -1350,8 +1345,8 @@ ul.md-list li::before {
|
|
|
1350
1345
|
.chat-input-area {
|
|
1351
1346
|
position: relative;
|
|
1352
1347
|
padding: 16px 16px;
|
|
1353
|
-
border-top: 1px solid var(--border, var(--
|
|
1354
|
-
background: var(--bg-surface, var(--
|
|
1348
|
+
border-top: 1px solid var(--border, var(--border));
|
|
1349
|
+
background: var(--bg-surface, var(--bg-card));
|
|
1355
1350
|
flex-shrink: 0;
|
|
1356
1351
|
}
|
|
1357
1352
|
|
|
@@ -1408,8 +1403,8 @@ ul.md-list li::before {
|
|
|
1408
1403
|
display: flex;
|
|
1409
1404
|
align-items: flex-end;
|
|
1410
1405
|
gap: 8px;
|
|
1411
|
-
background: var(--bg-card, var(--
|
|
1412
|
-
border: 1px solid var(--border, var(--
|
|
1406
|
+
background: var(--bg-card, var(--bg-card));
|
|
1407
|
+
border: 1px solid var(--border, var(--border));
|
|
1413
1408
|
border-radius: 24px;
|
|
1414
1409
|
padding: 8px 8px 8px 16px;
|
|
1415
1410
|
transition: border-color 0.15s, box-shadow 0.15s;
|
|
@@ -1481,7 +1476,7 @@ ul.md-list li::before {
|
|
|
1481
1476
|
|
|
1482
1477
|
/* ═══ Session Rename ═══ */
|
|
1483
1478
|
.session-item-rename {
|
|
1484
|
-
background: var(--bg-input, var(--
|
|
1479
|
+
background: var(--bg-input, var(--bg-card));
|
|
1485
1480
|
border: 1px solid var(--accent, var(--color-primary, #3b82f6));
|
|
1486
1481
|
border-radius: var(--radius-sm);
|
|
1487
1482
|
padding: 2px 6px;
|
|
@@ -1572,7 +1567,7 @@ ul.md-list li::before {
|
|
|
1572
1567
|
.session-item-wrapper .session-item {
|
|
1573
1568
|
position: relative;
|
|
1574
1569
|
z-index: 1;
|
|
1575
|
-
background: var(--bg-surface, var(--
|
|
1570
|
+
background: var(--bg-surface, var(--bg-card));
|
|
1576
1571
|
touch-action: pan-y;
|
|
1577
1572
|
user-select: none;
|
|
1578
1573
|
}
|
package/ui/styles/variables.css
CHANGED
|
@@ -87,15 +87,15 @@
|
|
|
87
87
|
--accent-danger: var(--color-error);
|
|
88
88
|
|
|
89
89
|
/* Layout */
|
|
90
|
-
--header-height: calc(
|
|
91
|
-
--nav-height:
|
|
92
|
-
--sidebar-width:
|
|
93
|
-
--rail-width:
|
|
94
|
-
--inspector-width:
|
|
90
|
+
--header-height: calc(44px + var(--content-safe-top));
|
|
91
|
+
--nav-height: 56px;
|
|
92
|
+
--sidebar-width: 72px;
|
|
93
|
+
--rail-width: 300px;
|
|
94
|
+
--inspector-width: 300px;
|
|
95
95
|
--content-max: 1200px;
|
|
96
|
-
--shell-gap:
|
|
97
|
-
--radius-xs:
|
|
98
|
-
--radius-sm:
|
|
96
|
+
--shell-gap: 0px;
|
|
97
|
+
--radius-xs: 6px;
|
|
98
|
+
--radius-sm: 10px;
|
|
99
99
|
--radius-md: 14px;
|
|
100
100
|
--radius-lg: 18px;
|
|
101
101
|
--radius-xl: 24px;
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
.ws-switcher-dropdown {
|
|
52
52
|
position: absolute;
|
|
53
53
|
top: calc(100% + 4px);
|
|
54
|
-
|
|
54
|
+
right: 0;
|
|
55
55
|
min-width: 260px;
|
|
56
|
-
max-width: 340px;
|
|
56
|
+
max-width: min(340px, calc(100vw - 32px));
|
|
57
57
|
max-height: 400px;
|
|
58
58
|
overflow-y: auto;
|
|
59
59
|
background: var(--bg-primary, #1f1e1c);
|
|
@@ -195,8 +195,6 @@
|
|
|
195
195
|
align-items: center;
|
|
196
196
|
justify-content: center;
|
|
197
197
|
background: rgba(0, 0, 0, 0.65);
|
|
198
|
-
backdrop-filter: blur(4px);
|
|
199
|
-
-webkit-backdrop-filter: blur(4px);
|
|
200
198
|
animation: wsOverlayIn 0.2s ease-out;
|
|
201
199
|
}
|
|
202
200
|
|
package/ui/tabs/control.js
CHANGED
|
@@ -64,9 +64,6 @@ export function ControlTab() {
|
|
|
64
64
|
const [commandInput, setCommandInput] = useState("");
|
|
65
65
|
const [startTaskId, setStartTaskId] = useState("");
|
|
66
66
|
const [retryTaskId, setRetryTaskId] = useState("");
|
|
67
|
-
const [retryReason, setRetryReason] = useState("");
|
|
68
|
-
const [askInput, setAskInput] = useState("");
|
|
69
|
-
const [steerInput, setSteerInput] = useState("");
|
|
70
67
|
const [quickCmdInput, setQuickCmdInput] = useState("");
|
|
71
68
|
const [quickCmdPrefix, setQuickCmdPrefix] = useState("shell");
|
|
72
69
|
const [quickCmdFeedback, setQuickCmdFeedback] = useState("");
|
|
@@ -83,6 +80,8 @@ export function ControlTab() {
|
|
|
83
80
|
const [tasksLoading, setTasksLoading] = useState(false);
|
|
84
81
|
const [startTaskError, setStartTaskError] = useState("");
|
|
85
82
|
const [retryTaskError, setRetryTaskError] = useState("");
|
|
83
|
+
const [planFocus, setPlanFocus] = useState(""); // chip selection — no typing needed
|
|
84
|
+
const [planCount, setPlanCount] = useState("5");
|
|
86
85
|
const startTaskIdRef = useRef("");
|
|
87
86
|
const retryTaskIdRef = useRef("");
|
|
88
87
|
|
|
@@ -502,19 +501,15 @@ export function ControlTab() {
|
|
|
502
501
|
try {
|
|
503
502
|
await apiFetch("/api/tasks/retry", {
|
|
504
503
|
method: "POST",
|
|
505
|
-
body: JSON.stringify({
|
|
506
|
-
taskId,
|
|
507
|
-
retryReason: retryReason.trim() || undefined,
|
|
508
|
-
}),
|
|
504
|
+
body: JSON.stringify({ taskId }),
|
|
509
505
|
});
|
|
510
506
|
showToast("Task retried", "success");
|
|
511
|
-
setRetryReason("");
|
|
512
507
|
refreshTaskOptions();
|
|
513
508
|
scheduleRefresh(150);
|
|
514
509
|
} catch {
|
|
515
510
|
/* toast via apiFetch */
|
|
516
511
|
}
|
|
517
|
-
}, [retryTaskId,
|
|
512
|
+
}, [retryTaskId, refreshTaskOptions]);
|
|
518
513
|
|
|
519
514
|
return html`
|
|
520
515
|
${!executor && !config && html`<${Card} title="Loading…"><${SkeletonCard} /><//>`}
|
|
@@ -707,58 +702,6 @@ export function ControlTab() {
|
|
|
707
702
|
<//>
|
|
708
703
|
<//>
|
|
709
704
|
|
|
710
|
-
<${Card} className="agent-control-card">
|
|
711
|
-
<${Collapsible} title="Agent Control" defaultOpen=${!isCompact}>
|
|
712
|
-
<div class="meta-text mb-sm">Ask or steer the active agent.</div>
|
|
713
|
-
<div class="agent-control-grid">
|
|
714
|
-
<div>
|
|
715
|
-
<div class="form-label">Ask agent</div>
|
|
716
|
-
<textarea
|
|
717
|
-
class="input mb-sm"
|
|
718
|
-
rows="2"
|
|
719
|
-
placeholder="Ask the agent…"
|
|
720
|
-
value=${askInput}
|
|
721
|
-
onInput=${(e) => setAskInput(e.target.value)}
|
|
722
|
-
></textarea>
|
|
723
|
-
<div class="btn-row">
|
|
724
|
-
<button
|
|
725
|
-
class="btn btn-primary btn-sm"
|
|
726
|
-
onClick=${() => {
|
|
727
|
-
if (askInput.trim()) {
|
|
728
|
-
sendCmd(`/ask ${askInput.trim()}`);
|
|
729
|
-
setAskInput("");
|
|
730
|
-
}
|
|
731
|
-
}}
|
|
732
|
-
>
|
|
733
|
-
💬 Ask
|
|
734
|
-
</button>
|
|
735
|
-
</div>
|
|
736
|
-
</div>
|
|
737
|
-
<div>
|
|
738
|
-
<div class="form-label">Steer prompt</div>
|
|
739
|
-
<div class="input-row mb-sm">
|
|
740
|
-
<input
|
|
741
|
-
class="input"
|
|
742
|
-
placeholder="Steer prompt (focus on…)"
|
|
743
|
-
value=${steerInput}
|
|
744
|
-
onInput=${(e) => setSteerInput(e.target.value)}
|
|
745
|
-
/>
|
|
746
|
-
<button
|
|
747
|
-
class="btn btn-secondary btn-sm"
|
|
748
|
-
onClick=${() => {
|
|
749
|
-
if (steerInput.trim()) {
|
|
750
|
-
sendCmd(`/steer ${steerInput.trim()}`);
|
|
751
|
-
setSteerInput("");
|
|
752
|
-
}
|
|
753
|
-
}}
|
|
754
|
-
>
|
|
755
|
-
🎯 Steer
|
|
756
|
-
</button>
|
|
757
|
-
</div>
|
|
758
|
-
</div>
|
|
759
|
-
</div>
|
|
760
|
-
<//>
|
|
761
|
-
<//>
|
|
762
705
|
</div>
|
|
763
706
|
|
|
764
707
|
<div class="control-side">
|
|
@@ -813,6 +756,7 @@ export function ControlTab() {
|
|
|
813
756
|
<div class="field-group">
|
|
814
757
|
<div class="form-label">Retry task</div>
|
|
815
758
|
<div class="input-row">
|
|
759
|
+
<div class="input-row">
|
|
816
760
|
<select
|
|
817
761
|
class=${retryTaskError ? "input input-error" : "input"}
|
|
818
762
|
value=${retryTaskId}
|
|
@@ -831,27 +775,52 @@ export function ControlTab() {
|
|
|
831
775
|
`,
|
|
832
776
|
)}
|
|
833
777
|
</select>
|
|
834
|
-
<input
|
|
835
|
-
class="input"
|
|
836
|
-
placeholder="Retry reason (optional)"
|
|
837
|
-
value=${retryReason}
|
|
838
|
-
onInput=${(e) => setRetryReason(e.target.value)}
|
|
839
|
-
/>
|
|
840
778
|
<button
|
|
841
779
|
class="btn btn-secondary btn-sm"
|
|
842
780
|
disabled=${!retryTaskId}
|
|
843
781
|
onClick=${handleRetryTask}
|
|
844
782
|
>
|
|
845
|
-
Retry
|
|
846
|
-
</button>
|
|
847
|
-
<button class="btn btn-ghost btn-sm" onClick=${() => sendCmd("/plan")}>
|
|
848
|
-
📋 Plan
|
|
783
|
+
↻ Retry
|
|
849
784
|
</button>
|
|
850
785
|
</div>
|
|
851
786
|
${retryTaskError
|
|
852
787
|
? html`<div class="form-hint error">${retryTaskError}</div>`
|
|
853
788
|
: null}
|
|
854
789
|
</div>
|
|
790
|
+
|
|
791
|
+
<div class="field-group">
|
|
792
|
+
<div class="form-label">Task Planner</div>
|
|
793
|
+
<div class="plan-chips">
|
|
794
|
+
${["fix bugs", "add tests", "security", "refactor", "add docs", "performance"].map((chip) => html`
|
|
795
|
+
<button
|
|
796
|
+
key=${chip}
|
|
797
|
+
class=${`chip ${planFocus === chip ? "active" : ""}`}
|
|
798
|
+
onClick=${() => { haptic("light"); setPlanFocus(planFocus === chip ? "" : chip); }}
|
|
799
|
+
>${chip}</button>
|
|
800
|
+
`)}
|
|
801
|
+
</div>
|
|
802
|
+
<div class="input-row mt-sm">
|
|
803
|
+
<span class="form-hint" style="flex:1;margin:0">Generate
|
|
804
|
+
<input
|
|
805
|
+
type="number"
|
|
806
|
+
class="input plan-count-input"
|
|
807
|
+
min="1" max="50"
|
|
808
|
+
value=${planCount}
|
|
809
|
+
onInput=${(e) => setPlanCount(e.target.value)}
|
|
810
|
+
/>
|
|
811
|
+
tasks${planFocus ? ` · ${planFocus}` : ""}
|
|
812
|
+
</span>
|
|
813
|
+
<button
|
|
814
|
+
class="btn btn-ghost btn-sm"
|
|
815
|
+
onClick=${() => {
|
|
816
|
+
const n = Math.max(1, parseInt(planCount, 10) || 5);
|
|
817
|
+
sendCmd(planFocus ? `/plan ${n} ${planFocus}` : `/plan ${n}`);
|
|
818
|
+
}}
|
|
819
|
+
>
|
|
820
|
+
📋 Plan
|
|
821
|
+
</button>
|
|
822
|
+
</div>
|
|
823
|
+
</div>
|
|
855
824
|
<//>
|
|
856
825
|
<//>
|
|
857
826
|
|