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
Binary file
@@ -0,0 +1 @@
1
+ <svg role="img" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M17.813 4.653h.854c1.51.054 2.769.578 3.773 1.574 1.004.995 1.524 2.249 1.56 3.76v7.36c-.036 1.51-.556 2.769-1.56 3.773s-2.262 1.524-3.773 1.56H5.333c-1.51-.036-2.769-.556-3.773-1.56S.036 18.858 0 17.347v-7.36c.036-1.511.556-2.765 1.56-3.76 1.004-.996 2.262-1.52 3.773-1.574h.774l-1.174-1.12a1.234 1.234 0 0 1-.373-.906c0-.356.124-.658.373-.907l.027-.027c.267-.249.573-.373.92-.373.347 0 .653.124.92.373L9.653 4.44c.071.071.134.142.187.213h4.267a.836.836 0 0 1 .16-.213l2.853-2.747c.267-.249.573-.373.92-.373.347 0 .662.151.929.4.267.249.391.551.391.907 0 .355-.124.657-.373.906zM5.333 7.24c-.746.018-1.373.276-1.88.773-.506.498-.769 1.13-.786 1.894v7.52c.017.764.28 1.395.786 1.893.507.498 1.134.756 1.88.773h13.334c.746-.017 1.373-.275 1.88-.773.506-.498.769-1.129.786-1.893v-7.52c-.017-.765-.28-1.396-.786-1.894-.507-.497-1.134-.755-1.88-.773zM8 11.107c.373 0 .684.124.933.373.25.249.383.569.4.96v1.173c-.017.391-.15.711-.4.96-.249.25-.56.374-.933.374s-.684-.125-.933-.374c-.25-.249-.383-.569-.4-.96V12.44c0-.373.129-.689.386-.947.258-.257.574-.386.947-.386zm8 0c.373 0 .684.124.933.373.25.249.383.569.4.96v1.173c-.017.391-.15.711-.4.96-.249.25-.56.374-.933.374s-.684-.125-.933-.374c-.25-.249-.383-.569-.4-.96V12.44c.017-.391.15-.711.4-.96.249-.249.56-.373.933-.373Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg role="img" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><title>Douyin</title><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z"/></svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
2
+ <path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"/>
3
+ </svg>
@@ -0,0 +1 @@
1
+ <svg role="img" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M22.405 9.879c.002.016.01.02.07.019h.725a.797.797 0 0 0 .78-.972.794.794 0 0 0-.884-.618.795.795 0 0 0-.692.794c0 .101-.002.666.001.777zm-11.509 4.808c-.203.001-1.353.004-1.685.003a2.528 2.528 0 0 1-.766-.126.025.025 0 0 0-.03.014L7.7 16.127a.025.025 0 0 0 .01.032c.111.06.336.124.495.124.66.01 1.32.002 1.981 0 .01 0 .02-.006.023-.015l.712-1.545a.025.025 0 0 0-.024-.036zM.477 9.91c-.071 0-.076.002-.076.01a.834.834 0 0 0-.01.08c-.027.397-.038.495-.234 3.06-.012.24-.034.389-.135.607-.026.057-.033.042.003.112.046.092.681 1.523.787 1.74.008.015.011.02.017.02.008 0 .033-.026.047-.044.147-.187.268-.391.371-.606.306-.635.44-1.325.486-1.706.014-.11.021-.22.03-.33l.204-2.616.022-.293c.003-.029 0-.033-.03-.034zm7.203 3.757a1.427 1.427 0 0 1-.135-.607c-.004-.084-.031-.39-.235-3.06a.443.443 0 0 0-.01-.082c-.004-.011-.052-.008-.076-.008h-1.48c-.03.001-.034.005-.03.034l.021.293c.076.982.153 1.964.233 2.946.05.4.186 1.085.487 1.706.103.215.223.419.37.606.015.018.037.051.048.049.02-.003.742-1.642.804-1.765.036-.07.03-.055.003-.112zm3.861-.913h-.872a.126.126 0 0 1-.116-.178l1.178-2.625a.025.025 0 0 0-.023-.035l-1.318-.003a.148.148 0 0 1-.135-.21l.876-1.954a.025.025 0 0 0-.023-.035h-1.56c-.01 0-.02.006-.024.015l-.926 2.068c-.085.169-.314.634-.399.938a.534.534 0 0 0-.02.191.46.46 0 0 0 .23.378.981.981 0 0 0 .46.119h.59c.041 0-.688 1.482-.834 1.972a.53.53 0 0 0-.023.172.465.465 0 0 0 .23.398c.15.092.342.12.475.12l1.66-.001c.01 0 .02-.006.023-.015l.575-1.28a.025.025 0 0 0-.024-.035zm-6.93-4.937H3.1a.032.032 0 0 0-.034.033c0 1.048-.01 2.795-.01 6.829 0 .288-.269.262-.28.262h-.74c-.04.001-.044.004-.04.047.001.037.465 1.064.555 1.263.01.02.03.033.051.033.157.003.767.009.938-.014.153-.02.3-.06.438-.132.3-.156.49-.419.595-.765.052-.172.075-.353.075-.533.002-2.33 0-4.66-.007-6.991a.032.032 0 0 0-.032-.032zm11.784 6.896c0-.014-.01-.021-.024-.022h-1.465c-.048-.001-.049-.002-.05-.049v-4.66c0-.072-.005-.07.07-.07h.863c.08 0 .075.004.075-.074V8.393c0-.082.006-.076-.08-.076h-3.5c-.064 0-.075-.006-.075.073v1.445c0 .083-.006.077.08.077h.854c.075 0 .07-.004.07.07v4.624c0 .095.008.084-.085.084-.37 0-1.11-.002-1.304 0-.048.001-.06.03-.06.03l-.697 1.519s-.014.025-.008.036c.006.01.013.008.058.008 1.748.003 3.495.002 5.243.002.03-.001.034-.006.035-.033v-1.539zm4.177-3.43c0 .013-.007.023-.02.024-.346.006-.692.004-1.037.004-.014-.002-.022-.01-.022-.024-.005-.434-.007-.869-.01-1.303 0-.072-.006-.071.07-.07l.733-.003c.041 0 .081.002.12.015.093.025.16.107.165.204.006.431.002 1.153.001 1.153zm2.67.244a1.953 1.953 0 0 0-.883-.222h-.18c-.04-.001-.04-.003-.042-.04V10.21c0-.132-.007-.263-.025-.394a1.823 1.823 0 0 0-.153-.53 1.533 1.533 0 0 0-.677-.71 2.167 2.167 0 0 0-1-.258c-.153-.003-.567 0-.72 0-.07 0-.068.004-.068-.065V7.76c0-.031-.01-.041-.046-.039H17.93s-.016 0-.023.007c-.006.006-.008.012-.008.023v.546c-.008.036-.057.015-.082.022h-.95c-.022.002-.028.008-.03.032v1.481c0 .09-.004.082.082.082h.913c.082 0 .072.128.072.128V11.19s.003.117-.06.117h-1.482c-.068 0-.06.082-.06.082v1.445s-.01.068.064.068h1.457c.082 0 .076-.006.076.079v3.225c0 .088-.007.081.082.081h1.43c.09 0 .082.007.082-.08v-3.27c0-.029.006-.035.033-.035l2.323-.003c.098 0 .191.02.28.061a.46.46 0 0 1 .274.407c.008.395.003.79.003 1.185 0 .259-.107.367-.33.367h-1.218c-.023.002-.029.008-.028.033.184.437.374.871.57 1.303a.045.045 0 0 0 .04.026c.17.005.34.002.51.003.15-.002.517.004.666-.01a2.03 2.03 0 0 0 .408-.075c.59-.18.975-.698.976-1.313v-1.981c0-.128-.01-.254-.034-.38 0 .078-.029-.641-.724-.998z"/></svg>
@@ -0,0 +1,270 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ DESKTOP_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
7
+ REPO_ROOT="$(cd "${DESKTOP_DIR}/.." && pwd)"
8
+
9
+ TARGET_TRIPLE="aarch64-apple-darwin"
10
+ TAURI_TARGET_DIR="${DESKTOP_DIR}/src-tauri/target"
11
+ CANONICAL_OUTPUT_DIR="${DESKTOP_DIR}/build-artifacts/macos-arm64"
12
+ APP_BUNDLE_NAME="Claude Code Haha.app"
13
+ APP_BUNDLE_ID="com.claude-code-haha.desktop"
14
+
15
+ usage() {
16
+ cat <<'EOF'
17
+ Build Claude Code Haha desktop for macOS Apple Silicon and output a DMG.
18
+
19
+ Usage:
20
+ ./desktop/scripts/build-macos-arm64.sh [extra tauri build args...]
21
+
22
+ Environment:
23
+ SKIP_INSTALL=1 Skip `bun install` in the repo root and desktop app.
24
+ SIGN_BUILD=1 Remove the default `--no-sign` flag and allow signed builds.
25
+ OPEN_OUTPUT=1 Open the canonical artifact output directory in Finder after a successful build.
26
+
27
+ Examples:
28
+ ./desktop/scripts/build-macos-arm64.sh
29
+ SKIP_INSTALL=1 ./desktop/scripts/build-macos-arm64.sh
30
+ SIGN_BUILD=1 ./desktop/scripts/build-macos-arm64.sh --skip-stapling
31
+ EOF
32
+ }
33
+
34
+ if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
35
+ usage
36
+ exit 0
37
+ fi
38
+
39
+ if [[ "$(uname -s)" != "Darwin" ]]; then
40
+ echo "[build-macos-arm64] This script must run on macOS." >&2
41
+ exit 1
42
+ fi
43
+
44
+ if [[ "$(uname -m)" != "arm64" ]]; then
45
+ echo "[build-macos-arm64] This script is intended for Apple Silicon hosts (arm64)." >&2
46
+ exit 1
47
+ fi
48
+
49
+ for command in bun cargo rustc codesign hdiutil; do
50
+ if ! command -v "${command}" >/dev/null 2>&1; then
51
+ echo "[build-macos-arm64] Missing required command: ${command}" >&2
52
+ exit 1
53
+ fi
54
+ done
55
+
56
+ if [[ "${SKIP_INSTALL:-0}" != "1" ]]; then
57
+ echo "[build-macos-arm64] Installing root dependencies..."
58
+ (cd "${REPO_ROOT}" && bun install)
59
+
60
+ echo "[build-macos-arm64] Installing desktop dependencies..."
61
+ (cd "${DESKTOP_DIR}" && bun install)
62
+ fi
63
+
64
+ # ── 清理 + 显式预热前端 / sidecar ────────────────────────────
65
+ # 之前遇到过"改了 src/ 代码,build 的 .app 里 sidecar 还是旧的"的诡异
66
+ # case —— 根因是 Bun.build / Tauri bundler 某一层的缓存把旧 sidecar
67
+ # binary 复用进了新 .app(.app 被删干净了也救不回来,因为 binary 源在
68
+ # desktop/src-tauri/binaries/)。
69
+ #
70
+ # 这里做三件事强制 fresh build:
71
+ # 1) 硬删 sidecar 源 binary + Tauri bundle 目录 + 前端 dist
72
+ # 2) 显式跑 bun run build + bun run build:sidecars
73
+ # 3) tauri build 用 --config 覆盖 beforeBuildCommand 为 true(no-op),
74
+ # 避免 sidecar 被重复编译浪费 ~10s
75
+ # 任一步失败,整个脚本立即退出(set -e)。
76
+ echo "[build-macos-arm64] Cleaning stale sidecar binaries and bundle output..."
77
+ rm -rf "${DESKTOP_DIR}/src-tauri/binaries/claude-sidecar-"*
78
+ rm -rf "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/bundle"
79
+ rm -rf "${DESKTOP_DIR}/src-tauri/target/release/bundle"
80
+ rm -rf "${DESKTOP_DIR}/dist"
81
+
82
+ echo "[build-macos-arm64] Rebuilding frontend (tsc + vite)..."
83
+ (cd "${DESKTOP_DIR}" && bun run build)
84
+
85
+ echo "[build-macos-arm64] Rebuilding sidecar for ${TARGET_TRIPLE}..."
86
+ (cd "${DESKTOP_DIR}" && TAURI_ENV_TARGET_TRIPLE="${TARGET_TRIPLE}" bun run build:sidecars)
87
+
88
+ TAURI_ARGS=(
89
+ bunx
90
+ tauri
91
+ build
92
+ --target
93
+ "${TARGET_TRIPLE}"
94
+ --bundles
95
+ app,dmg
96
+ --ci
97
+ --config
98
+ '{"build":{"beforeBuildCommand":"true"}}'
99
+ )
100
+
101
+ if [[ "${SIGN_BUILD:-0}" != "1" ]]; then
102
+ TAURI_ARGS+=(--no-sign)
103
+ fi
104
+
105
+ if [[ "$#" -gt 0 ]]; then
106
+ TAURI_ARGS+=("$@")
107
+ fi
108
+
109
+ echo "[build-macos-arm64] Building DMG for ${TARGET_TRIPLE}..."
110
+ (
111
+ cd "${DESKTOP_DIR}"
112
+ export TAURI_ENV_TARGET_TRIPLE="${TARGET_TRIPLE}"
113
+ "${TAURI_ARGS[@]}"
114
+ )
115
+
116
+ TARGETED_DMG_DIR="${TAURI_TARGET_DIR}/${TARGET_TRIPLE}/release/bundle/dmg"
117
+ FALLBACK_DMG_DIR="${TAURI_TARGET_DIR}/release/bundle/dmg"
118
+ TARGETED_APP_DIR="${TAURI_TARGET_DIR}/${TARGET_TRIPLE}/release/bundle/macos"
119
+ FALLBACK_APP_DIR="${TAURI_TARGET_DIR}/release/bundle/macos"
120
+ LEGACY_BUNDLE_ROOT="${TAURI_TARGET_DIR}/release/bundle"
121
+
122
+ mkdir -p "${CANONICAL_OUTPUT_DIR}"
123
+ find "${CANONICAL_OUTPUT_DIR}" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
124
+
125
+ find_latest_file() {
126
+ local search_dir="$1"
127
+ local pattern="$2"
128
+ if [[ -d "${search_dir}" ]]; then
129
+ find "${search_dir}" -maxdepth 1 -type f -name "${pattern}" | sort | tail -n 1
130
+ fi
131
+ }
132
+
133
+ find_latest_dir() {
134
+ local search_dir="$1"
135
+ local pattern="$2"
136
+ if [[ -d "${search_dir}" ]]; then
137
+ find "${search_dir}" -maxdepth 1 -type d -name "${pattern}" | sort | tail -n 1
138
+ fi
139
+ }
140
+
141
+ LATEST_DMG="$(find_latest_file "${TARGETED_DMG_DIR}" '*.dmg')"
142
+ if [[ -z "${LATEST_DMG}" ]]; then
143
+ LATEST_DMG="$(find_latest_file "${FALLBACK_DMG_DIR}" '*.dmg')"
144
+ fi
145
+
146
+ LATEST_APP="$(find_latest_dir "${TARGETED_APP_DIR}" '*.app')"
147
+ if [[ -z "${LATEST_APP}" ]]; then
148
+ LATEST_APP="$(find_latest_dir "${FALLBACK_APP_DIR}" '*.app')"
149
+ fi
150
+
151
+ build_canonical_dmg() {
152
+ local app_bundle="$1"
153
+ local dmg_output="$2"
154
+ local staging_dir
155
+ local rw_dmg
156
+
157
+ staging_dir="$(mktemp -d "${TMPDIR:-/tmp}/cc-haha-dmg.XXXXXX")"
158
+ rw_dmg="$(mktemp "${TMPDIR:-/tmp}/cc-haha-rw.XXXXXX").dmg"
159
+
160
+ cp -R "${app_bundle}" "${staging_dir}/"
161
+ ln -s /Applications "${staging_dir}/Applications"
162
+
163
+ # Create a read-write DMG first so we can customize the Finder layout
164
+ hdiutil create \
165
+ -volname "Claude Code Haha" \
166
+ -srcfolder "${staging_dir}" \
167
+ -ov \
168
+ -format UDRW \
169
+ "${rw_dmg}" >/dev/null
170
+
171
+ rm -rf "${staging_dir}"
172
+
173
+ # Mount the read-write DMG and apply Finder layout via AppleScript
174
+ local dev_name mount_dir
175
+ dev_name=$(hdiutil attach -readwrite -noverify -noautoopen -nobrowse "${rw_dmg}" \
176
+ | grep -E '^/dev/' | head -1 | awk '{print $1}')
177
+ mount_dir=$(hdiutil info | grep -E "${dev_name}" | tail -1 | awk '{$1=$2=""; print}' | xargs)
178
+
179
+ # Finder AppleScript 在新版 macOS (Sequoia+) 上某些属性
180
+ # (toolbar/statusbar visible、某些 container window 属性) 不再支持,
181
+ # 会返回 -10006 错误。美化失败不是 blocker —— 即便 layout 没设上,
182
+ # DMG 本身还是可用的,只是用户打开时看到的是 Finder 默认排布。
183
+ # 所以这里允许 osascript 非零退出,只 warn,不让 set -e 炸掉整个脚本。
184
+ if ! osascript <<APPLESCRIPT
185
+ tell application "Finder"
186
+ tell disk "Claude Code Haha"
187
+ open
188
+ set current view of container window to icon view
189
+ set toolbar visible of container window to false
190
+ set statusbar visible of container window to false
191
+ set the bounds of container window to {100, 100, 760, 500}
192
+ set viewOptions to the icon view options of container window
193
+ set arrangement of viewOptions to not arranged
194
+ set icon size of viewOptions to 128
195
+ set position of item "${APP_BUNDLE_NAME}" of container window to {180, 170}
196
+ set position of item "Applications" of container window to {480, 170}
197
+ close
198
+ open
199
+ update without registering applications
200
+ delay 2
201
+ close
202
+ end tell
203
+ end tell
204
+ APPLESCRIPT
205
+ then
206
+ echo "[build-macos-arm64] WARN: Finder layout AppleScript failed (likely macOS version incompatible); DMG will use default Finder layout" >&2
207
+ fi
208
+
209
+ sync
210
+ # osascript 可能已经让 Finder 打开了 volume 窗口,正常 detach 可能因为
211
+ # "Resource busy" 失败。失败时用 -force 二次尝试。
212
+ hdiutil detach "${dev_name}" -quiet 2>/dev/null \
213
+ || hdiutil detach "${dev_name}" -force -quiet
214
+
215
+ # Convert to compressed read-only DMG
216
+ hdiutil convert "${rw_dmg}" -format UDZO -o "${dmg_output}" -ov >/dev/null
217
+ rm -f "${rw_dmg}"
218
+ }
219
+
220
+ if [[ -n "${LATEST_DMG}" ]]; then
221
+ cp -f "${LATEST_DMG}" "${CANONICAL_OUTPUT_DIR}/"
222
+ fi
223
+
224
+ if [[ -n "${LATEST_APP}" ]]; then
225
+ # 注意: 不要再对 .app 重签名。曾经脚本在这里跑过
226
+ # `codesign --force --deep --sign - --identifier <bundle-id>` 来统一
227
+ # sidecar 和外层的 signing identifier,但这会改变 sidecar binary 的
228
+ # code signature hash —— macOS Keychain ACL 按 hash 识别 caller,
229
+ # 重签完再访问时会被 ACL 当作"陌生 binary"静默拒绝,导致 CLI 读不到
230
+ # OAuth token,最终请求打到 Anthropic 返回 403 "Request not allowed"。
231
+ # Tauri 的 --no-sign 其实已经做了 ad-hoc 签名,直接用即可。
232
+ cp -R "${LATEST_APP}" "${CANONICAL_OUTPUT_DIR}/"
233
+ rm -f "${CANONICAL_OUTPUT_DIR}/"*.dmg
234
+ build_canonical_dmg \
235
+ "${CANONICAL_OUTPUT_DIR}/${APP_BUNDLE_NAME}" \
236
+ "${CANONICAL_OUTPUT_DIR}/$(basename "${LATEST_DMG:-Claude Code Haha_0.1.0_aarch64.dmg}")"
237
+ fi
238
+
239
+ cat > "${CANONICAL_OUTPUT_DIR}/BUILD_INFO.txt" <<EOF
240
+ Target triple: ${TARGET_TRIPLE}
241
+ Canonical output: ${CANONICAL_OUTPUT_DIR}
242
+ Source DMG: ${LATEST_DMG:-not found}
243
+ Source app: ${LATEST_APP:-not found}
244
+ Built at: $(date '+%Y-%m-%d %H:%M:%S %z')
245
+ EOF
246
+
247
+ if [[ -d "${LEGACY_BUNDLE_ROOT}" ]]; then
248
+ rm -rf "${LEGACY_BUNDLE_ROOT}"
249
+ fi
250
+
251
+ echo
252
+ echo "[build-macos-arm64] Build finished."
253
+ if [[ -n "${LATEST_DMG}" ]]; then
254
+ echo "[build-macos-arm64] DMG source: ${LATEST_DMG}"
255
+ else
256
+ echo "[build-macos-arm64] No DMG found in ${TARGETED_DMG_DIR} or ${FALLBACK_DMG_DIR}" >&2
257
+ fi
258
+
259
+ if [[ -n "${LATEST_APP}" ]]; then
260
+ echo "[build-macos-arm64] App source: ${LATEST_APP}"
261
+ else
262
+ echo "[build-macos-arm64] No .app found in ${TARGETED_APP_DIR} or ${FALLBACK_APP_DIR}" >&2
263
+ fi
264
+
265
+ echo "[build-macos-arm64] Canonical output: ${CANONICAL_OUTPUT_DIR}"
266
+ echo "[build-macos-arm64] Removed legacy bundle dir: ${LEGACY_BUNDLE_ROOT}"
267
+
268
+ if [[ "${OPEN_OUTPUT:-0}" == "1" ]]; then
269
+ open "${CANONICAL_OUTPUT_DIR}"
270
+ fi
@@ -0,0 +1,183 @@
1
+ import { mkdir } from 'node:fs/promises'
2
+ import path from 'node:path'
3
+
4
+ const desktopRoot = path.resolve(import.meta.dir, '..')
5
+ const repoRoot = path.resolve(desktopRoot, '..')
6
+ const binariesDir = path.join(desktopRoot, 'src-tauri', 'binaries')
7
+
8
+ const targetTriple =
9
+ process.env.TAURI_ENV_TARGET_TRIPLE ||
10
+ process.env.CARGO_BUILD_TARGET ||
11
+ (await detectHostTriple())
12
+
13
+ const bunTarget = mapTargetTripleToBun(targetTriple)
14
+
15
+ // 编译前先扫一遍 src/ 把所有缺失的 ant-internal 模块在磁盘上 stub 出来。
16
+ // 见 desktop/scripts/scan-missing-imports.ts。
17
+ console.log('[build-sidecars] scanning for missing imports...')
18
+ const scanProc = Bun.spawn(
19
+ ['bun', 'run', path.join(desktopRoot, 'scripts/scan-missing-imports.ts')],
20
+ { cwd: repoRoot, stdout: 'inherit', stderr: 'inherit' },
21
+ )
22
+ const scanExit = await scanProc.exited
23
+ if (scanExit !== 0) {
24
+ throw new Error(`[build-sidecars] scan-missing-imports failed (exit ${scanExit})`)
25
+ }
26
+
27
+ await mkdir(binariesDir, { recursive: true })
28
+
29
+ // 单一合并 sidecar:server / cli 共享一份 bun runtime + 共享依赖代码。
30
+ // 调用方(Tauri lib.rs / conversationService)通过第一个 positional 参数
31
+ // 选择 'server' 或 'cli' 模式,详见 desktop/sidecars/claude-sidecar.ts。
32
+ await compileExecutable({
33
+ entrypoint: path.join(desktopRoot, 'sidecars/claude-sidecar.ts'),
34
+ outfileBase: path.join(binariesDir, `claude-sidecar-${targetTriple}`),
35
+ productName: 'Claude Code Sidecar',
36
+ bunTarget,
37
+ })
38
+
39
+ console.log(`[build-sidecars] Built desktop sidecar for ${targetTriple} (${bunTarget})`)
40
+
41
+ async function detectHostTriple() {
42
+ const proc = Bun.spawn(['rustc', '-vV'], {
43
+ cwd: repoRoot,
44
+ stdout: 'pipe',
45
+ stderr: 'pipe',
46
+ })
47
+
48
+ const stdout = await new Response(proc.stdout).text()
49
+ const stderr = await new Response(proc.stderr).text()
50
+ const exitCode = await proc.exited
51
+
52
+ if (exitCode !== 0) {
53
+ throw new Error(`[build-sidecars] rustc -vV failed: ${stderr || stdout}`)
54
+ }
55
+
56
+ const hostLine = stdout
57
+ .split('\n')
58
+ .map((line) => line.trim())
59
+ .find((line) => line.startsWith('host: '))
60
+
61
+ if (!hostLine) {
62
+ throw new Error('[build-sidecars] Could not detect Rust host triple')
63
+ }
64
+
65
+ return hostLine.replace('host: ', '')
66
+ }
67
+
68
+ function mapTargetTripleToBun(triple: string) {
69
+ switch (triple) {
70
+ case 'aarch64-apple-darwin':
71
+ return 'bun-darwin-arm64'
72
+ case 'x86_64-apple-darwin':
73
+ return 'bun-darwin-x64'
74
+ case 'x86_64-pc-windows-msvc':
75
+ return 'bun-windows-x64'
76
+ case 'aarch64-pc-windows-msvc':
77
+ return 'bun-windows-arm64'
78
+ case 'x86_64-unknown-linux-gnu':
79
+ return 'bun-linux-x64-baseline'
80
+ case 'aarch64-unknown-linux-gnu':
81
+ return 'bun-linux-arm64'
82
+ case 'x86_64-unknown-linux-musl':
83
+ return 'bun-linux-x64-musl'
84
+ case 'aarch64-unknown-linux-musl':
85
+ return 'bun-linux-arm64-musl'
86
+ default:
87
+ throw new Error(`[build-sidecars] Unsupported target triple: ${triple}`)
88
+ }
89
+ }
90
+
91
+ async function compileExecutable({
92
+ entrypoint,
93
+ outfileBase,
94
+ productName,
95
+ bunTarget,
96
+ }: {
97
+ entrypoint: string
98
+ outfileBase: string
99
+ productName: string
100
+ bunTarget: string
101
+ }) {
102
+ const result = await Bun.build({
103
+ entrypoints: [entrypoint],
104
+ // minify whitespace + identifiers + dead-code 大概能省 5-15% 的二进制大小,
105
+ // 代价是 stack trace 里的函数名变成短名 —— 终端用户场景可接受。
106
+ minify: { whitespace: true, identifiers: true, syntax: true },
107
+ sourcemap: 'none',
108
+ target: 'bun',
109
+ // 可选 npm 包:开 telemetry / 用 sharp 图像 / 用 Bedrock/Vertex 等
110
+ // 替代 provider 时才需要,全部不在顶层 package.json 里。标 external
111
+ // 让 bun build 跳过解析;运行时 import 在没装时自然失败,由 try/catch
112
+ // 或 feature() gate 兜底。
113
+ external: [
114
+ // OpenTelemetry exporters(开 OTEL_* env 时才加载)
115
+ '@opentelemetry/exporter-trace-otlp-grpc',
116
+ '@opentelemetry/exporter-trace-otlp-http',
117
+ '@opentelemetry/exporter-trace-otlp-proto',
118
+ '@opentelemetry/exporter-logs-otlp-grpc',
119
+ '@opentelemetry/exporter-logs-otlp-http',
120
+ '@opentelemetry/exporter-logs-otlp-proto',
121
+ '@opentelemetry/exporter-metrics-otlp-grpc',
122
+ '@opentelemetry/exporter-metrics-otlp-http',
123
+ '@opentelemetry/exporter-metrics-otlp-proto',
124
+ '@opentelemetry/exporter-prometheus',
125
+ // 替代 LLM provider —— 默认不用,用户自装
126
+ '@aws-sdk/client-bedrock',
127
+ '@aws-sdk/client-sts',
128
+ '@anthropic-ai/bedrock-sdk',
129
+ '@anthropic-ai/foundry-sdk',
130
+ '@anthropic-ai/vertex-sdk',
131
+ '@azure/identity',
132
+ // ant-internal / 可选工具
133
+ '@anthropic-ai/mcpb',
134
+ 'fflate',
135
+ 'turndown',
136
+ 'sharp',
137
+ 'react-devtools-core',
138
+ ],
139
+ compile: {
140
+ target: bunTarget,
141
+ outfile: outfileBase,
142
+ autoloadTsconfig: true,
143
+ autoloadPackageJson: true,
144
+ windows: {
145
+ title: productName,
146
+ publisher: 'Claude Code',
147
+ description: productName,
148
+ hideConsole: true,
149
+ },
150
+ },
151
+ })
152
+
153
+ if (!result.success) {
154
+ const logs = result.logs.map((log) => log.message).join('\n')
155
+ throw new Error(`[build-sidecars] Failed to compile ${productName}:\n${logs}`)
156
+ }
157
+
158
+ const outputPath = result.outputs[0]?.path ?? outfileBase
159
+ console.log(`[build-sidecars] ${productName} -> ${outputPath}`)
160
+
161
+ // macOS Apple System Policy (ASP) requires valid code signatures on all
162
+ // executables. Bun-compiled binaries ship with an invalid/empty signature
163
+ // that causes "load code signature error 4" and SIGKILL at launch.
164
+ // Fix: strip the broken signature, then ad-hoc sign.
165
+ if (process.platform === 'darwin') {
166
+ console.log(`[build-sidecars] ad-hoc signing ${outputPath} for macOS ...`)
167
+ const strip = Bun.spawn(['codesign', '--remove-signature', outputPath], {
168
+ stdout: 'inherit',
169
+ stderr: 'inherit',
170
+ })
171
+ await strip.exited
172
+
173
+ const sign = Bun.spawn(
174
+ ['codesign', '--sign', '-', '--force', '--timestamp=none', outputPath],
175
+ { stdout: 'inherit', stderr: 'inherit' },
176
+ )
177
+ const signExit = await sign.exited
178
+ if (signExit !== 0) {
179
+ throw new Error(`[build-sidecars] ad-hoc codesign failed for ${outputPath} (exit ${signExit})`)
180
+ }
181
+ console.log(`[build-sidecars] ad-hoc signed ${outputPath}`)
182
+ }
183
+ }