vibesurf 0.1.10__py3-none-any.whl → 0.1.11__py3-none-any.whl
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.
Potentially problematic release.
This version of vibesurf might be problematic. Click here for more details.
- vibe_surf/_version.py +2 -2
- vibe_surf/agents/browser_use_agent.py +68 -45
- vibe_surf/agents/prompts/report_writer_prompt.py +73 -0
- vibe_surf/agents/prompts/vibe_surf_prompt.py +85 -172
- vibe_surf/agents/report_writer_agent.py +380 -226
- vibe_surf/agents/vibe_surf_agent.py +879 -825
- vibe_surf/agents/views.py +130 -0
- vibe_surf/backend/api/activity.py +3 -1
- vibe_surf/backend/api/browser.py +9 -5
- vibe_surf/backend/api/config.py +8 -5
- vibe_surf/backend/api/files.py +59 -50
- vibe_surf/backend/api/models.py +2 -2
- vibe_surf/backend/api/task.py +45 -12
- vibe_surf/backend/database/manager.py +24 -18
- vibe_surf/backend/database/queries.py +199 -192
- vibe_surf/backend/database/schemas.py +1 -1
- vibe_surf/backend/main.py +4 -2
- vibe_surf/backend/shared_state.py +28 -35
- vibe_surf/backend/utils/encryption.py +3 -1
- vibe_surf/backend/utils/llm_factory.py +41 -36
- vibe_surf/browser/agent_browser_session.py +0 -4
- vibe_surf/browser/browser_manager.py +14 -8
- vibe_surf/browser/utils.py +5 -3
- vibe_surf/browser/watchdogs/dom_watchdog.py +0 -45
- vibe_surf/chrome_extension/background.js +4 -0
- vibe_surf/chrome_extension/scripts/api-client.js +13 -0
- vibe_surf/chrome_extension/scripts/file-manager.js +27 -71
- vibe_surf/chrome_extension/scripts/session-manager.js +21 -3
- vibe_surf/chrome_extension/scripts/ui-manager.js +831 -48
- vibe_surf/chrome_extension/sidepanel.html +21 -4
- vibe_surf/chrome_extension/styles/activity.css +365 -5
- vibe_surf/chrome_extension/styles/input.css +139 -0
- vibe_surf/cli.py +4 -22
- vibe_surf/common.py +35 -0
- vibe_surf/llm/openai_compatible.py +148 -93
- vibe_surf/logger.py +99 -0
- vibe_surf/{controller/vibesurf_tools.py → tools/browser_use_tools.py} +233 -219
- vibe_surf/tools/file_system.py +415 -0
- vibe_surf/{controller → tools}/mcp_client.py +4 -3
- vibe_surf/tools/report_writer_tools.py +21 -0
- vibe_surf/tools/vibesurf_tools.py +657 -0
- vibe_surf/tools/views.py +120 -0
- {vibesurf-0.1.10.dist-info → vibesurf-0.1.11.dist-info}/METADATA +6 -2
- {vibesurf-0.1.10.dist-info → vibesurf-0.1.11.dist-info}/RECORD +49 -43
- vibe_surf/controller/file_system.py +0 -53
- vibe_surf/controller/views.py +0 -37
- /vibe_surf/{controller → tools}/__init__.py +0 -0
- {vibesurf-0.1.10.dist-info → vibesurf-0.1.11.dist-info}/WHEEL +0 -0
- {vibesurf-0.1.10.dist-info → vibesurf-0.1.11.dist-info}/entry_points.txt +0 -0
- {vibesurf-0.1.10.dist-info → vibesurf-0.1.11.dist-info}/licenses/LICENSE +0 -0
- {vibesurf-0.1.10.dist-info → vibesurf-0.1.11.dist-info}/top_level.txt +0 -0
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
<div id="control-panel" class="control-panel hidden">
|
|
111
111
|
<button id="cancel-btn" class="control-btn cancel-btn">
|
|
112
112
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
113
|
-
<path d="M6
|
|
113
|
+
<path d="M6 4H10V20H6V4ZM14 4H18V20H14V4Z" fill="currentColor"/>
|
|
114
114
|
</svg>
|
|
115
115
|
Pause
|
|
116
116
|
</button>
|
|
@@ -134,11 +134,28 @@
|
|
|
134
134
|
<div class="input-container">
|
|
135
135
|
<div class="input-main">
|
|
136
136
|
<div class="textarea-container">
|
|
137
|
-
<textarea
|
|
138
|
-
id="task-input"
|
|
139
|
-
class="task-input"
|
|
137
|
+
<textarea
|
|
138
|
+
id="task-input"
|
|
139
|
+
class="task-input"
|
|
140
140
|
placeholder="Describe your browsing task..."
|
|
141
141
|
rows="3"></textarea>
|
|
142
|
+
<!-- Tab Selection Dropdown -->
|
|
143
|
+
<div id="tab-selector-dropdown" class="tab-selector-dropdown hidden">
|
|
144
|
+
<div class="tab-selector-header">
|
|
145
|
+
<span class="tab-selector-title">Select Tabs</span>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="tab-selector-content">
|
|
148
|
+
<div class="tab-selector-controls">
|
|
149
|
+
<label class="tab-option select-all-option">
|
|
150
|
+
<input type="radio" id="select-all-tabs" name="tab-selection" class="tab-radio">
|
|
151
|
+
<span class="tab-name">Select All</span>
|
|
152
|
+
</label>
|
|
153
|
+
</div>
|
|
154
|
+
<div id="tab-options-list" class="tab-options-list">
|
|
155
|
+
<!-- Tab options will be populated here -->
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
142
159
|
<div class="input-actions">
|
|
143
160
|
<button id="attach-file-btn" class="action-btn attach-btn" title="Attach Files">
|
|
144
161
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -135,7 +135,8 @@
|
|
|
135
135
|
.message-container {
|
|
136
136
|
display: flex;
|
|
137
137
|
flex-direction: column;
|
|
138
|
-
max-width:
|
|
138
|
+
max-width: 85%;
|
|
139
|
+
min-width: 0; /* Allow shrinking */
|
|
139
140
|
animation: fadeIn 0.3s ease-out;
|
|
140
141
|
}
|
|
141
142
|
|
|
@@ -152,34 +153,65 @@
|
|
|
152
153
|
.message-header {
|
|
153
154
|
display: flex;
|
|
154
155
|
align-items: center;
|
|
155
|
-
|
|
156
|
+
justify-content: space-between;
|
|
156
157
|
margin-bottom: var(--spacing-xs);
|
|
157
158
|
font-size: var(--font-size-xs);
|
|
158
159
|
color: var(--text-muted);
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
.user-container .message-header {
|
|
162
|
-
|
|
163
|
+
flex-direction: row-reverse;
|
|
164
|
+
gap: var(--spacing-md);
|
|
163
165
|
}
|
|
164
166
|
|
|
165
167
|
.agent-container .message-header {
|
|
166
|
-
|
|
168
|
+
flex-direction: row;
|
|
169
|
+
gap: var(--spacing-md);
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
.agent-name {
|
|
170
173
|
font-weight: var(--font-weight-medium);
|
|
171
174
|
color: var(--text-secondary);
|
|
175
|
+
flex-shrink: 0;
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
.user-container .agent-name {
|
|
175
179
|
color: var(--primary-color);
|
|
176
180
|
}
|
|
177
181
|
|
|
182
|
+
.message-metadata {
|
|
183
|
+
display: flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
gap: var(--spacing-sm);
|
|
186
|
+
font-size: 10px;
|
|
187
|
+
flex-shrink: 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
178
190
|
.message-time {
|
|
179
|
-
font-size:
|
|
191
|
+
font-size: 10px;
|
|
180
192
|
color: var(--text-muted);
|
|
181
193
|
}
|
|
182
194
|
|
|
195
|
+
.message-metrics {
|
|
196
|
+
display: flex;
|
|
197
|
+
align-items: center;
|
|
198
|
+
gap: var(--spacing-xs);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.metric-item {
|
|
202
|
+
font-size: 10px;
|
|
203
|
+
color: var(--text-muted);
|
|
204
|
+
background-color: var(--bg-tertiary);
|
|
205
|
+
padding: 1px 4px;
|
|
206
|
+
border-radius: var(--radius-sm);
|
|
207
|
+
font-weight: var(--font-weight-normal);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.user-container .metric-item {
|
|
211
|
+
background-color: rgba(255, 255, 255, 0.2);
|
|
212
|
+
color: rgba(255, 255, 255, 0.9);
|
|
213
|
+
}
|
|
214
|
+
|
|
183
215
|
/* Message Bubbles */
|
|
184
216
|
.message-bubble {
|
|
185
217
|
padding: var(--spacing-md);
|
|
@@ -187,6 +219,9 @@
|
|
|
187
219
|
position: relative;
|
|
188
220
|
word-wrap: break-word;
|
|
189
221
|
box-shadow: var(--shadow-sm);
|
|
222
|
+
min-width: 0; /* Allow shrinking */
|
|
223
|
+
max-width: 100%;
|
|
224
|
+
overflow-wrap: break-word;
|
|
190
225
|
}
|
|
191
226
|
|
|
192
227
|
/* Copy Message Button */
|
|
@@ -300,6 +335,8 @@
|
|
|
300
335
|
.message-content {
|
|
301
336
|
line-height: 1.6;
|
|
302
337
|
font-size: var(--font-size-sm);
|
|
338
|
+
min-width: 0; /* Allow shrinking */
|
|
339
|
+
overflow-wrap: break-word;
|
|
303
340
|
}
|
|
304
341
|
|
|
305
342
|
.user-bubble .message-content {
|
|
@@ -348,6 +385,28 @@
|
|
|
348
385
|
font-size: var(--font-size-xs);
|
|
349
386
|
margin: var(--spacing-sm) 0;
|
|
350
387
|
border: 1px solid var(--border-color);
|
|
388
|
+
max-width: 100%;
|
|
389
|
+
white-space: pre-wrap;
|
|
390
|
+
word-break: break-all;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/* Custom scrollbar for code blocks */
|
|
394
|
+
.message-content .code-block::-webkit-scrollbar {
|
|
395
|
+
height: 6px;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.message-content .code-block::-webkit-scrollbar-track {
|
|
399
|
+
background: var(--bg-secondary);
|
|
400
|
+
border-radius: 3px;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.message-content .code-block::-webkit-scrollbar-thumb {
|
|
404
|
+
background: var(--border-color);
|
|
405
|
+
border-radius: 3px;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.message-content .code-block::-webkit-scrollbar-thumb:hover {
|
|
409
|
+
background: var(--border-hover);
|
|
351
410
|
}
|
|
352
411
|
|
|
353
412
|
.user-bubble .code-block {
|
|
@@ -361,6 +420,8 @@
|
|
|
361
420
|
border-radius: var(--radius-sm);
|
|
362
421
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
363
422
|
font-size: var(--font-size-xs);
|
|
423
|
+
word-break: break-all;
|
|
424
|
+
overflow-wrap: break-word;
|
|
364
425
|
}
|
|
365
426
|
|
|
366
427
|
.user-bubble .inline-code {
|
|
@@ -376,6 +437,28 @@
|
|
|
376
437
|
font-size: var(--font-size-xs);
|
|
377
438
|
margin: var(--spacing-sm) 0;
|
|
378
439
|
border: 1px solid var(--border-color);
|
|
440
|
+
max-width: 100%;
|
|
441
|
+
white-space: pre-wrap;
|
|
442
|
+
word-break: break-all;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/* Custom scrollbar for JSON content */
|
|
446
|
+
.message-content .json-content::-webkit-scrollbar {
|
|
447
|
+
height: 6px;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.message-content .json-content::-webkit-scrollbar-track {
|
|
451
|
+
background: var(--bg-secondary);
|
|
452
|
+
border-radius: 3px;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.message-content .json-content::-webkit-scrollbar-thumb {
|
|
456
|
+
background: var(--border-color);
|
|
457
|
+
border-radius: 3px;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.message-content .json-content::-webkit-scrollbar-thumb:hover {
|
|
461
|
+
background: var(--border-hover);
|
|
379
462
|
}
|
|
380
463
|
|
|
381
464
|
.user-bubble .json-content {
|
|
@@ -571,4 +654,281 @@
|
|
|
571
654
|
|
|
572
655
|
.message-content em {
|
|
573
656
|
font-style: italic;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/* Suggestion Tasks Styles */
|
|
660
|
+
.suggestion-tasks-container {
|
|
661
|
+
margin: var(--spacing-lg) 0;
|
|
662
|
+
padding: var(--spacing-md);
|
|
663
|
+
background: linear-gradient(135deg, rgba(0, 122, 204, 0.02), rgba(0, 122, 204, 0.05));
|
|
664
|
+
border: 1px solid rgba(0, 122, 204, 0.1);
|
|
665
|
+
border-radius: var(--radius-xl);
|
|
666
|
+
position: relative;
|
|
667
|
+
overflow: visible;
|
|
668
|
+
display: block;
|
|
669
|
+
width: 100%;
|
|
670
|
+
box-sizing: border-box;
|
|
671
|
+
min-height: auto;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.suggestion-tasks-container::before {
|
|
675
|
+
content: '';
|
|
676
|
+
position: absolute;
|
|
677
|
+
top: 0;
|
|
678
|
+
left: 0;
|
|
679
|
+
right: 0;
|
|
680
|
+
height: 3px;
|
|
681
|
+
background: linear-gradient(90deg, var(--primary-color), var(--accent-color));
|
|
682
|
+
border-radius: var(--radius-xl) var(--radius-xl) 0 0;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.suggestion-tasks-header {
|
|
686
|
+
text-align: center;
|
|
687
|
+
margin-bottom: var(--spacing-md);
|
|
688
|
+
padding: 0;
|
|
689
|
+
display: block;
|
|
690
|
+
width: 100%;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.suggestion-tasks-header h4 {
|
|
694
|
+
font-size: var(--font-size-xl);
|
|
695
|
+
font-weight: var(--font-weight-bold);
|
|
696
|
+
color: var(--text-primary);
|
|
697
|
+
margin: 0;
|
|
698
|
+
display: block;
|
|
699
|
+
text-align: center;
|
|
700
|
+
line-height: 1.3;
|
|
701
|
+
white-space: normal;
|
|
702
|
+
overflow: visible;
|
|
703
|
+
word-wrap: break-word;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.suggestion-tasks-header p {
|
|
707
|
+
font-size: var(--font-size-sm);
|
|
708
|
+
color: var(--text-secondary);
|
|
709
|
+
margin: 0;
|
|
710
|
+
opacity: 0.8;
|
|
711
|
+
line-height: 1.4;
|
|
712
|
+
display: block;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
.suggestion-cards {
|
|
716
|
+
display: flex;
|
|
717
|
+
flex-direction: column;
|
|
718
|
+
gap: var(--spacing-sm);
|
|
719
|
+
width: 100%;
|
|
720
|
+
min-height: auto;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.suggestion-task-card {
|
|
724
|
+
display: flex;
|
|
725
|
+
align-items: center;
|
|
726
|
+
gap: var(--spacing-md);
|
|
727
|
+
padding: var(--spacing-md);
|
|
728
|
+
background: var(--bg-primary);
|
|
729
|
+
border: 2px solid var(--border-color);
|
|
730
|
+
border-radius: var(--radius-lg);
|
|
731
|
+
cursor: pointer;
|
|
732
|
+
transition: all var(--transition-fast);
|
|
733
|
+
position: relative;
|
|
734
|
+
overflow: visible;
|
|
735
|
+
width: 100%;
|
|
736
|
+
min-height: 50px;
|
|
737
|
+
box-sizing: border-box;
|
|
738
|
+
margin-bottom: 0;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
.suggestion-task-card:last-child {
|
|
742
|
+
margin-bottom: 0;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
.suggestion-task-card::before {
|
|
746
|
+
content: '';
|
|
747
|
+
position: absolute;
|
|
748
|
+
top: 0;
|
|
749
|
+
left: 0;
|
|
750
|
+
bottom: 0;
|
|
751
|
+
width: 4px;
|
|
752
|
+
background: var(--primary-color);
|
|
753
|
+
transform: scaleX(0);
|
|
754
|
+
transform-origin: left;
|
|
755
|
+
transition: transform var(--transition-fast);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
.suggestion-task-card:hover {
|
|
759
|
+
border-color: var(--primary-color);
|
|
760
|
+
background: var(--bg-hover);
|
|
761
|
+
transform: translateY(-2px);
|
|
762
|
+
box-shadow: var(--shadow-lg);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
.suggestion-task-card:hover::before {
|
|
766
|
+
transform: scaleX(1);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
.suggestion-task-card:active {
|
|
770
|
+
transform: translateY(-1px);
|
|
771
|
+
box-shadow: var(--shadow-md);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
.suggestion-card-icon {
|
|
775
|
+
flex-shrink: 0;
|
|
776
|
+
width: 40px;
|
|
777
|
+
height: 40px;
|
|
778
|
+
display: flex;
|
|
779
|
+
align-items: center;
|
|
780
|
+
justify-content: center;
|
|
781
|
+
background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
|
|
782
|
+
border-radius: var(--radius-md);
|
|
783
|
+
color: white;
|
|
784
|
+
transition: transform var(--transition-fast);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.suggestion-task-card:hover .suggestion-card-icon {
|
|
788
|
+
transform: scale(1.1);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.suggestion-card-content {
|
|
792
|
+
flex: 1;
|
|
793
|
+
min-width: 0;
|
|
794
|
+
display: flex;
|
|
795
|
+
flex-direction: column;
|
|
796
|
+
justify-content: center;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
.suggestion-task-text {
|
|
800
|
+
font-size: var(--font-size-sm);
|
|
801
|
+
color: var(--text-primary);
|
|
802
|
+
line-height: 1.5;
|
|
803
|
+
font-weight: var(--font-weight-medium);
|
|
804
|
+
word-wrap: break-word;
|
|
805
|
+
overflow-wrap: break-word;
|
|
806
|
+
white-space: normal;
|
|
807
|
+
text-overflow: clip;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
.suggestion-tasks-section {
|
|
811
|
+
margin: var(--spacing-lg) 0;
|
|
812
|
+
width: 100%;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
.suggestion-tasks-header {
|
|
816
|
+
display: flex;
|
|
817
|
+
align-items: center;
|
|
818
|
+
gap: var(--spacing-sm);
|
|
819
|
+
margin-bottom: var(--spacing-md);
|
|
820
|
+
padding: 0 var(--spacing-sm);
|
|
821
|
+
min-height: 24px;
|
|
822
|
+
width: 100%;
|
|
823
|
+
overflow: visible;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
.suggestion-tasks-header h4 {
|
|
827
|
+
font-size: var(--font-size-base);
|
|
828
|
+
font-weight: var(--font-weight-bold);
|
|
829
|
+
color: var(--text-primary);
|
|
830
|
+
margin: 0;
|
|
831
|
+
white-space: nowrap;
|
|
832
|
+
overflow: visible;
|
|
833
|
+
text-overflow: clip;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
.suggestion-cards-container {
|
|
837
|
+
display: flex;
|
|
838
|
+
flex-direction: column;
|
|
839
|
+
gap: var(--spacing-md);
|
|
840
|
+
width: 100%;
|
|
841
|
+
padding: 0 var(--spacing-sm);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
.suggestion-card-arrow {
|
|
845
|
+
flex-shrink: 0;
|
|
846
|
+
width: 24px;
|
|
847
|
+
height: 24px;
|
|
848
|
+
display: flex;
|
|
849
|
+
align-items: center;
|
|
850
|
+
justify-content: center;
|
|
851
|
+
color: var(--text-muted);
|
|
852
|
+
transition: all var(--transition-fast);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
.suggestion-task-card:hover .suggestion-card-arrow {
|
|
856
|
+
color: var(--primary-color);
|
|
857
|
+
transform: translateX(4px);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/* Animation for suggestion cards */
|
|
861
|
+
.suggestion-tasks-container.fade-in {
|
|
862
|
+
animation: suggestionFadeIn 0.5s ease-out;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
@keyframes suggestionFadeIn {
|
|
866
|
+
from {
|
|
867
|
+
opacity: 0;
|
|
868
|
+
transform: translateY(20px);
|
|
869
|
+
}
|
|
870
|
+
to {
|
|
871
|
+
opacity: 1;
|
|
872
|
+
transform: translateY(0);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/* Responsive design for suggestion cards */
|
|
877
|
+
@media (max-width: 480px) {
|
|
878
|
+
.suggestion-tasks-container {
|
|
879
|
+
margin: var(--spacing-lg) 0;
|
|
880
|
+
padding: var(--spacing-md);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.suggestion-task-card {
|
|
884
|
+
padding: var(--spacing-md);
|
|
885
|
+
gap: var(--spacing-sm);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
.suggestion-card-icon {
|
|
889
|
+
width: 32px;
|
|
890
|
+
height: 32px;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
.suggestion-card-icon svg {
|
|
894
|
+
width: 14px;
|
|
895
|
+
height: 14px;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.suggestion-task-text {
|
|
899
|
+
font-size: var(--font-size-xs);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
.suggestion-tasks-header h4 {
|
|
903
|
+
font-size: var(--font-size-base);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/* Loading state for suggestion cards */
|
|
908
|
+
.suggestion-task-card.loading {
|
|
909
|
+
pointer-events: none;
|
|
910
|
+
opacity: 0.6;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
.suggestion-task-card.loading .suggestion-card-icon {
|
|
914
|
+
animation: pulse 1.5s ease-in-out infinite;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
@keyframes pulse {
|
|
918
|
+
0%, 100% {
|
|
919
|
+
opacity: 1;
|
|
920
|
+
}
|
|
921
|
+
50% {
|
|
922
|
+
opacity: 0.7;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
/* Success state when card is clicked */
|
|
927
|
+
.suggestion-task-card.success {
|
|
928
|
+
border-color: var(--accent-color);
|
|
929
|
+
background: rgba(40, 167, 69, 0.05);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.suggestion-task-card.success .suggestion-card-icon {
|
|
933
|
+
background: var(--accent-color);
|
|
574
934
|
}
|
|
@@ -426,4 +426,143 @@ select.task-running-disabled {
|
|
|
426
426
|
color: var(--danger-color);
|
|
427
427
|
font-size: var(--font-size-sm);
|
|
428
428
|
text-align: center;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* Tab Selection Dropdown */
|
|
432
|
+
.tab-selector-dropdown {
|
|
433
|
+
position: fixed !important;
|
|
434
|
+
z-index: 1000;
|
|
435
|
+
background: var(--bg-primary);
|
|
436
|
+
border: 1px solid var(--border-color);
|
|
437
|
+
border-radius: var(--radius-md);
|
|
438
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
439
|
+
max-height: 300px;
|
|
440
|
+
overflow: hidden;
|
|
441
|
+
display: none;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.tab-selector-header {
|
|
445
|
+
display: flex;
|
|
446
|
+
align-items: center;
|
|
447
|
+
justify-content: space-between;
|
|
448
|
+
padding: var(--spacing-sm) var(--spacing-md);
|
|
449
|
+
background: var(--bg-secondary);
|
|
450
|
+
border-bottom: 1px solid var(--border-color);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.tab-selector-title {
|
|
454
|
+
font-size: var(--font-size-sm);
|
|
455
|
+
font-weight: var(--font-weight-medium);
|
|
456
|
+
color: var(--text-primary);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.tab-selector-close {
|
|
460
|
+
width: 24px;
|
|
461
|
+
height: 24px;
|
|
462
|
+
border: none;
|
|
463
|
+
background: none;
|
|
464
|
+
font-size: 18px;
|
|
465
|
+
color: var(--text-muted);
|
|
466
|
+
cursor: pointer;
|
|
467
|
+
border-radius: var(--radius-sm);
|
|
468
|
+
display: flex;
|
|
469
|
+
align-items: center;
|
|
470
|
+
justify-content: center;
|
|
471
|
+
transition: all var(--transition-fast);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.tab-selector-close:hover {
|
|
475
|
+
background: var(--bg-hover);
|
|
476
|
+
color: var(--text-primary);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.tab-selector-content {
|
|
480
|
+
max-height: 200px;
|
|
481
|
+
overflow-y: auto;
|
|
482
|
+
padding: var(--spacing-xs);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.tab-selector-controls {
|
|
486
|
+
padding: var(--spacing-xs) var(--spacing-sm);
|
|
487
|
+
border-bottom: 1px solid var(--border-color);
|
|
488
|
+
margin-bottom: var(--spacing-xs);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.select-all-option {
|
|
492
|
+
font-weight: var(--font-weight-medium);
|
|
493
|
+
color: var(--primary-color);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.tab-options-list {
|
|
497
|
+
display: flex;
|
|
498
|
+
flex-direction: column;
|
|
499
|
+
gap: 2px;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.tab-option {
|
|
503
|
+
display: flex;
|
|
504
|
+
align-items: center;
|
|
505
|
+
gap: var(--spacing-sm);
|
|
506
|
+
padding: var(--spacing-xs) var(--spacing-sm);
|
|
507
|
+
cursor: pointer;
|
|
508
|
+
border-radius: var(--radius-sm);
|
|
509
|
+
transition: background-color var(--transition-fast);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
.tab-option:hover {
|
|
513
|
+
background: var(--bg-hover);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.tab-option.active-tab {
|
|
517
|
+
background: rgba(144, 238, 144, 0.3);
|
|
518
|
+
border: 1px solid rgba(144, 238, 144, 0.6);
|
|
519
|
+
box-shadow: 0 2px 4px rgba(144, 238, 144, 0.2);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.tab-option.active-tab .tab-name {
|
|
523
|
+
color: #2d5a2d;
|
|
524
|
+
font-weight: var(--font-weight-medium);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.tab-option.active-tab .tab-id {
|
|
528
|
+
color: #1a4d1a;
|
|
529
|
+
font-weight: var(--font-weight-medium);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.tab-radio {
|
|
533
|
+
width: 16px;
|
|
534
|
+
height: 16px;
|
|
535
|
+
cursor: pointer;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.tab-name {
|
|
539
|
+
flex: 1;
|
|
540
|
+
font-size: var(--font-size-sm);
|
|
541
|
+
color: var(--text-primary);
|
|
542
|
+
overflow: hidden;
|
|
543
|
+
text-overflow: ellipsis;
|
|
544
|
+
white-space: nowrap;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/* Remove footer and buttons for single-select auto-confirm */
|
|
548
|
+
|
|
549
|
+
/* Tab selection indicator in textarea */
|
|
550
|
+
.task-input.has-selected-tabs {
|
|
551
|
+
border-color: var(--primary-color);
|
|
552
|
+
background: rgba(0, 122, 204, 0.02);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/* Selected tabs display */
|
|
556
|
+
.selected-tabs-indicator {
|
|
557
|
+
position: absolute;
|
|
558
|
+
bottom: 8px;
|
|
559
|
+
left: 8px;
|
|
560
|
+
background: var(--primary-color);
|
|
561
|
+
color: white;
|
|
562
|
+
padding: 2px 6px;
|
|
563
|
+
border-radius: var(--radius-sm);
|
|
564
|
+
font-size: 10px;
|
|
565
|
+
font-weight: var(--font-weight-medium);
|
|
566
|
+
pointer-events: none;
|
|
567
|
+
z-index: 2;
|
|
429
568
|
}
|
vibe_surf/cli.py
CHANGED
|
@@ -41,15 +41,8 @@ VIBESURF_LOGO = """
|
|
|
41
41
|
console = Console()
|
|
42
42
|
|
|
43
43
|
# Add logger import for the workspace directory logging
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
logger = logging.getLogger(__name__)
|
|
47
|
-
logging.basicConfig(level=logging.INFO)
|
|
48
|
-
except ImportError:
|
|
49
|
-
class SimpleLogger:
|
|
50
|
-
def info(self, msg):
|
|
51
|
-
console.print(f"[dim]{msg}[/dim]")
|
|
52
|
-
logger = SimpleLogger()
|
|
44
|
+
from vibe_surf.logger import get_logger
|
|
45
|
+
logger = get_logger(__name__)
|
|
53
46
|
|
|
54
47
|
|
|
55
48
|
def find_chrome_browser() -> Optional[str]:
|
|
@@ -348,19 +341,8 @@ def start_backend(port: int) -> None:
|
|
|
348
341
|
def get_browser_execution_path() -> Optional[str]:
|
|
349
342
|
"""Get browser execution path from envs.json or environment variables."""
|
|
350
343
|
# 1. Load environment variables
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
# Set default workspace directory based on OS
|
|
354
|
-
if platform.system() == "Windows":
|
|
355
|
-
default_workspace = os.path.join(os.environ.get("APPDATA", ""), "VibeSurf")
|
|
356
|
-
elif platform.system() == "Darwin": # macOS
|
|
357
|
-
default_workspace = os.path.join(os.path.expanduser("~"), "Library", "Application Support", "VibeSurf")
|
|
358
|
-
else: # Linux and others
|
|
359
|
-
default_workspace = os.path.join(os.path.expanduser("~"), ".vibesurf")
|
|
360
|
-
workspace_dir = default_workspace
|
|
361
|
-
else:
|
|
362
|
-
workspace_dir = env_workspace_dir
|
|
363
|
-
workspace_dir = os.path.abspath(workspace_dir)
|
|
344
|
+
from .common import get_workspace_dir
|
|
345
|
+
workspace_dir = get_workspace_dir()
|
|
364
346
|
os.makedirs(workspace_dir, exist_ok=True)
|
|
365
347
|
logger.info("WorkSpace directory: {}".format(workspace_dir))
|
|
366
348
|
|
vibe_surf/common.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Common utilities and configurations for VibeSurf.
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
import platform
|
|
6
|
+
from dotenv import load_dotenv
|
|
7
|
+
|
|
8
|
+
project_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
|
9
|
+
|
|
10
|
+
load_dotenv(os.path.join(project_dir, ".env"))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_workspace_dir():
|
|
14
|
+
"""
|
|
15
|
+
Get the workspace directory for VibeSurf.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
str: The absolute path to the workspace directory.
|
|
19
|
+
"""
|
|
20
|
+
env_workspace_dir = os.getenv("VIBESURF_WORKSPACE", "")
|
|
21
|
+
if not env_workspace_dir or not env_workspace_dir.strip():
|
|
22
|
+
# Set default workspace directory based on OS
|
|
23
|
+
if platform.system() == "Windows":
|
|
24
|
+
default_workspace = os.path.join(os.environ.get("APPDATA", ""), "VibeSurf")
|
|
25
|
+
elif platform.system() == "Darwin": # macOS
|
|
26
|
+
default_workspace = os.path.join(os.path.expanduser("~"), "Library", "Application Support", "VibeSurf")
|
|
27
|
+
else: # Linux and others
|
|
28
|
+
default_workspace = os.path.join(os.path.expanduser("~"), ".vibesurf")
|
|
29
|
+
workspace_dir = default_workspace
|
|
30
|
+
else:
|
|
31
|
+
workspace_dir = env_workspace_dir
|
|
32
|
+
|
|
33
|
+
workspace_dir = os.path.abspath(workspace_dir)
|
|
34
|
+
os.makedirs(workspace_dir, exist_ok=True)
|
|
35
|
+
return workspace_dir
|