bingocode 1.0.2 → 1.0.3

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 (186) hide show
  1. package/desktop/README.md +30 -0
  2. package/desktop/bunfig.toml +1 -0
  3. package/desktop/index.html +17 -0
  4. package/desktop/package.json +55 -0
  5. package/desktop/pnpm-lock.yaml +3832 -0
  6. package/desktop/public/app-icon.jpg +0 -0
  7. package/desktop/public/fonts/inter-latin-ext.woff2 +0 -0
  8. package/desktop/public/fonts/inter-latin.woff2 +0 -0
  9. package/desktop/public/fonts/jetbrains-mono-latin-ext.woff2 +0 -0
  10. package/desktop/public/fonts/jetbrains-mono-latin.woff2 +0 -0
  11. package/desktop/public/fonts/manrope-latin-ext.woff2 +0 -0
  12. package/desktop/public/fonts/manrope-latin.woff2 +0 -0
  13. package/desktop/public/fonts/material-symbols-outlined.woff2 +0 -0
  14. package/desktop/public/icons/bilibili.svg +1 -0
  15. package/desktop/public/icons/douyin.svg +1 -0
  16. package/desktop/public/icons/github.svg +3 -0
  17. package/desktop/public/icons/xiaohongshu.svg +1 -0
  18. package/desktop/scripts/build-macos-arm64.sh +270 -0
  19. package/desktop/scripts/build-sidecars.ts +183 -0
  20. package/desktop/scripts/build-windows-x64.ps1 +295 -0
  21. package/desktop/scripts/scan-missing-imports.ts +235 -0
  22. package/desktop/sidecars/claude-sidecar.ts +156 -0
  23. package/desktop/src/App.tsx +5 -0
  24. package/desktop/src/__tests__/agentsSettings.test.tsx +349 -0
  25. package/desktop/src/__tests__/pages.test.tsx +290 -0
  26. package/desktop/src/__tests__/skillsSettings.test.tsx +205 -0
  27. package/desktop/src/api/adapters.ts +12 -0
  28. package/desktop/src/api/agents.ts +36 -0
  29. package/desktop/src/api/cliTasks.ts +28 -0
  30. package/desktop/src/api/client.ts +63 -0
  31. package/desktop/src/api/computerUse.ts +76 -0
  32. package/desktop/src/api/filesystem.ts +30 -0
  33. package/desktop/src/api/hahaOAuth.ts +38 -0
  34. package/desktop/src/api/models.ts +28 -0
  35. package/desktop/src/api/providers.ts +63 -0
  36. package/desktop/src/api/search.ts +29 -0
  37. package/desktop/src/api/sessions.ts +56 -0
  38. package/desktop/src/api/settings.ts +20 -0
  39. package/desktop/src/api/skills.ts +19 -0
  40. package/desktop/src/api/tasks.ts +36 -0
  41. package/desktop/src/api/teams.ts +44 -0
  42. package/desktop/src/api/websocket.ts +164 -0
  43. package/desktop/src/components/chat/AskUserQuestion.tsx +268 -0
  44. package/desktop/src/components/chat/AssistantMessage.tsx +29 -0
  45. package/desktop/src/components/chat/AttachmentGallery.tsx +113 -0
  46. package/desktop/src/components/chat/ChatInput.tsx +622 -0
  47. package/desktop/src/components/chat/CodeViewer.tsx +161 -0
  48. package/desktop/src/components/chat/ComputerUsePermissionModal.test.tsx +174 -0
  49. package/desktop/src/components/chat/ComputerUsePermissionModal.tsx +311 -0
  50. package/desktop/src/components/chat/DiffViewer.tsx +157 -0
  51. package/desktop/src/components/chat/FileSearchMenu.tsx +198 -0
  52. package/desktop/src/components/chat/ImageGalleryModal.tsx +91 -0
  53. package/desktop/src/components/chat/InlineImageGallery.tsx +106 -0
  54. package/desktop/src/components/chat/InlineTaskSummary.tsx +60 -0
  55. package/desktop/src/components/chat/MermaidRenderer.test.tsx +98 -0
  56. package/desktop/src/components/chat/MermaidRenderer.tsx +361 -0
  57. package/desktop/src/components/chat/MessageActionBar.tsx +27 -0
  58. package/desktop/src/components/chat/MessageList.test.tsx +313 -0
  59. package/desktop/src/components/chat/MessageList.tsx +249 -0
  60. package/desktop/src/components/chat/PermissionDialog.tsx +262 -0
  61. package/desktop/src/components/chat/SessionTaskBar.test.tsx +99 -0
  62. package/desktop/src/components/chat/SessionTaskBar.tsx +159 -0
  63. package/desktop/src/components/chat/StreamingIndicator.tsx +41 -0
  64. package/desktop/src/components/chat/TerminalChrome.tsx +35 -0
  65. package/desktop/src/components/chat/ThinkingBlock.tsx +87 -0
  66. package/desktop/src/components/chat/ToolCallBlock.tsx +247 -0
  67. package/desktop/src/components/chat/ToolCallGroup.tsx +617 -0
  68. package/desktop/src/components/chat/ToolResultBlock.tsx +107 -0
  69. package/desktop/src/components/chat/UserMessage.tsx +38 -0
  70. package/desktop/src/components/chat/chatBlocks.test.tsx +136 -0
  71. package/desktop/src/components/chat/clipboard.ts +25 -0
  72. package/desktop/src/components/chat/composerUtils.test.ts +55 -0
  73. package/desktop/src/components/chat/composerUtils.ts +149 -0
  74. package/desktop/src/components/controls/ModelSelector.tsx +156 -0
  75. package/desktop/src/components/controls/PermissionModeSelector.tsx +229 -0
  76. package/desktop/src/components/layout/AppShell.tsx +107 -0
  77. package/desktop/src/components/layout/ContentRouter.tsx +27 -0
  78. package/desktop/src/components/layout/ProjectFilter.tsx +126 -0
  79. package/desktop/src/components/layout/Sidebar.test.tsx +158 -0
  80. package/desktop/src/components/layout/Sidebar.tsx +384 -0
  81. package/desktop/src/components/layout/StatusBar.tsx +31 -0
  82. package/desktop/src/components/layout/TabBar.test.tsx +136 -0
  83. package/desktop/src/components/layout/TabBar.tsx +318 -0
  84. package/desktop/src/components/layout/TitleBar.tsx +96 -0
  85. package/desktop/src/components/layout/WindowControls.test.tsx +69 -0
  86. package/desktop/src/components/layout/WindowControls.tsx +89 -0
  87. package/desktop/src/components/markdown/MarkdownRenderer.test.tsx +100 -0
  88. package/desktop/src/components/markdown/MarkdownRenderer.tsx +229 -0
  89. package/desktop/src/components/settings/ClaudeOfficialLogin.tsx +107 -0
  90. package/desktop/src/components/shared/Button.tsx +63 -0
  91. package/desktop/src/components/shared/CopyButton.tsx +58 -0
  92. package/desktop/src/components/shared/DirectoryPicker.tsx +316 -0
  93. package/desktop/src/components/shared/Dropdown.tsx +91 -0
  94. package/desktop/src/components/shared/Input.tsx +38 -0
  95. package/desktop/src/components/shared/Modal.tsx +65 -0
  96. package/desktop/src/components/shared/ProjectContextChip.tsx +30 -0
  97. package/desktop/src/components/shared/Spinner.tsx +30 -0
  98. package/desktop/src/components/shared/Textarea.tsx +38 -0
  99. package/desktop/src/components/shared/Toast.tsx +47 -0
  100. package/desktop/src/components/shared/UpdateChecker.tsx +90 -0
  101. package/desktop/src/components/skills/SkillDetail.test.tsx +89 -0
  102. package/desktop/src/components/skills/SkillDetail.tsx +403 -0
  103. package/desktop/src/components/skills/SkillList.tsx +254 -0
  104. package/desktop/src/components/tasks/DayOfWeekPicker.tsx +57 -0
  105. package/desktop/src/components/tasks/NewTaskModal.tsx +407 -0
  106. package/desktop/src/components/tasks/PromptEditor.tsx +74 -0
  107. package/desktop/src/components/tasks/TaskEmptyState.tsx +30 -0
  108. package/desktop/src/components/tasks/TaskList.tsx +46 -0
  109. package/desktop/src/components/tasks/TaskRow.tsx +253 -0
  110. package/desktop/src/components/tasks/TaskRunsPanel.tsx +195 -0
  111. package/desktop/src/components/teams/TeamStatusBar.tsx +147 -0
  112. package/desktop/src/config/providerPresets.ts +78 -0
  113. package/desktop/src/config/spinnerVerbs.ts +193 -0
  114. package/desktop/src/hooks/useKeyboardShortcuts.ts +60 -0
  115. package/desktop/src/i18n/index.ts +54 -0
  116. package/desktop/src/i18n/locales/en.ts +670 -0
  117. package/desktop/src/i18n/locales/zh.ts +670 -0
  118. package/desktop/src/lib/__tests__/cronDescribe.test.ts +93 -0
  119. package/desktop/src/lib/cronDescribe.ts +188 -0
  120. package/desktop/src/lib/desktopRuntime.ts +54 -0
  121. package/desktop/src/lib/parseRunOutput.ts +79 -0
  122. package/desktop/src/main.tsx +13 -0
  123. package/desktop/src/mocks/data.ts +202 -0
  124. package/desktop/src/pages/ActiveSession.test.tsx +181 -0
  125. package/desktop/src/pages/ActiveSession.tsx +219 -0
  126. package/desktop/src/pages/AdapterSettings.tsx +375 -0
  127. package/desktop/src/pages/AgentTeams.tsx +200 -0
  128. package/desktop/src/pages/ComputerUseSettings.tsx +420 -0
  129. package/desktop/src/pages/EmptySession.tsx +518 -0
  130. package/desktop/src/pages/NewTaskModal.tsx +346 -0
  131. package/desktop/src/pages/ScheduledTasks.tsx +66 -0
  132. package/desktop/src/pages/ScheduledTasksEmpty.tsx +152 -0
  133. package/desktop/src/pages/ScheduledTasksList.tsx +416 -0
  134. package/desktop/src/pages/SessionControls.tsx +460 -0
  135. package/desktop/src/pages/Settings.tsx +1448 -0
  136. package/desktop/src/pages/ToolInspection.tsx +235 -0
  137. package/desktop/src/stores/adapterStore.ts +106 -0
  138. package/desktop/src/stores/agentStore.ts +34 -0
  139. package/desktop/src/stores/chatStore.test.ts +505 -0
  140. package/desktop/src/stores/chatStore.ts +850 -0
  141. package/desktop/src/stores/cliTaskStore.ts +152 -0
  142. package/desktop/src/stores/hahaOAuthStore.test.ts +77 -0
  143. package/desktop/src/stores/hahaOAuthStore.ts +97 -0
  144. package/desktop/src/stores/providerStore.ts +101 -0
  145. package/desktop/src/stores/sessionStore.test.ts +63 -0
  146. package/desktop/src/stores/sessionStore.ts +102 -0
  147. package/desktop/src/stores/settingsStore.ts +120 -0
  148. package/desktop/src/stores/skillStore.ts +51 -0
  149. package/desktop/src/stores/tabStore.ts +169 -0
  150. package/desktop/src/stores/taskStore.ts +68 -0
  151. package/desktop/src/stores/teamStore.ts +344 -0
  152. package/desktop/src/stores/uiStore.ts +100 -0
  153. package/desktop/src/stores/updateStore.test.ts +71 -0
  154. package/desktop/src/stores/updateStore.ts +221 -0
  155. package/desktop/src/theme/globals.css +465 -0
  156. package/desktop/src/types/adapter.ts +33 -0
  157. package/desktop/src/types/chat.ts +152 -0
  158. package/desktop/src/types/cliTask.ts +24 -0
  159. package/desktop/src/types/provider.ts +62 -0
  160. package/desktop/src/types/session.ts +27 -0
  161. package/desktop/src/types/settings.ts +22 -0
  162. package/desktop/src/types/skill.ts +38 -0
  163. package/desktop/src/types/task.ts +56 -0
  164. package/desktop/src/types/team.ts +38 -0
  165. package/desktop/src-tauri/Cargo.lock +5549 -0
  166. package/desktop/src-tauri/Cargo.toml +20 -0
  167. package/desktop/src-tauri/app-icon.svg +13 -0
  168. package/desktop/src-tauri/build.rs +3 -0
  169. package/desktop/src-tauri/capabilities/default.json +106 -0
  170. package/desktop/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  171. package/desktop/src-tauri/icons/android/values/ic_launcher_background.xml +4 -0
  172. package/desktop/src-tauri/icons/icon.icns +0 -0
  173. package/desktop/src-tauri/icons/icon.ico +0 -0
  174. package/desktop/src-tauri/src/lib.rs +408 -0
  175. package/desktop/src-tauri/src/main.rs +6 -0
  176. package/desktop/src-tauri/tauri.conf.json +78 -0
  177. package/desktop/src-tauri/tauri.macos.conf.json +18 -0
  178. package/desktop/src-tauri/tauri.release-ci.json +5 -0
  179. package/desktop/src-tauri/tauri.windows.conf.json +16 -0
  180. package/desktop/src-tauri/windows-installer-hooks.nsh +17 -0
  181. package/desktop/tsconfig.json +25 -0
  182. package/desktop/vite.config.ts +26 -0
  183. package/desktop/vitest.config.ts +18 -0
  184. package/package.json +1 -1
  185. package/src/commands/desktop/desktop.tsx +9 -0
  186. package/src/commands/desktop/index.ts +26 -0
@@ -0,0 +1,221 @@
1
+ import { create } from 'zustand'
2
+ import type { Update } from '@tauri-apps/plugin-updater'
3
+ import { isTauriRuntime } from '../lib/desktopRuntime'
4
+
5
+ export type UpdateStatus =
6
+ | 'idle'
7
+ | 'checking'
8
+ | 'available'
9
+ | 'up-to-date'
10
+ | 'downloading'
11
+ | 'restarting'
12
+ | 'error'
13
+
14
+ type CheckOptions = {
15
+ silent?: boolean
16
+ }
17
+
18
+ type UpdateStore = {
19
+ status: UpdateStatus
20
+ availableVersion: string | null
21
+ releaseNotes: string | null
22
+ progressPercent: number
23
+ downloadedBytes: number
24
+ totalBytes: number | null
25
+ error: string | null
26
+ checkedAt: number | null
27
+ shouldPrompt: boolean
28
+ initialize: () => Promise<void>
29
+ checkForUpdates: (options?: CheckOptions) => Promise<Update | null>
30
+ installUpdate: () => Promise<void>
31
+ dismissPrompt: () => void
32
+ }
33
+
34
+ let pendingUpdate: Update | null = null
35
+ let startupCheckPromise: Promise<void> | null = null
36
+
37
+ async function setPendingUpdate(next: Update | null) {
38
+ const previous = pendingUpdate
39
+ pendingUpdate = next
40
+
41
+ if (previous && previous !== next) {
42
+ try {
43
+ await previous.close()
44
+ } catch {
45
+ // Ignore stale resource cleanup failures.
46
+ }
47
+ }
48
+ }
49
+
50
+ function getErrorMessage(error: unknown) {
51
+ return error instanceof Error ? error.message : String(error)
52
+ }
53
+
54
+ export const useUpdateStore = create<UpdateStore>((set, get) => ({
55
+ status: 'idle',
56
+ availableVersion: null,
57
+ releaseNotes: null,
58
+ progressPercent: 0,
59
+ downloadedBytes: 0,
60
+ totalBytes: null,
61
+ error: null,
62
+ checkedAt: null,
63
+ shouldPrompt: false,
64
+
65
+ initialize: async () => {
66
+ if (!isTauriRuntime()) return
67
+ if (!startupCheckPromise) {
68
+ startupCheckPromise = (async () => {
69
+ await new Promise((resolve) => setTimeout(resolve, 5000))
70
+ await get().checkForUpdates({ silent: true })
71
+ })().finally(() => {
72
+ startupCheckPromise = null
73
+ })
74
+ }
75
+
76
+ await startupCheckPromise
77
+ },
78
+
79
+ checkForUpdates: async ({ silent = false } = {}) => {
80
+ if (!isTauriRuntime()) return null
81
+
82
+ set((state) => ({
83
+ ...state,
84
+ status: 'checking',
85
+ error: null,
86
+ }))
87
+
88
+ try {
89
+ const { check } = await import('@tauri-apps/plugin-updater')
90
+ const update = await check()
91
+ await setPendingUpdate(update)
92
+
93
+ const checkedAt = Date.now()
94
+
95
+ if (!update) {
96
+ set((state) => ({
97
+ ...state,
98
+ status: 'up-to-date',
99
+ availableVersion: null,
100
+ releaseNotes: null,
101
+ progressPercent: 0,
102
+ downloadedBytes: 0,
103
+ totalBytes: null,
104
+ checkedAt,
105
+ error: null,
106
+ shouldPrompt: false,
107
+ }))
108
+ return null
109
+ }
110
+
111
+ set((state) => ({
112
+ ...state,
113
+ status: 'available',
114
+ availableVersion: update.version,
115
+ releaseNotes: update.body ?? null,
116
+ progressPercent: 0,
117
+ downloadedBytes: 0,
118
+ totalBytes: null,
119
+ checkedAt,
120
+ error: null,
121
+ shouldPrompt: true,
122
+ }))
123
+ return update
124
+ } catch (error) {
125
+ if (!silent) {
126
+ set((state) => ({
127
+ ...state,
128
+ status: 'error',
129
+ error: getErrorMessage(error),
130
+ checkedAt: Date.now(),
131
+ }))
132
+ } else {
133
+ set((state) => ({
134
+ ...state,
135
+ status: state.availableVersion ? 'available' : 'idle',
136
+ checkedAt: Date.now(),
137
+ }))
138
+ }
139
+ return null
140
+ }
141
+ },
142
+
143
+ installUpdate: async () => {
144
+ if (!isTauriRuntime()) return
145
+
146
+ let update = pendingUpdate
147
+ if (!update) {
148
+ update = await get().checkForUpdates()
149
+ if (!update) return
150
+ }
151
+
152
+ set((state) => ({
153
+ ...state,
154
+ status: 'downloading',
155
+ error: null,
156
+ shouldPrompt: true,
157
+ progressPercent: 0,
158
+ downloadedBytes: 0,
159
+ totalBytes: null,
160
+ }))
161
+
162
+ try {
163
+ const { relaunch } = await import('@tauri-apps/plugin-process')
164
+ let totalBytes: number | null = null
165
+ let downloadedBytes = 0
166
+
167
+ await update.downloadAndInstall((event) => {
168
+ if (event.event === 'Started') {
169
+ totalBytes = event.data.contentLength ?? null
170
+ downloadedBytes = 0
171
+ set((state) => ({
172
+ ...state,
173
+ totalBytes,
174
+ downloadedBytes: 0,
175
+ progressPercent: 0,
176
+ }))
177
+ } else if (event.event === 'Progress') {
178
+ downloadedBytes += event.data.chunkLength
179
+ const progressPercent =
180
+ totalBytes && totalBytes > 0
181
+ ? Math.min(Math.round((downloadedBytes / totalBytes) * 100), 100)
182
+ : 0
183
+
184
+ set((state) => ({
185
+ ...state,
186
+ downloadedBytes,
187
+ totalBytes,
188
+ progressPercent,
189
+ }))
190
+ } else if (event.event === 'Finished') {
191
+ set((state) => ({
192
+ ...state,
193
+ progressPercent: 100,
194
+ }))
195
+ }
196
+ })
197
+
198
+ set((state) => ({
199
+ ...state,
200
+ status: 'restarting',
201
+ progressPercent: 100,
202
+ }))
203
+
204
+ await relaunch()
205
+ } catch (error) {
206
+ set((state) => ({
207
+ ...state,
208
+ status: 'available',
209
+ error: getErrorMessage(error),
210
+ shouldPrompt: true,
211
+ }))
212
+ }
213
+ },
214
+
215
+ dismissPrompt: () => {
216
+ set((state) => ({
217
+ ...state,
218
+ shouldPrompt: false,
219
+ }))
220
+ },
221
+ }))
@@ -0,0 +1,465 @@
1
+ @import "tailwindcss";
2
+ @plugin "@tailwindcss/typography";
3
+
4
+ /* ─── Self-hosted fonts (no Google CDN dependency) ────────────── */
5
+
6
+ /* Inter – variable weight 400-600, latin */
7
+ @font-face {
8
+ font-family: 'Inter';
9
+ font-style: normal;
10
+ font-weight: 400 600;
11
+ font-display: swap;
12
+ src: url('/fonts/inter-latin.woff2') format('woff2');
13
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
14
+ }
15
+ @font-face {
16
+ font-family: 'Inter';
17
+ font-style: normal;
18
+ font-weight: 400 600;
19
+ font-display: swap;
20
+ src: url('/fonts/inter-latin-ext.woff2') format('woff2');
21
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
22
+ }
23
+
24
+ /* Manrope – variable weight 400-800, latin */
25
+ @font-face {
26
+ font-family: 'Manrope';
27
+ font-style: normal;
28
+ font-weight: 400 800;
29
+ font-display: swap;
30
+ src: url('/fonts/manrope-latin.woff2') format('woff2');
31
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
32
+ }
33
+ @font-face {
34
+ font-family: 'Manrope';
35
+ font-style: normal;
36
+ font-weight: 400 800;
37
+ font-display: swap;
38
+ src: url('/fonts/manrope-latin-ext.woff2') format('woff2');
39
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
40
+ }
41
+
42
+ /* JetBrains Mono – weight 400, latin */
43
+ @font-face {
44
+ font-family: 'JetBrains Mono';
45
+ font-style: normal;
46
+ font-weight: 400;
47
+ font-display: swap;
48
+ src: url('/fonts/jetbrains-mono-latin.woff2') format('woff2');
49
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
50
+ }
51
+ @font-face {
52
+ font-family: 'JetBrains Mono';
53
+ font-style: normal;
54
+ font-weight: 400;
55
+ font-display: swap;
56
+ src: url('/fonts/jetbrains-mono-latin-ext.woff2') format('woff2');
57
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
58
+ }
59
+
60
+ /* Material Symbols Outlined – variable weight, use block to avoid showing raw text */
61
+ @font-face {
62
+ font-family: 'Material Symbols Outlined';
63
+ font-style: normal;
64
+ font-weight: 100 700;
65
+ font-display: block;
66
+ src: url('/fonts/material-symbols-outlined.woff2') format('woff2');
67
+ }
68
+
69
+ /* Code highlighting is handled by shiki/react-shiki (inline styles + CSS line numbers) */
70
+
71
+ /* ─── Shiki code viewer ───────────────────────────────────────── */
72
+ .code-viewer-area .line {
73
+ display: inline-block;
74
+ width: 100%;
75
+ padding: 1px 12px;
76
+ }
77
+
78
+ .code-viewer-area .has-line-numbers .line {
79
+ padding-left: 0;
80
+ }
81
+
82
+ .code-viewer-area .line:hover {
83
+ background: rgba(0, 0, 0, 0.03);
84
+ }
85
+
86
+ .code-viewer-area .has-line-numbers {
87
+ --line-numbers-foreground: rgba(135, 115, 109, 0.5);
88
+ --line-numbers-width: 2.5ch;
89
+ --line-numbers-padding-left: 1ch;
90
+ --line-numbers-padding-right: 1.5ch;
91
+ --line-numbers-font-size: 11px;
92
+ }
93
+
94
+ /* ─── Tailwind Theme Override (matches prototype design system) ─── */
95
+ @theme {
96
+ --color-primary: #8F482F;
97
+ --color-primary-container: #AD5F45;
98
+ --color-primary-fixed: #FFDBD0;
99
+ --color-primary-fixed-dim: #FFB59D;
100
+
101
+ --color-on-primary: #FFFFFF;
102
+ --color-on-surface: #1B1C1A;
103
+ --color-on-surface-variant: #54433E;
104
+
105
+ --color-surface: #FAF9F5;
106
+ --color-surface-bright: #FAF9F5;
107
+ --color-surface-dim: #DBDAD6;
108
+ --color-surface-container: #EFEEEA;
109
+ --color-surface-container-low: #F4F4F0;
110
+ --color-surface-container-high: #E9E8E4;
111
+ --color-surface-container-highest: #E3E2DF;
112
+ --color-surface-container-lowest: #FFFFFF;
113
+ --color-surface-variant: #E3E2DF;
114
+
115
+ --color-background: #FAF9F5;
116
+
117
+ --color-outline: #87736D;
118
+ --color-outline-variant: #DAC1BA;
119
+
120
+ --color-secondary: #2D628F;
121
+ --color-secondary-container: #9ACBFE;
122
+ --color-tertiary: #4F6237;
123
+ --color-tertiary-container: #677B4E;
124
+
125
+ --color-error: #BA1A1A;
126
+ --color-error-container: #FFDAD6;
127
+ --color-on-error-container: #410002;
128
+
129
+ --color-inverse-surface: #2F312E;
130
+ --color-inverse-on-surface: #F2F1ED;
131
+ --color-inverse-primary: #FFB59D;
132
+
133
+ --color-success: #16A34A;
134
+ --color-warning: #CA8A04;
135
+
136
+ --font-headline: 'Manrope', sans-serif;
137
+ --font-body: 'Inter', sans-serif;
138
+ --font-label: 'Inter', sans-serif;
139
+ --font-mono: 'JetBrains Mono', monospace;
140
+ }
141
+
142
+ /* ─── Semantic Aliases (used by layout & infrastructure components) ── */
143
+ :root,
144
+ [data-theme="light"] {
145
+ color-scheme: light;
146
+
147
+ /* Layout dimensions */
148
+ --sidebar-width: 280px;
149
+ --titlebar-height: 40px;
150
+ --statusbar-height: 36px;
151
+
152
+ /* Surface aliases */
153
+ --color-surface-sidebar: var(--color-surface-container-low);
154
+ --color-surface-hover: var(--color-surface-container-high);
155
+ --color-surface-selected: var(--color-surface-container);
156
+
157
+ /* Border aliases */
158
+ --color-border: var(--color-outline-variant);
159
+ --color-border-focus: var(--color-primary);
160
+ --color-border-separator: var(--color-outline-variant);
161
+
162
+ /* Text aliases */
163
+ --color-text-primary: var(--color-on-surface);
164
+ --color-text-secondary: var(--color-on-surface-variant);
165
+ --color-text-tertiary: var(--color-outline);
166
+
167
+ /* Info surface (for team status bar, notifications) */
168
+ --color-surface-info: var(--color-surface-container-low);
169
+
170
+ /* Brand & accents */
171
+ --color-brand: var(--color-primary);
172
+ --color-text-accent: var(--color-secondary);
173
+
174
+ /* Shadows */
175
+ --shadow-dropdown: 0 4px 20px rgba(27, 28, 26, 0.04), 0 12px 40px rgba(27, 28, 26, 0.08);
176
+ --shadow-focus-ring: 0 0 0 1px rgba(143, 72, 47, 0.16);
177
+ --shadow-error-ring: 0 0 0 1px rgba(186, 26, 26, 0.18);
178
+ --shadow-button-primary: 0 8px 24px rgba(143, 72, 47, 0.18);
179
+
180
+ /* Button colors */
181
+ --color-btn-primary-fg: var(--color-on-primary);
182
+ --gradient-btn-primary: linear-gradient(135deg, var(--color-primary), var(--color-primary-container));
183
+ --gradient-btn-primary-hover: linear-gradient(135deg, var(--color-primary-container), var(--color-primary));
184
+
185
+ /* User message bubble */
186
+ --color-surface-user-msg: var(--color-surface-container);
187
+
188
+ /* Glass / overlays */
189
+ --color-overlay-scrim: rgba(27, 28, 26, 0.48);
190
+ --color-surface-glass: rgba(255, 255, 255, 0.84);
191
+ --color-surface-glass-border: rgba(218, 193, 186, 0.22);
192
+
193
+ /* Code + diff */
194
+ --color-code-bg: #FDFCF9;
195
+ --color-code-fg: #24201E;
196
+ --color-code-comment: #5C6B7A;
197
+ --color-code-string: #437220;
198
+ --color-code-keyword: #B8533B;
199
+ --color-code-function: #1D5A8C;
200
+ --color-code-number: #1B7A6A;
201
+ --color-code-property: #7A3E20;
202
+ --color-code-type: #7E5520;
203
+ --color-code-parameter: #5C3D2E;
204
+ --color-code-punctuation: #5C504A;
205
+ --color-code-inserted: #1A7F37;
206
+ --color-code-deleted: #CF222E;
207
+
208
+ --color-diff-added-bg: #E8F5E2;
209
+ --color-diff-added-word: #B8E4A8;
210
+ --color-diff-added-gutter: #D4EDCA;
211
+ --color-diff-added-text: #1A7F37;
212
+ --color-diff-removed-bg: #FDECEA;
213
+ --color-diff-removed-word: #F5B8B4;
214
+ --color-diff-removed-gutter: #F9D4D0;
215
+ --color-diff-removed-text: #CF222E;
216
+ --color-diff-highlight-bg: #FFF5D6;
217
+ --color-diff-highlight-gutter: #FFECB3;
218
+ --color-diff-title-bg: #F4F4F0;
219
+ --color-diff-title-color: #87736D;
220
+ --color-diff-title-border: #DAC1BA;
221
+
222
+ /* Terminal */
223
+ --color-terminal-header: #2D2D2D;
224
+ --color-terminal-bg: #1E1E1E;
225
+ --color-terminal-border: #1A1A1A;
226
+ --color-terminal-fg: #D4D4D4;
227
+ --color-terminal-muted: #999999;
228
+ --color-terminal-accent: #28C840;
229
+ --color-terminal-danger: #FF5F57;
230
+ --color-terminal-warning: #FEBC2E;
231
+
232
+ /* Misc */
233
+ --color-window-close-hover: #E81123;
234
+ --color-selection-bg: rgba(255, 219, 208, 0.9);
235
+ --color-selection-fg: #390C00;
236
+
237
+ /* Radii */
238
+ --radius-sm: 4px;
239
+ --radius-md: 8px;
240
+ --radius-lg: 12px;
241
+ --radius-xl: 16px;
242
+ --radius-full: 9999px;
243
+ }
244
+
245
+ [data-theme="dark"] {
246
+ color-scheme: dark;
247
+
248
+ --color-primary: #FFB59F;
249
+ --color-primary-container: #FF6E40;
250
+ --color-primary-fixed: #FFD9CF;
251
+ --color-primary-fixed-dim: #FFB59F;
252
+
253
+ --color-on-primary: #2C120B;
254
+ --color-on-surface: #E5E2E1;
255
+ --color-on-surface-variant: #B7AAA5;
256
+
257
+ --color-surface: #131313;
258
+ --color-surface-bright: #201F1F;
259
+ --color-surface-dim: #0E0E0E;
260
+ --color-surface-container: #201F1F;
261
+ --color-surface-container-low: #1C1B1B;
262
+ --color-surface-container-high: #2A2929;
263
+ --color-surface-container-highest: #353534;
264
+ --color-surface-container-lowest: #0E0E0E;
265
+ --color-surface-variant: #252120;
266
+ --color-background: #0E0E0E;
267
+
268
+ --color-outline: #8D7F7A;
269
+ --color-outline-variant: #5A4138;
270
+
271
+ --color-secondary: #CDBDFF;
272
+ --color-secondary-container: #3A3050;
273
+ --color-tertiary: #00DAF3;
274
+ --color-tertiary-container: #003D44;
275
+
276
+ --color-error: #FFB4AB;
277
+ --color-error-container: #93000A;
278
+ --color-on-error-container: #FFDAD6;
279
+
280
+ --color-inverse-surface: #E5E2E1;
281
+ --color-inverse-on-surface: #1B1C1A;
282
+ --color-inverse-primary: #8F482F;
283
+
284
+ --color-success: #7EDB8B;
285
+ --color-warning: #F7C46C;
286
+
287
+ --color-surface-sidebar: var(--color-surface-container-low);
288
+ --color-surface-hover: var(--color-surface-container-highest);
289
+ --color-surface-selected: var(--color-surface-container);
290
+
291
+ --color-border: rgba(90, 65, 56, 0.18);
292
+ --color-border-focus: rgba(255, 181, 159, 0.55);
293
+ --color-border-separator: rgba(90, 65, 56, 0.12);
294
+
295
+ --color-text-primary: var(--color-on-surface);
296
+ --color-text-secondary: var(--color-on-surface-variant);
297
+ --color-text-tertiary: #8F827D;
298
+
299
+ --color-surface-info: rgba(32, 31, 31, 0.88);
300
+ --color-brand: var(--color-primary);
301
+ --color-text-accent: var(--color-tertiary);
302
+
303
+ --shadow-dropdown: 0 12px 32px rgba(0, 0, 0, 0.4);
304
+ --shadow-focus-ring: 0 0 0 1px rgba(255, 181, 159, 0.32);
305
+ --shadow-error-ring: 0 0 0 1px rgba(255, 180, 171, 0.26);
306
+ --shadow-button-primary: 0 12px 24px rgba(255, 110, 64, 0.18);
307
+
308
+ --gradient-btn-primary: linear-gradient(135deg, var(--color-primary), var(--color-primary-container));
309
+ --gradient-btn-primary-hover: linear-gradient(135deg, var(--color-primary-container), var(--color-primary));
310
+
311
+ --color-surface-user-msg: rgba(32, 31, 31, 0.92);
312
+
313
+ --color-overlay-scrim: rgba(6, 6, 6, 0.56);
314
+ --color-surface-glass: rgba(32, 31, 31, 0.8);
315
+ --color-surface-glass-border: rgba(90, 65, 56, 0.18);
316
+
317
+ --color-code-bg: #0E0E0E;
318
+ --color-code-fg: #E5E2E1;
319
+ --color-code-comment: #8F8683;
320
+ --color-code-string: #88C988;
321
+ --color-code-keyword: #FF8F70;
322
+ --color-code-function: #00DAF3;
323
+ --color-code-number: #74E0F7;
324
+ --color-code-property: #FFC9B8;
325
+ --color-code-type: #CDBDFF;
326
+ --color-code-parameter: #E5E2E1;
327
+ --color-code-punctuation: #9B908C;
328
+ --color-code-inserted: #8EEA9A;
329
+ --color-code-deleted: #FFB59F;
330
+
331
+ --color-diff-added-bg: rgba(126, 219, 139, 0.12);
332
+ --color-diff-added-word: rgba(126, 219, 139, 0.22);
333
+ --color-diff-added-gutter: rgba(126, 219, 139, 0.18);
334
+ --color-diff-added-text: #8EEA9A;
335
+ --color-diff-removed-bg: rgba(255, 110, 64, 0.12);
336
+ --color-diff-removed-word: rgba(255, 110, 64, 0.24);
337
+ --color-diff-removed-gutter: rgba(255, 110, 64, 0.18);
338
+ --color-diff-removed-text: #FFB59F;
339
+ --color-diff-highlight-bg: rgba(205, 189, 255, 0.12);
340
+ --color-diff-highlight-gutter: rgba(205, 189, 255, 0.16);
341
+ --color-diff-title-bg: var(--color-surface-container-low);
342
+ --color-diff-title-color: var(--color-text-tertiary);
343
+ --color-diff-title-border: rgba(90, 65, 56, 0.15);
344
+
345
+ --color-terminal-header: #242323;
346
+ --color-terminal-bg: #121212;
347
+ --color-terminal-border: #1A1919;
348
+ --color-terminal-fg: #D7D2D0;
349
+ --color-terminal-muted: #8F8683;
350
+ --color-terminal-accent: #7EF18A;
351
+ --color-terminal-danger: #FF6D67;
352
+ --color-terminal-warning: #F8C55F;
353
+
354
+ --color-window-close-hover: #C63B44;
355
+ --color-selection-bg: rgba(255, 181, 159, 0.32);
356
+ --color-selection-fg: #FBE7E1;
357
+ }
358
+
359
+ /* ─── Material Symbols ─────────────────────────────────────────── */
360
+ .material-symbols-outlined {
361
+ font-family: 'Material Symbols Outlined';
362
+ font-weight: normal;
363
+ font-style: normal;
364
+ font-size: 24px;
365
+ line-height: 1;
366
+ letter-spacing: normal;
367
+ text-transform: none;
368
+ display: inline-block;
369
+ white-space: nowrap;
370
+ word-wrap: normal;
371
+ direction: ltr;
372
+ -webkit-font-feature-settings: 'liga';
373
+ -webkit-font-smoothing: antialiased;
374
+ font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
375
+ vertical-align: middle;
376
+ }
377
+
378
+ /* ─── Base styles ──────────────────────────────────────────────── */
379
+ * {
380
+ box-sizing: border-box;
381
+ }
382
+
383
+ html, body, #root {
384
+ height: 100%;
385
+ margin: 0;
386
+ padding: 0;
387
+ font-family: var(--font-body);
388
+ color: var(--color-on-surface);
389
+ background-color: var(--color-background);
390
+ -webkit-font-smoothing: antialiased;
391
+ -moz-osx-font-smoothing: grayscale;
392
+ }
393
+
394
+ ::selection {
395
+ background: var(--color-selection-bg);
396
+ color: var(--color-selection-fg);
397
+ }
398
+
399
+ /* Tauri drag region */
400
+ [data-tauri-drag-region] {
401
+ -webkit-app-region: drag;
402
+ }
403
+ button, input, textarea, select, a, [role="button"] {
404
+ -webkit-app-region: no-drag;
405
+ }
406
+ [draggable="true"] {
407
+ -webkit-app-region: no-drag;
408
+ }
409
+
410
+ /* Custom shadow from prototype */
411
+ .custom-shadow {
412
+ box-shadow: var(--shadow-dropdown);
413
+ }
414
+
415
+ .glass-panel {
416
+ background: var(--color-surface-glass);
417
+ border: 1px solid var(--color-surface-glass-border);
418
+ backdrop-filter: blur(20px);
419
+ -webkit-backdrop-filter: blur(20px);
420
+ box-shadow: var(--shadow-dropdown);
421
+ }
422
+
423
+ .glass-panel:focus-within {
424
+ box-shadow: var(--shadow-focus-ring), var(--shadow-dropdown);
425
+ }
426
+
427
+ .markdown-prose .md-table-wrap table {
428
+ border-collapse: separate;
429
+ border-spacing: 0;
430
+ }
431
+
432
+ .markdown-prose .md-table-wrap tbody tr:last-child td {
433
+ border-bottom: 0;
434
+ }
435
+
436
+ .markdown-prose a code {
437
+ color: inherit;
438
+ }
439
+
440
+ /* Scrollbar */
441
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
442
+ ::-webkit-scrollbar-track { background: transparent; }
443
+ ::-webkit-scrollbar-thumb { background: var(--color-outline); border-radius: 9999px; opacity: 0.3; }
444
+ ::-webkit-scrollbar-thumb:hover { opacity: 0.6; }
445
+
446
+ /* Animations */
447
+ @keyframes shimmer {
448
+ 0%, 100% { opacity: 0.4; }
449
+ 50% { opacity: 1; }
450
+ }
451
+ @keyframes spin {
452
+ to { transform: rotate(360deg); }
453
+ }
454
+ @keyframes pulse-dot {
455
+ 0%, 100% { opacity: 1; }
456
+ 50% { opacity: 0.3; }
457
+ }
458
+ .animate-shimmer { animation: shimmer 1.5s ease-in-out infinite; }
459
+ .animate-spin { animation: spin 1s linear infinite; }
460
+ .animate-pulse-dot { animation: pulse-dot 1.5s ease-in-out infinite; }
461
+
462
+ /* Progress bar */
463
+ @keyframes progress-fill {
464
+ from { width: 0%; }
465
+ }
@@ -0,0 +1,33 @@
1
+ export type PairedUser = {
2
+ userId: string | number
3
+ displayName: string
4
+ pairedAt: number
5
+ }
6
+
7
+ export type PairingState = {
8
+ code: string | null
9
+ expiresAt: number | null
10
+ createdAt: number | null
11
+ }
12
+
13
+ export type AdapterFileConfig = {
14
+ serverUrl?: string
15
+ defaultProjectDir?: string
16
+ pairing?: PairingState
17
+ telegram?: {
18
+ botToken?: string
19
+ allowedUsers?: number[]
20
+ pairedUsers?: PairedUser[]
21
+ defaultWorkDir?: string
22
+ }
23
+ feishu?: {
24
+ appId?: string
25
+ appSecret?: string
26
+ encryptKey?: string
27
+ verificationToken?: string
28
+ allowedUsers?: string[]
29
+ pairedUsers?: PairedUser[]
30
+ defaultWorkDir?: string
31
+ streamingCard?: boolean
32
+ }
33
+ }