@vibe-forge/client 0.2.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/LICENSE +21 -0
  2. package/cli.cjs +6 -0
  3. package/index.html +27 -0
  4. package/package.json +42 -0
  5. package/src/App.tsx +174 -0
  6. package/src/api.ts +241 -0
  7. package/src/components/ArchiveView.scss +168 -0
  8. package/src/components/ArchiveView.tsx +299 -0
  9. package/src/components/AutomationView/AutomationView.scss +26 -0
  10. package/src/components/AutomationView/RuleFormPanel.scss +129 -0
  11. package/src/components/AutomationView/RuleFormPanel.tsx +257 -0
  12. package/src/components/AutomationView/RuleSidebar.scss +219 -0
  13. package/src/components/AutomationView/RuleSidebar.tsx +258 -0
  14. package/src/components/AutomationView/RunHistoryPanel.scss +286 -0
  15. package/src/components/AutomationView/RunHistoryPanel.tsx +320 -0
  16. package/src/components/AutomationView/TaskList.scss +128 -0
  17. package/src/components/AutomationView/TaskList.tsx +79 -0
  18. package/src/components/AutomationView/TriggerList.scss +153 -0
  19. package/src/components/AutomationView/TriggerList.tsx +217 -0
  20. package/src/components/AutomationView/index.tsx +228 -0
  21. package/src/components/AutomationView/types.ts +21 -0
  22. package/src/components/Chat.scss +89 -0
  23. package/src/components/Chat.tsx +92 -0
  24. package/src/components/ConfigView.scss +185 -0
  25. package/src/components/ConfigView.tsx +258 -0
  26. package/src/components/NavRail.scss +71 -0
  27. package/src/components/NavRail.tsx +188 -0
  28. package/src/components/Sidebar.scss +112 -0
  29. package/src/components/Sidebar.tsx +291 -0
  30. package/src/components/chat/ChatHeader.scss +401 -0
  31. package/src/components/chat/ChatHeader.tsx +342 -0
  32. package/src/components/chat/ChatHistoryView.tsx +122 -0
  33. package/src/components/chat/ChatSettingsView.tsx +22 -0
  34. package/src/components/chat/ChatTimelineView.scss +53 -0
  35. package/src/components/chat/ChatTimelineView.tsx +158 -0
  36. package/src/components/chat/CodeBlock.scss +87 -0
  37. package/src/components/chat/CodeBlock.tsx +179 -0
  38. package/src/components/chat/CompletionMenu.scss +70 -0
  39. package/src/components/chat/CompletionMenu.tsx +58 -0
  40. package/src/components/chat/CurrentTodoList.scss +217 -0
  41. package/src/components/chat/CurrentTodoList.tsx +103 -0
  42. package/src/components/chat/MarkdownContent.tsx +43 -0
  43. package/src/components/chat/MessageFooter.tsx +48 -0
  44. package/src/components/chat/MessageItem.scss +251 -0
  45. package/src/components/chat/MessageItem.tsx +78 -0
  46. package/src/components/chat/NewSessionGuide.scss +186 -0
  47. package/src/components/chat/NewSessionGuide.tsx +167 -0
  48. package/src/components/chat/Sender.scss +367 -0
  49. package/src/components/chat/Sender.tsx +541 -0
  50. package/src/components/chat/SessionTimelinePanel/EventList.scss +58 -0
  51. package/src/components/chat/SessionTimelinePanel/EventList.tsx +212 -0
  52. package/src/components/chat/SessionTimelinePanel/gantt.ts +177 -0
  53. package/src/components/chat/SessionTimelinePanel/git-graph.ts +518 -0
  54. package/src/components/chat/SessionTimelinePanel/index.scss +28 -0
  55. package/src/components/chat/SessionTimelinePanel/index.tsx +121 -0
  56. package/src/components/chat/SessionTimelinePanel/mermaid.ts +4 -0
  57. package/src/components/chat/SessionTimelinePanel/types.ts +64 -0
  58. package/src/components/chat/SessionTimelinePanel/utils.ts +20 -0
  59. package/src/components/chat/ThinkingStatus.scss +70 -0
  60. package/src/components/chat/ThinkingStatus.tsx +13 -0
  61. package/src/components/chat/ToolCallBox.scss +137 -0
  62. package/src/components/chat/ToolCallBox.tsx +55 -0
  63. package/src/components/chat/ToolGroup.scss +154 -0
  64. package/src/components/chat/ToolGroup.tsx +102 -0
  65. package/src/components/chat/ToolRenderer.tsx +45 -0
  66. package/src/components/chat/messageUtils.ts +171 -0
  67. package/src/components/chat/safeSerialize.ts +84 -0
  68. package/src/components/chat/tools/DefaultTool.tsx +63 -0
  69. package/src/components/chat/tools/adapter-claude/BashTool.scss +71 -0
  70. package/src/components/chat/tools/adapter-claude/BashTool.tsx +82 -0
  71. package/src/components/chat/tools/adapter-claude/GlobTool.scss +88 -0
  72. package/src/components/chat/tools/adapter-claude/GlobTool.tsx +85 -0
  73. package/src/components/chat/tools/adapter-claude/GrepTool.scss +96 -0
  74. package/src/components/chat/tools/adapter-claude/GrepTool.tsx +114 -0
  75. package/src/components/chat/tools/adapter-claude/LSTool.scss +85 -0
  76. package/src/components/chat/tools/adapter-claude/LSTool.tsx +94 -0
  77. package/src/components/chat/tools/adapter-claude/ReadTool.scss +57 -0
  78. package/src/components/chat/tools/adapter-claude/ReadTool.tsx +87 -0
  79. package/src/components/chat/tools/adapter-claude/TodoTool.scss +78 -0
  80. package/src/components/chat/tools/adapter-claude/TodoTool.tsx +60 -0
  81. package/src/components/chat/tools/adapter-claude/WriteTool.scss +92 -0
  82. package/src/components/chat/tools/adapter-claude/WriteTool.tsx +86 -0
  83. package/src/components/chat/tools/adapter-claude/components/FileList.scss +65 -0
  84. package/src/components/chat/tools/adapter-claude/components/FileList.tsx +185 -0
  85. package/src/components/chat/tools/adapter-claude/index.ts +28 -0
  86. package/src/components/chat/tools/defineToolRender.ts +28 -0
  87. package/src/components/chat/tools/task/GetTaskInfoTool.scss +50 -0
  88. package/src/components/chat/tools/task/GetTaskInfoTool.tsx +88 -0
  89. package/src/components/chat/tools/task/ListTasksTool.scss +56 -0
  90. package/src/components/chat/tools/task/ListTasksTool.tsx +83 -0
  91. package/src/components/chat/tools/task/StartTasksTool.scss +56 -0
  92. package/src/components/chat/tools/task/StartTasksTool.tsx +96 -0
  93. package/src/components/chat/tools/task/components/TaskToolCard.scss +127 -0
  94. package/src/components/chat/tools/task/components/TaskToolCard.tsx +177 -0
  95. package/src/components/chat/tools/task/index.ts +15 -0
  96. package/src/components/chat/useChatModels.tsx +206 -0
  97. package/src/components/chat/useChatSession.ts +370 -0
  98. package/src/components/config/ConfigAboutSection.scss +111 -0
  99. package/src/components/config/ConfigAboutSection.tsx +86 -0
  100. package/src/components/config/ConfigDisplayValue.scss +22 -0
  101. package/src/components/config/ConfigDisplayValue.tsx +62 -0
  102. package/src/components/config/ConfigEditors.scss +65 -0
  103. package/src/components/config/ConfigEditors.tsx +98 -0
  104. package/src/components/config/ConfigFieldRow.scss +97 -0
  105. package/src/components/config/ConfigFieldRow.tsx +36 -0
  106. package/src/components/config/ConfigSectionForm.scss +94 -0
  107. package/src/components/config/ConfigSectionForm.tsx +436 -0
  108. package/src/components/config/ConfigSectionPanel.tsx +67 -0
  109. package/src/components/config/ConfigShortcutInput.scss +11 -0
  110. package/src/components/config/ConfigShortcutInput.tsx +52 -0
  111. package/src/components/config/ConfigSourceSwitch.tsx +57 -0
  112. package/src/components/config/configSchema.ts +319 -0
  113. package/src/components/config/configUtils.ts +83 -0
  114. package/src/components/config/index.tsx +5 -0
  115. package/src/components/config/recordEditors/BooleanRecordEditor.scss +1 -0
  116. package/src/components/config/recordEditors/BooleanRecordEditor.tsx +75 -0
  117. package/src/components/config/recordEditors/KeyValueEditor.scss +1 -0
  118. package/src/components/config/recordEditors/KeyValueEditor.tsx +97 -0
  119. package/src/components/config/recordEditors/McpServersRecordEditor.scss +1 -0
  120. package/src/components/config/recordEditors/McpServersRecordEditor.tsx +258 -0
  121. package/src/components/config/recordEditors/ModelServicesRecordEditor.scss +1 -0
  122. package/src/components/config/recordEditors/ModelServicesRecordEditor.tsx +233 -0
  123. package/src/components/config/recordEditors/RecordEditors.scss +117 -0
  124. package/src/components/config/recordEditors/RecordJsonEditor.scss +1 -0
  125. package/src/components/config/recordEditors/RecordJsonEditor.tsx +113 -0
  126. package/src/components/config/recordEditors/index.tsx +5 -0
  127. package/src/components/knowledge-base/KnowledgeBaseView.scss +19 -0
  128. package/src/components/knowledge-base/KnowledgeBaseView.tsx +186 -0
  129. package/src/components/knowledge-base/components/ActionButton.scss +5 -0
  130. package/src/components/knowledge-base/components/ActionButton.tsx +9 -0
  131. package/src/components/knowledge-base/components/EmptyState.scss +19 -0
  132. package/src/components/knowledge-base/components/EmptyState.tsx +42 -0
  133. package/src/components/knowledge-base/components/EntitiesTab.scss +5 -0
  134. package/src/components/knowledge-base/components/EntitiesTab.tsx +80 -0
  135. package/src/components/knowledge-base/components/EntityItem.scss +82 -0
  136. package/src/components/knowledge-base/components/EntityItem.tsx +79 -0
  137. package/src/components/knowledge-base/components/EntityList.scss +5 -0
  138. package/src/components/knowledge-base/components/EntityList.tsx +70 -0
  139. package/src/components/knowledge-base/components/FilterBar.scss +21 -0
  140. package/src/components/knowledge-base/components/FilterBar.tsx +51 -0
  141. package/src/components/knowledge-base/components/FlowsTab.scss +5 -0
  142. package/src/components/knowledge-base/components/FlowsTab.tsx +80 -0
  143. package/src/components/knowledge-base/components/KnowledgeBaseHeader.scss +27 -0
  144. package/src/components/knowledge-base/components/KnowledgeBaseHeader.tsx +29 -0
  145. package/src/components/knowledge-base/components/KnowledgeList.scss +19 -0
  146. package/src/components/knowledge-base/components/KnowledgeList.tsx +19 -0
  147. package/src/components/knowledge-base/components/LoadingState.scss +5 -0
  148. package/src/components/knowledge-base/components/LoadingState.tsx +11 -0
  149. package/src/components/knowledge-base/components/MetaList.scss +19 -0
  150. package/src/components/knowledge-base/components/MetaList.tsx +18 -0
  151. package/src/components/knowledge-base/components/RulesTab.scss +5 -0
  152. package/src/components/knowledge-base/components/RulesTab.tsx +49 -0
  153. package/src/components/knowledge-base/components/SectionHeader.scss +22 -0
  154. package/src/components/knowledge-base/components/SectionHeader.tsx +21 -0
  155. package/src/components/knowledge-base/components/SkillsTab.scss +5 -0
  156. package/src/components/knowledge-base/components/SkillsTab.tsx +49 -0
  157. package/src/components/knowledge-base/components/SpecItem.scss +138 -0
  158. package/src/components/knowledge-base/components/SpecItem.tsx +131 -0
  159. package/src/components/knowledge-base/components/SpecList.scss +5 -0
  160. package/src/components/knowledge-base/components/SpecList.tsx +70 -0
  161. package/src/components/knowledge-base/components/TabContent.scss +8 -0
  162. package/src/components/knowledge-base/components/TabContent.tsx +17 -0
  163. package/src/components/knowledge-base/components/TabLabel.scss +10 -0
  164. package/src/components/knowledge-base/components/TabLabel.tsx +15 -0
  165. package/src/components/knowledge-base/index.tsx +1 -0
  166. package/src/components/sidebar/SessionItem.scss +256 -0
  167. package/src/components/sidebar/SessionItem.tsx +265 -0
  168. package/src/components/sidebar/SessionList.scss +92 -0
  169. package/src/components/sidebar/SessionList.tsx +166 -0
  170. package/src/components/sidebar/SidebarHeader.scss +79 -0
  171. package/src/components/sidebar/SidebarHeader.tsx +128 -0
  172. package/src/connectionManager.ts +172 -0
  173. package/src/hooks/useGlobalShortcut.ts +26 -0
  174. package/src/hooks/useQueryParams.ts +54 -0
  175. package/src/i18n.ts +22 -0
  176. package/src/main.tsx +41 -0
  177. package/src/resources/locales/en.json +765 -0
  178. package/src/resources/locales/zh.json +766 -0
  179. package/src/store/index.ts +23 -0
  180. package/src/styles/global.scss +100 -0
  181. package/src/utils/shortcutUtils.ts +88 -0
  182. package/src/vite-env.d.ts +12 -0
  183. package/src/ws.ts +33 -0
  184. package/vite.config.ts +26 -0
@@ -0,0 +1,131 @@
1
+ import './SpecItem.scss'
2
+
3
+ import { Button, Empty, Popover, Tag, Tooltip } from 'antd'
4
+ import React from 'react'
5
+ import { useTranslation } from 'react-i18next'
6
+ import useSWR from 'swr'
7
+
8
+ import type { SpecDetail, SpecSummary } from '#~/api.js'
9
+ import { getSpecDetail } from '#~/api.js'
10
+ import { MarkdownContent } from '#~/components/chat/MarkdownContent'
11
+ import { LoadingState } from './LoadingState'
12
+ import { MetaList } from './MetaList'
13
+
14
+ type SpecItemProps = {
15
+ spec: SpecSummary
16
+ }
17
+
18
+ export function SpecItem({ spec }: SpecItemProps) {
19
+ const { t } = useTranslation()
20
+ const [expanded, setExpanded] = React.useState(false)
21
+ const { data, isLoading } = useSWR<{ spec: SpecDetail }>(
22
+ expanded ? ['spec-detail', spec.id] : null,
23
+ () => getSpecDetail(spec.id)
24
+ )
25
+ const detail = data?.spec
26
+ const body = detail?.body ?? ''
27
+ const tags = spec.tags ?? []
28
+ const skills = spec.skills ?? []
29
+ const rules = spec.rules ?? []
30
+
31
+ return (
32
+ <div className='knowledge-base-view__item'>
33
+ <div className='knowledge-base-view__item-row'>
34
+ <div className='knowledge-base-view__item-main'>
35
+ <div className='knowledge-base-view__item-title'>
36
+ <span className='material-symbols-rounded knowledge-base-view__item-icon'>account_tree</span>
37
+ <span>{spec.name}</span>
38
+ </div>
39
+ <div className='knowledge-base-view__item-desc'>{spec.description}</div>
40
+ {spec.params.length > 0 && (
41
+ <div className='knowledge-base-view__params'>
42
+ {spec.params.map(param => (
43
+ <div key={param.name} className='knowledge-base-view__param'>
44
+ <span className='material-symbols-rounded knowledge-base-view__param-icon'>tune</span>
45
+ <div className='knowledge-base-view__param-text'>
46
+ <span className='knowledge-base-view__param-name'>{param.name}</span>
47
+ {param.description && (
48
+ <span className='knowledge-base-view__param-desc'>{param.description}</span>
49
+ )}
50
+ </div>
51
+ </div>
52
+ ))}
53
+ </div>
54
+ )}
55
+ {tags.length > 0 && (
56
+ <div className='knowledge-base-view__tag-list'>
57
+ {tags.map(tag => (
58
+ <Tag key={tag} className='knowledge-base-view__tag'>
59
+ <span className='material-symbols-rounded knowledge-base-view__tag-icon'>sell</span>
60
+ <span>{tag}</span>
61
+ </Tag>
62
+ ))}
63
+ </div>
64
+ )}
65
+ </div>
66
+ <div className='knowledge-base-view__item-meta'>
67
+ {spec.always && (
68
+ <Tag color='blue'>{t('knowledge.meta.always')}</Tag>
69
+ )}
70
+ <div className='knowledge-base-view__meta-pills'>
71
+ <Popover
72
+ content={<MetaList items={skills} />}
73
+ title={t('knowledge.meta.skills')}
74
+ trigger='click'
75
+ placement='bottomRight'
76
+ >
77
+ <Button
78
+ type='text'
79
+ className='knowledge-base-view__meta-pill'
80
+ disabled={skills.length === 0}
81
+ >
82
+ <span className='material-symbols-rounded knowledge-base-view__meta-pill-icon'>psychology</span>
83
+ <span>{t('knowledge.meta.skillsCount', { count: skills.length })}</span>
84
+ </Button>
85
+ </Popover>
86
+ <Popover
87
+ content={<MetaList items={rules} />}
88
+ title={t('knowledge.meta.rules')}
89
+ trigger='click'
90
+ placement='bottomRight'
91
+ >
92
+ <Button
93
+ type='text'
94
+ className='knowledge-base-view__meta-pill'
95
+ disabled={rules.length === 0}
96
+ >
97
+ <span className='material-symbols-rounded knowledge-base-view__meta-pill-icon'>gavel</span>
98
+ <span>{t('knowledge.meta.rulesCount', { count: rules.length })}</span>
99
+ </Button>
100
+ </Popover>
101
+ </div>
102
+ <Tooltip title={expanded ? t('knowledge.actions.collapse') : t('knowledge.actions.expand')}>
103
+ <Button
104
+ type='text'
105
+ className='knowledge-base-view__icon-button'
106
+ onClick={() => setExpanded(prev => !prev)}
107
+ icon={
108
+ <span className='material-symbols-rounded'>
109
+ {expanded ? 'expand_less' : 'expand_more'}
110
+ </span>
111
+ }
112
+ />
113
+ </Tooltip>
114
+ </div>
115
+ </div>
116
+ {expanded && (
117
+ <div className='knowledge-base-view__detail'>
118
+ {isLoading && <LoadingState />}
119
+ {!isLoading && body.trim() === '' && (
120
+ <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={t('knowledge.flows.noContent')} />
121
+ )}
122
+ {!isLoading && body.trim() !== '' && (
123
+ <div className='knowledge-base-view__markdown'>
124
+ <MarkdownContent content={body} />
125
+ </div>
126
+ )}
127
+ </div>
128
+ )}
129
+ </div>
130
+ )
131
+ }
@@ -0,0 +1,5 @@
1
+ .knowledge-base-view__spec-list {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 12px;
5
+ }
@@ -0,0 +1,70 @@
1
+ import './SpecList.scss'
2
+
3
+ import { List } from 'antd'
4
+ import { useTranslation } from 'react-i18next'
5
+
6
+ import type { SpecSummary } from '#~/api.js'
7
+ import { EmptyState } from './EmptyState'
8
+ import { KnowledgeList } from './KnowledgeList'
9
+ import { LoadingState } from './LoadingState'
10
+ import { SpecItem } from './SpecItem'
11
+
12
+ type SpecListProps = {
13
+ isLoading: boolean
14
+ specs: SpecSummary[]
15
+ filteredSpecs: SpecSummary[]
16
+ onCreate: () => void
17
+ }
18
+
19
+ export function SpecList({
20
+ isLoading,
21
+ specs,
22
+ filteredSpecs,
23
+ onCreate
24
+ }: SpecListProps) {
25
+ const { t } = useTranslation()
26
+
27
+ if (isLoading) {
28
+ return (
29
+ <div className='knowledge-base-view__spec-list'>
30
+ <LoadingState />
31
+ </div>
32
+ )
33
+ }
34
+
35
+ if (specs.length === 0) {
36
+ return (
37
+ <div className='knowledge-base-view__spec-list'>
38
+ <EmptyState
39
+ description={t('knowledge.flows.empty')}
40
+ actionLabel={t('knowledge.flows.create')}
41
+ onAction={onCreate}
42
+ />
43
+ </div>
44
+ )
45
+ }
46
+
47
+ if (filteredSpecs.length === 0) {
48
+ return (
49
+ <div className='knowledge-base-view__spec-list'>
50
+ <EmptyState
51
+ description={t('knowledge.filters.noResults')}
52
+ variant='simple'
53
+ />
54
+ </div>
55
+ )
56
+ }
57
+
58
+ return (
59
+ <div className='knowledge-base-view__spec-list'>
60
+ <KnowledgeList
61
+ data={filteredSpecs}
62
+ renderItem={(spec) => (
63
+ <List.Item className='knowledge-base-view__list-item'>
64
+ <SpecItem spec={spec} />
65
+ </List.Item>
66
+ )}
67
+ />
68
+ </div>
69
+ )
70
+ }
@@ -0,0 +1,8 @@
1
+ .knowledge-base-view__content {
2
+ height: 100%;
3
+ overflow: auto;
4
+ padding: 16px 24px 24px;
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 16px;
8
+ }
@@ -0,0 +1,17 @@
1
+ import './TabContent.scss'
2
+
3
+ import type { ReactNode } from 'react'
4
+
5
+ type TabContentProps = {
6
+ children: ReactNode
7
+ className?: string
8
+ }
9
+
10
+ export function TabContent({ children, className }: TabContentProps) {
11
+ const mergedClassName = ['knowledge-base-view__content', className].filter(Boolean).join(' ')
12
+ return (
13
+ <div className={mergedClassName}>
14
+ {children}
15
+ </div>
16
+ )
17
+ }
@@ -0,0 +1,10 @@
1
+ .knowledge-base-view__tab-label {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: 8px;
5
+ }
6
+
7
+ .knowledge-base-view__tab-icon {
8
+ font-size: 18px;
9
+ color: var(--sub-text-color);
10
+ }
@@ -0,0 +1,15 @@
1
+ import './TabLabel.scss'
2
+
3
+ type TabLabelProps = {
4
+ icon: string
5
+ label: string
6
+ }
7
+
8
+ export function TabLabel({ icon, label }: TabLabelProps) {
9
+ return (
10
+ <span className='knowledge-base-view__tab-label'>
11
+ <span className='material-symbols-rounded knowledge-base-view__tab-icon'>{icon}</span>
12
+ <span>{label}</span>
13
+ </span>
14
+ )
15
+ }
@@ -0,0 +1 @@
1
+ export { KnowledgeBaseView } from './KnowledgeBaseView.js'
@@ -0,0 +1,256 @@
1
+ .session-item {
2
+ color: var(--text-color);
3
+ cursor: pointer;
4
+ padding: 12px !important;
5
+ position: relative;
6
+ border: 1px solid var(--border-color) !important;
7
+ border-radius: 12px;
8
+ transition: all .2s ease;
9
+ background-color: var(--bg-color);
10
+
11
+ &:hover {
12
+ background-color: var(--sidebar-hover-bg);
13
+ border-color: var(--sidebar-hover-bg) !important;
14
+
15
+ .session-item-actions {
16
+ opacity: 1;
17
+ }
18
+ }
19
+
20
+ &.active {
21
+ background-color: var(--sidebar-active-bg) !important;
22
+ border-color: var(--sidebar-active-text) !important;
23
+ color: var(--sidebar-active-text) !important;
24
+
25
+ .session-item-actions {
26
+ opacity: 1;
27
+ }
28
+ }
29
+
30
+ &.selected {
31
+ background-color: var(--sidebar-active-bg) !important;
32
+ border-color: var(--sidebar-active-text) !important;
33
+ }
34
+
35
+ .session-item-content {
36
+ display: flex;
37
+ align-items: flex-start;
38
+ width: 100%;
39
+ gap: 12px;
40
+
41
+ .status-dot {
42
+ width: 10px;
43
+ height: 10px;
44
+ border-radius: 50%;
45
+ background-color: var(--sub-text-color); // Default gray
46
+ opacity: .3;
47
+ flex-shrink: 0;
48
+ margin-top: 5px;
49
+ margin-right: -4px; // Pull closer to the text
50
+ transition: all .2s;
51
+
52
+ &.active {
53
+ background-color: var(--sidebar-active-text); // Active blue
54
+ opacity: 1;
55
+ }
56
+ }
57
+
58
+ .batch-checkbox-wrapper {
59
+ width: 32px;
60
+ height: 32px;
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ flex-shrink: 0;
65
+ }
66
+
67
+ .status-indicator {
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ width: 20px;
72
+ height: 20px;
73
+ flex-shrink: 0;
74
+ margin-top: 2px;
75
+
76
+ .status-icon {
77
+ &.spin {
78
+ animation: spin 1.5s linear infinite;
79
+ }
80
+ }
81
+
82
+ .waiting-input-indicator {
83
+ width: 14px;
84
+ height: 14px;
85
+ background-color: #faad14;
86
+ border-radius: 50%;
87
+ position: relative;
88
+ animation: pulse-yellow 2s infinite;
89
+
90
+ &::after {
91
+ content: '';
92
+ position: absolute;
93
+ top: -4px;
94
+ left: -4px;
95
+ right: -4px;
96
+ bottom: -4px;
97
+ border: 1px dashed #faad14;
98
+ border-radius: 50%;
99
+ animation: spin 3s linear infinite;
100
+ }
101
+ }
102
+ }
103
+
104
+ .session-info {
105
+ flex: 1;
106
+ min-width: 0;
107
+ display: flex;
108
+ flex-direction: column;
109
+ gap: 4px;
110
+
111
+ &.with-actions {
112
+ padding-right: 0; // Remove padding as actions are positioned differently
113
+ }
114
+
115
+ .session-header {
116
+ display: flex;
117
+ justify-content: space-between;
118
+ align-items: flex-start;
119
+ gap: 8px;
120
+
121
+ .session-title {
122
+ flex: 1;
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 8px;
126
+ min-width: 0;
127
+
128
+ .session-title-text {
129
+ font-weight: 500;
130
+ overflow: hidden;
131
+ text-overflow: ellipsis;
132
+ white-space: nowrap;
133
+ font-size: 14px;
134
+ }
135
+ }
136
+ }
137
+
138
+ .last-message {
139
+ font-size: 12px;
140
+ color: var(--sub-text-color);
141
+ overflow: hidden;
142
+ text-overflow: ellipsis;
143
+ white-space: nowrap;
144
+ line-height: 1.5;
145
+ }
146
+
147
+ .session-meta {
148
+ display: flex;
149
+ justify-content: space-between;
150
+ align-items: center;
151
+ margin-top: 4px;
152
+
153
+ .time-display {
154
+ font-size: 11px;
155
+ color: var(--sub-text-color);
156
+ }
157
+ }
158
+
159
+ .tags-container {
160
+ display: flex;
161
+ flex-wrap: wrap;
162
+ gap: 4px;
163
+ align-items: center;
164
+
165
+ .session-tag {
166
+ font-size: 10px;
167
+ margin: 0;
168
+ padding: 0 4px;
169
+ line-height: 14px;
170
+ border-radius: 2px;
171
+
172
+ &--automation {
173
+ padding: 0 6px;
174
+ }
175
+
176
+ &__link {
177
+ color: var(--primary-color);
178
+ text-decoration: none;
179
+ }
180
+ }
181
+ }
182
+
183
+ }
184
+ }
185
+
186
+ .session-item-badge {
187
+ position: absolute;
188
+ top: -6px;
189
+ right: -6px;
190
+ z-index: 20;
191
+
192
+ .ant-badge-count {
193
+ background-color: var(--sub-text-color) !important;
194
+ color: #fff;
195
+ box-shadow: none;
196
+ }
197
+ }
198
+
199
+ .session-item-actions {
200
+ display: flex;
201
+ gap: 4px;
202
+ opacity: 0;
203
+ transition: opacity .2s ease;
204
+
205
+ .action-btn {
206
+ color: var(--sub-text-color);
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: center;
210
+ width: 20px;
211
+ height: 20px;
212
+ padding: 0;
213
+
214
+ &:hover {
215
+ background-color: transparent;
216
+ color: #3b82f6; // Blue on hover
217
+ }
218
+
219
+ &.starred {
220
+ .material-symbols-rounded {
221
+ color: #f59e0b; // Amber for starred
222
+ font-variation-settings: 'FILL' 1; // Always filled for starred state
223
+
224
+ &.filled {
225
+ font-variation-settings: 'FILL' 1;
226
+ }
227
+ }
228
+ }
229
+
230
+ .material-symbols-rounded {
231
+ font-size: 18px;
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ @keyframes spin {
238
+ from {
239
+ transform: rotate(0deg);
240
+ }
241
+ to {
242
+ transform: rotate(360deg);
243
+ }
244
+ }
245
+
246
+ @keyframes pulse-yellow {
247
+ 0% {
248
+ box-shadow: 0 0 0 0 rgba(250, 173, 20, .4);
249
+ }
250
+ 70% {
251
+ box-shadow: 0 0 0 6px rgba(250, 173, 20, 0);
252
+ }
253
+ 100% {
254
+ box-shadow: 0 0 0 0 rgba(250, 173, 20, 0);
255
+ }
256
+ }