chenbhao commited on
Commit
101eacf
·
1 Parent(s): df64d6e

chore: h5 fix

Browse files
README.md CHANGED
@@ -126,6 +126,8 @@ firefox http://localhost:8080
126
  ```
127
 
128
  ```bash
 
 
129
  cd desktop && bun run tauri dev
130
  # ai_friend api in 8889 so local build Omni model or use cloud service on 8889
131
  ```
 
126
  ```
127
 
128
  ```bash
129
+ # cd desktop && rm -rf node_modules/.vite && bun run dev
130
+ # cd desktop && bun run vite build
131
  cd desktop && bun run tauri dev
132
  # ai_friend api in 8889 so local build Omni model or use cloud service on 8889
133
  ```
desktop/index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Claude Code Companion</title>
7
  <!-- Fonts are self-hosted in /fonts/ and declared via @font-face in globals.css -->
8
  <style>
9
  /* Prevent a warm flash before the theme is hydrated. */
 
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Versper AI Claw</title>
7
  <!-- Fonts are self-hosted in /fonts/ and declared via @font-face in globals.css -->
8
  <style>
9
  /* Prevent a warm flash before the theme is hydrated. */
desktop/scripts/build-macos-arm64.sh CHANGED
@@ -9,12 +9,12 @@ REPO_ROOT="$(cd "${DESKTOP_DIR}/.." && pwd)"
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...]
@@ -191,7 +191,7 @@ build_canonical_dmg() {
191
 
192
  # Create a read-write DMG first so we can customize the Finder layout
193
  hdiutil create \
194
- -volname "Claude Code Haha" \
195
  -srcfolder "${staging_dir}" \
196
  -ov \
197
  -format UDRW \
@@ -212,7 +212,7 @@ build_canonical_dmg() {
212
  # 所以这里允许 osascript 非零退出,只 warn,不让 set -e 炸掉整个脚本。
213
  if ! osascript <<APPLESCRIPT
214
  tell application "Finder"
215
- tell disk "Claude Code Haha"
216
  open
217
  set current view of container window to icon view
218
  set toolbar visible of container window to false
@@ -283,7 +283,7 @@ sign_canonical_app_bundle() {
283
 
284
  if [[ -n "${LATEST_APP}" ]]; then
285
  # Normalize the Tauri-produced app in place before copying it anywhere.
286
- # Without this, opening target/.../bundle/macos/Claude Code Haha.app directly
287
  # uses the executable's ad-hoc signing identifier instead of the app bundle id,
288
  # which makes macOS notification authorization behave like a different app.
289
  sign_canonical_app_bundle "${LATEST_APP}"
@@ -298,7 +298,7 @@ if [[ -n "${LATEST_APP}" ]]; then
298
  cp -R "${LATEST_APP}" "${CANONICAL_OUTPUT_DIR}/"
299
  sign_canonical_app_bundle "${CANONICAL_OUTPUT_DIR}/${APP_BUNDLE_NAME}"
300
  rm -f "${CANONICAL_OUTPUT_DIR}/"*.dmg
301
- CANONICAL_DMG="${CANONICAL_OUTPUT_DIR}/$(basename "${LATEST_DMG:-Claude Code Haha_0.1.0_aarch64.dmg}")"
302
  build_canonical_dmg \
303
  "${CANONICAL_OUTPUT_DIR}/${APP_BUNDLE_NAME}" \
304
  "${CANONICAL_DMG}"
 
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="Versper AI Claw.app"
13
+ APP_BUNDLE_ID="com.versperai.claw.desktop"
14
 
15
  usage() {
16
  cat <<'EOF'
17
+ Build Versper AI Claw desktop for macOS Apple Silicon and output a DMG.
18
 
19
  Usage:
20
  ./desktop/scripts/build-macos-arm64.sh [extra tauri build args...]
 
191
 
192
  # Create a read-write DMG first so we can customize the Finder layout
193
  hdiutil create \
194
+ -volname "Versper AI Claw" \
195
  -srcfolder "${staging_dir}" \
196
  -ov \
197
  -format UDRW \
 
212
  # 所以这里允许 osascript 非零退出,只 warn,不让 set -e 炸掉整个脚本。
213
  if ! osascript <<APPLESCRIPT
214
  tell application "Finder"
215
+ tell disk "Versper AI Claw"
216
  open
217
  set current view of container window to icon view
218
  set toolbar visible of container window to false
 
283
 
284
  if [[ -n "${LATEST_APP}" ]]; then
285
  # Normalize the Tauri-produced app in place before copying it anywhere.
286
+ # Without this, opening target/.../bundle/macos/Versper AI Claw.app directly
287
  # uses the executable's ad-hoc signing identifier instead of the app bundle id,
288
  # which makes macOS notification authorization behave like a different app.
289
  sign_canonical_app_bundle "${LATEST_APP}"
 
298
  cp -R "${LATEST_APP}" "${CANONICAL_OUTPUT_DIR}/"
299
  sign_canonical_app_bundle "${CANONICAL_OUTPUT_DIR}/${APP_BUNDLE_NAME}"
300
  rm -f "${CANONICAL_OUTPUT_DIR}/"*.dmg
301
+ CANONICAL_DMG="${CANONICAL_OUTPUT_DIR}/$(basename "${LATEST_DMG:-Versper AI Claw_0.1.0_aarch64.dmg}")"
302
  build_canonical_dmg \
303
  "${CANONICAL_OUTPUT_DIR}/${APP_BUNDLE_NAME}" \
304
  "${CANONICAL_DMG}"
desktop/scripts/build-sidecars.ts CHANGED
@@ -32,7 +32,7 @@ await mkdir(binariesDir, { recursive: true })
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
 
@@ -145,7 +145,7 @@ async function compileExecutable({
145
  autoloadPackageJson: true,
146
  windows: {
147
  title: productName,
148
- publisher: 'Claude Code',
149
  description: productName,
150
  hideConsole: true,
151
  },
 
32
  await compileExecutable({
33
  entrypoint: path.join(desktopRoot, 'sidecars/claude-sidecar.ts'),
34
  outfileBase: path.join(binariesDir, `claude-sidecar-${targetTriple}`),
35
+ productName: 'Versper Sidecar',
36
  bunTarget,
37
  })
38
 
 
145
  autoloadPackageJson: true,
146
  windows: {
147
  title: productName,
148
+ publisher: 'Versper AI',
149
  description: productName,
150
  hideConsole: true,
151
  },
desktop/scripts/e2e-slash-plugin-agent-browser.sh CHANGED
@@ -143,7 +143,7 @@ echo "Using MCP plugin: ${MCP_PLUGIN_NAME} (${MCP_PLUGIN_ID})"
143
 
144
  "${AB[@]}" open "${WEB_URL}"
145
  "${AB[@]}" wait --load networkidle
146
- wait_for_text "Claude Code Haha"
147
  "${AB[@]}" screenshot "${ARTIFACT_DIR}/01-home.png" >/dev/null
148
 
149
  # Always work from a fresh chat surface so slash-command behavior is deterministic.
 
143
 
144
  "${AB[@]}" open "${WEB_URL}"
145
  "${AB[@]}" wait --load networkidle
146
+ wait_for_text "Versper AI Claw"
147
  "${AB[@]}" screenshot "${ARTIFACT_DIR}/01-home.png" >/dev/null
148
 
149
  # Always work from a fresh chat surface so slash-command behavior is deterministic.
desktop/src-tauri/capabilities/default.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-capabilities-schema-v2.json",
3
  "identifier": "default",
4
- "description": "Default capabilities for Claude Code Desktop",
5
  "windows": ["main"],
6
  "permissions": [
7
  "core:default",
 
1
  {
2
  "$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-capabilities-schema-v2.json",
3
  "identifier": "default",
4
+ "description": "Default capabilities for Versper AI Claw Desktop",
5
  "windows": ["main"],
6
  "permissions": [
7
  "core:default",
desktop/src-tauri/src/lib.rs CHANGED
@@ -859,13 +859,13 @@ fn show_main_window(app: &AppHandle) {
859
 
860
  fn setup_system_tray(app: &mut tauri::App) -> tauri::Result<()> {
861
  let menu = MenuBuilder::new(app)
862
- .text(TRAY_SHOW_ID, "Show Claude Code Haha")
863
  .separator()
864
- .text(TRAY_QUIT_ID, "Quit Claude Code Haha")
865
  .build()?;
866
 
867
  let mut tray = TrayIconBuilder::with_id("main-tray")
868
- .tooltip("Claude Code Haha")
869
  .menu(&menu)
870
  .show_menu_on_left_click(false)
871
  .on_menu_event(|app, event| match event.id().as_ref() {
@@ -2137,12 +2137,12 @@ pub fn run() {
2137
  let builder = builder
2138
  .menu(|app| {
2139
  let about_item =
2140
- MenuItemBuilder::with_id("nav_about", "关于 Claude Code Haha").build(app)?;
2141
  let settings_item = MenuItemBuilder::with_id("nav_settings", "设置...")
2142
  .accelerator("CmdOrCtrl+,")
2143
  .build(app)?;
2144
 
2145
- let app_submenu = SubmenuBuilder::new(app, "Claude Code Haha")
2146
  .item(&about_item)
2147
  .separator()
2148
  .item(&settings_item)
 
859
 
860
  fn setup_system_tray(app: &mut tauri::App) -> tauri::Result<()> {
861
  let menu = MenuBuilder::new(app)
862
+ .text(TRAY_SHOW_ID, "Show Versper AI Claw")
863
  .separator()
864
+ .text(TRAY_QUIT_ID, "Quit Versper AI Claw")
865
  .build()?;
866
 
867
  let mut tray = TrayIconBuilder::with_id("main-tray")
868
+ .tooltip("Versper AI Claw")
869
  .menu(&menu)
870
  .show_menu_on_left_click(false)
871
  .on_menu_event(|app, event| match event.id().as_ref() {
 
2137
  let builder = builder
2138
  .menu(|app| {
2139
  let about_item =
2140
+ MenuItemBuilder::with_id("nav_about", "关于 Versper AI Claw").build(app)?;
2141
  let settings_item = MenuItemBuilder::with_id("nav_settings", "设置...")
2142
  .accelerator("CmdOrCtrl+,")
2143
  .build(app)?;
2144
 
2145
+ let app_submenu = SubmenuBuilder::new(app, "Versper AI Claw")
2146
  .item(&about_item)
2147
  .separator()
2148
  .item(&settings_item)
desktop/src-tauri/src/macos_notifications.m CHANGED
@@ -194,7 +194,7 @@ bool cchh_send_user_notification(const char *title, const char *body, const char
194
 
195
  if (@available(macOS 10.14, *)) {
196
  UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
197
- content.title = title != NULL ? [NSString stringWithUTF8String:title] : @"Claude Code Haha";
198
  if (body != NULL && strlen(body) > 0) {
199
  content.body = [NSString stringWithUTF8String:body];
200
  }
@@ -229,7 +229,7 @@ bool cchh_send_user_notification(const char *title, const char *body, const char
229
  }
230
 
231
  NSUserNotification *notification = [[NSUserNotification alloc] init];
232
- notification.title = title != NULL ? [NSString stringWithUTF8String:title] : @"Claude Code Haha";
233
  if (body != NULL && strlen(body) > 0) {
234
  notification.informativeText = [NSString stringWithUTF8String:body];
235
  }
 
194
 
195
  if (@available(macOS 10.14, *)) {
196
  UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
197
+ content.title = title != NULL ? [NSString stringWithUTF8String:title] : @"Versper AI Claw";
198
  if (body != NULL && strlen(body) > 0) {
199
  content.body = [NSString stringWithUTF8String:body];
200
  }
 
229
  }
230
 
231
  NSUserNotification *notification = [[NSUserNotification alloc] init];
232
+ notification.title = title != NULL ? [NSString stringWithUTF8String:title] : @"Versper AI Claw";
233
  if (body != NULL && strlen(body) > 0) {
234
  notification.informativeText = [NSString stringWithUTF8String:body];
235
  }
desktop/src-tauri/tauri.conf.json CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-schema-v2.json",
3
- "productName": "Claude Code Haha",
4
  "version": "0.2.9",
5
- "identifier": "com.claude-code-haha.desktop",
6
  "build": {
7
  "frontendDist": "../dist",
8
  "devUrl": "http://localhost:1420",
@@ -12,7 +12,7 @@
12
  "app": {
13
  "windows": [
14
  {
15
- "title": "Claude Code Haha",
16
  "width": 1440,
17
  "height": 960,
18
  "minWidth": 960,
 
1
  {
2
  "$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-schema-v2.json",
3
+ "productName": "Versper AI Claw",
4
  "version": "0.2.9",
5
+ "identifier": "com.versperai.claw.desktop",
6
  "build": {
7
  "frontendDist": "../dist",
8
  "devUrl": "http://localhost:1420",
 
12
  "app": {
13
  "windows": [
14
  {
15
+ "title": "Versper AI Claw",
16
  "width": 1440,
17
  "height": 960,
18
  "minWidth": 960,
desktop/src-tauri/tauri.macos.conf.json CHANGED
@@ -2,7 +2,7 @@
2
  "app": {
3
  "windows": [
4
  {
5
- "title": "Claude Code Haha",
6
  "width": 1440,
7
  "height": 960,
8
  "minWidth": 960,
 
2
  "app": {
3
  "windows": [
4
  {
5
+ "title": "Versper AI Claw",
6
  "width": 1440,
7
  "height": 960,
8
  "minWidth": 960,
desktop/src-tauri/tauri.windows.conf.json CHANGED
@@ -2,7 +2,7 @@
2
  "app": {
3
  "windows": [
4
  {
5
- "title": "Claude Code Haha",
6
  "width": 1440,
7
  "height": 960,
8
  "minWidth": 960,
 
2
  "app": {
3
  "windows": [
4
  {
5
+ "title": "Versper AI Claw",
6
  "width": 1440,
7
  "height": 960,
8
  "minWidth": 960,
desktop/src-tauri/windows-installer-hooks.nsh CHANGED
@@ -1,5 +1,5 @@
1
  !macro NSIS_HOOK_PREINSTALL
2
- DetailPrint "Stopping running Claude Code Haha sidecars..."
3
  nsExec::ExecToLog 'taskkill /F /T /IM claude-sidecar-x86_64-pc-windows-msvc.exe'
4
  Pop $0
5
  nsExec::ExecToLog 'taskkill /F /T /IM claude-sidecar-aarch64-pc-windows-msvc.exe'
@@ -10,7 +10,7 @@
10
  !macroend
11
 
12
  !macro NSIS_HOOK_PREUNINSTALL
13
- DetailPrint "Stopping running Claude Code Haha processes..."
14
  nsExec::ExecToLog 'taskkill /F /T /IM claude-code-desktop.exe'
15
  Pop $0
16
  nsExec::ExecToLog 'taskkill /F /T /IM claude-sidecar-x86_64-pc-windows-msvc.exe'
 
1
  !macro NSIS_HOOK_PREINSTALL
2
+ DetailPrint "Stopping running Versper AI Claw sidecars..."
3
  nsExec::ExecToLog 'taskkill /F /T /IM claude-sidecar-x86_64-pc-windows-msvc.exe'
4
  Pop $0
5
  nsExec::ExecToLog 'taskkill /F /T /IM claude-sidecar-aarch64-pc-windows-msvc.exe'
 
10
  !macroend
11
 
12
  !macro NSIS_HOOK_PREUNINSTALL
13
+ DetailPrint "Stopping running Versper AI Claw processes..."
14
  nsExec::ExecToLog 'taskkill /F /T /IM claude-code-desktop.exe'
15
  Pop $0
16
  nsExec::ExecToLog 'taskkill /F /T /IM claude-sidecar-x86_64-pc-windows-msvc.exe'
desktop/src/__tests__/generalSettings.test.tsx CHANGED
@@ -207,7 +207,7 @@ describe('Settings > General tab', () => {
207
  appMode: {
208
  mode: 'default',
209
  portableDir: null,
210
- defaultPortableDir: '/Applications/Claude Code Haha/CLAUDE_CONFIG_DIR',
211
  activeConfigDir: null,
212
  configDirSource: 'system',
213
  },
@@ -217,9 +217,9 @@ describe('Settings > General tab', () => {
217
  useSettingsStore.setState({
218
  appMode: {
219
  mode,
220
- portableDir: mode === 'portable' ? portableDir ?? '/Applications/Claude Code Haha/CLAUDE_CONFIG_DIR' : null,
221
- defaultPortableDir: '/Applications/Claude Code Haha/CLAUDE_CONFIG_DIR',
222
- activeConfigDir: mode === 'portable' ? portableDir ?? '/Applications/Claude Code Haha/CLAUDE_CONFIG_DIR' : null,
223
  configDirSource: mode === 'portable' ? 'portable' : 'system',
224
  },
225
  appModeRequiresRestart: true,
@@ -435,7 +435,7 @@ describe('Settings > General tab', () => {
435
  appMode: {
436
  mode: 'portable',
437
  portableDir: '/Users/test/cc-haha-data',
438
- defaultPortableDir: '/Applications/Claude Code Haha/CLAUDE_CONFIG_DIR',
439
  activeConfigDir: '/Users/test/cc-haha-data',
440
  configDirSource: 'portable',
441
  },
@@ -470,7 +470,7 @@ describe('Settings > General tab', () => {
470
  expect(screen.getByText('Choose or enter a portable data directory first.')).toBeInTheDocument()
471
 
472
  fireEvent.click(screen.getByRole('button', { name: 'Use the default portable folder beside the app' }))
473
- expect(input).toHaveValue('/Applications/Claude Code Haha/CLAUDE_CONFIG_DIR')
474
  expect(screen.queryByText('Choose or enter a portable data directory first.')).not.toBeInTheDocument()
475
  })
476
 
@@ -494,7 +494,7 @@ describe('Settings > General tab', () => {
494
  appMode: {
495
  mode: 'portable',
496
  portableDir: '/env/claude-data',
497
- defaultPortableDir: '/Applications/Claude Code Haha/CLAUDE_CONFIG_DIR',
498
  activeConfigDir: '/env/claude-data',
499
  configDirSource: 'environment',
500
  },
@@ -694,7 +694,7 @@ describe('Settings > General tab', () => {
694
  expect(desktopNotificationsMock.requestDesktopNotificationPermission).toHaveBeenCalledTimes(1)
695
  })
696
  expect(desktopNotificationsMock.notifyDesktop).toHaveBeenCalledWith({
697
- title: 'Claude Code Haha notifications are enabled',
698
  body: 'Permission prompts and completed agent replies will now use system notifications.',
699
  })
700
  })
@@ -1204,7 +1204,7 @@ describe('Settings > About tab', () => {
1204
  useUpdateStore.setState({
1205
  status: 'available',
1206
  availableVersion: '0.1.5',
1207
- releaseNotes: '# Claude Code Haha v0.1.5\n\n- Fixed updater rendering\n- Added markdown support',
1208
  progressPercent: 0,
1209
  downloadedBytes: 0,
1210
  totalBytes: null,
@@ -1221,7 +1221,7 @@ describe('Settings > About tab', () => {
1221
  it('renders release notes with markdown formatting', async () => {
1222
  render(<Settings />)
1223
 
1224
- expect(await screen.findByRole('heading', { name: 'Claude Code Haha v0.1.5' })).toBeInTheDocument()
1225
  expect(screen.getByText('Fixed updater rendering')).toBeInTheDocument()
1226
  expect(screen.getByText('Added markdown support')).toBeInTheDocument()
1227
  })
@@ -1230,7 +1230,7 @@ describe('Settings > About tab', () => {
1230
  useUpdateStore.setState({
1231
  status: 'downloading',
1232
  availableVersion: '0.1.5',
1233
- releaseNotes: '# Claude Code Haha v0.1.5',
1234
  progressPercent: 0,
1235
  downloadedBytes: 1536,
1236
  totalBytes: null,
 
207
  appMode: {
208
  mode: 'default',
209
  portableDir: null,
210
+ defaultPortableDir: '/Applications/Versper AI Claw/CLAUDE_CONFIG_DIR',
211
  activeConfigDir: null,
212
  configDirSource: 'system',
213
  },
 
217
  useSettingsStore.setState({
218
  appMode: {
219
  mode,
220
+ portableDir: mode === 'portable' ? portableDir ?? '/Applications/Versper AI Claw/CLAUDE_CONFIG_DIR' : null,
221
+ defaultPortableDir: '/Applications/Versper AI Claw/CLAUDE_CONFIG_DIR',
222
+ activeConfigDir: mode === 'portable' ? portableDir ?? '/Applications/Versper AI Claw/CLAUDE_CONFIG_DIR' : null,
223
  configDirSource: mode === 'portable' ? 'portable' : 'system',
224
  },
225
  appModeRequiresRestart: true,
 
435
  appMode: {
436
  mode: 'portable',
437
  portableDir: '/Users/test/cc-haha-data',
438
+ defaultPortableDir: '/Applications/Versper AI Claw/CLAUDE_CONFIG_DIR',
439
  activeConfigDir: '/Users/test/cc-haha-data',
440
  configDirSource: 'portable',
441
  },
 
470
  expect(screen.getByText('Choose or enter a portable data directory first.')).toBeInTheDocument()
471
 
472
  fireEvent.click(screen.getByRole('button', { name: 'Use the default portable folder beside the app' }))
473
+ expect(input).toHaveValue('/Applications/Versper AI Claw/CLAUDE_CONFIG_DIR')
474
  expect(screen.queryByText('Choose or enter a portable data directory first.')).not.toBeInTheDocument()
475
  })
476
 
 
494
  appMode: {
495
  mode: 'portable',
496
  portableDir: '/env/claude-data',
497
+ defaultPortableDir: '/Applications/Versper AI Claw/CLAUDE_CONFIG_DIR',
498
  activeConfigDir: '/env/claude-data',
499
  configDirSource: 'environment',
500
  },
 
694
  expect(desktopNotificationsMock.requestDesktopNotificationPermission).toHaveBeenCalledTimes(1)
695
  })
696
  expect(desktopNotificationsMock.notifyDesktop).toHaveBeenCalledWith({
697
+ title: 'Versper AI Claw notifications are enabled',
698
  body: 'Permission prompts and completed agent replies will now use system notifications.',
699
  })
700
  })
 
1204
  useUpdateStore.setState({
1205
  status: 'available',
1206
  availableVersion: '0.1.5',
1207
+ releaseNotes: '# Versper AI Claw v0.1.5\n\n- Fixed updater rendering\n- Added markdown support',
1208
  progressPercent: 0,
1209
  downloadedBytes: 0,
1210
  totalBytes: null,
 
1221
  it('renders release notes with markdown formatting', async () => {
1222
  render(<Settings />)
1223
 
1224
+ expect(await screen.findByRole('heading', { name: 'Versper AI Claw v0.1.5' })).toBeInTheDocument()
1225
  expect(screen.getByText('Fixed updater rendering')).toBeInTheDocument()
1226
  expect(screen.getByText('Added markdown support')).toBeInTheDocument()
1227
  })
 
1230
  useUpdateStore.setState({
1231
  status: 'downloading',
1232
  availableVersion: '0.1.5',
1233
+ releaseNotes: '# Versper AI Claw v0.1.5',
1234
  progressPercent: 0,
1235
  downloadedBytes: 1536,
1236
  totalBytes: null,
desktop/src/components/chat/chatBlocks.test.tsx CHANGED
@@ -83,7 +83,7 @@ describe('chat blocks', () => {
83
  toolName="mcp__computer-use__left_click"
84
  input={{ coordinate: [120, 220] }}
85
  result={{
86
- content: '"Claude Code Haha" is not in the allowed applications and is currently in front. Take a new screenshot — it may have appeared since your last one.',
87
  isError: true,
88
  }}
89
  />,
 
83
  toolName="mcp__computer-use__left_click"
84
  input={{ coordinate: [120, 220] }}
85
  result={{
86
+ content: '"Versper AI Claw" is not in the allowed applications and is currently in front. Take a new screenshot — it may have appeared since your last one.',
87
  isError: true,
88
  }}
89
  />,
desktop/src/components/shared/UpdateChecker.test.tsx CHANGED
@@ -17,7 +17,7 @@ describe('UpdateChecker', () => {
17
  useUpdateStore.setState({
18
  status: 'available',
19
  availableVersion: '0.1.5',
20
- releaseNotes: '# Claude Code Haha v0.1.5\n\n[Release notes](https://example.com/releases/v0.1.5)',
21
  progressPercent: 0,
22
  downloadedBytes: 0,
23
  totalBytes: null,
@@ -35,7 +35,7 @@ describe('UpdateChecker', () => {
35
  render(<UpdateChecker />)
36
 
37
  expect(screen.getByText('v0.1.5 available')).toBeInTheDocument()
38
- expect(screen.getByRole('heading', { name: 'Claude Code Haha v0.1.5' })).toBeInTheDocument()
39
 
40
  const link = screen.getByRole('link', { name: 'Release notes' })
41
  expect(link).toHaveAttribute('href', 'https://example.com/releases/v0.1.5')
@@ -46,7 +46,7 @@ describe('UpdateChecker', () => {
46
  useUpdateStore.setState({
47
  status: 'downloading',
48
  availableVersion: '0.1.5',
49
- releaseNotes: '# Claude Code Haha v0.1.5',
50
  progressPercent: 0,
51
  downloadedBytes: 1536,
52
  totalBytes: null,
 
17
  useUpdateStore.setState({
18
  status: 'available',
19
  availableVersion: '0.1.5',
20
+ releaseNotes: '# Versper AI Claw v0.1.5\n\n[Release notes](https://example.com/releases/v0.1.5)',
21
  progressPercent: 0,
22
  downloadedBytes: 0,
23
  totalBytes: null,
 
35
  render(<UpdateChecker />)
36
 
37
  expect(screen.getByText('v0.1.5 available')).toBeInTheDocument()
38
+ expect(screen.getByRole('heading', { name: 'Versper AI Claw v0.1.5' })).toBeInTheDocument()
39
 
40
  const link = screen.getByRole('link', { name: 'Release notes' })
41
  expect(link).toHaveAttribute('href', 'https://example.com/releases/v0.1.5')
 
46
  useUpdateStore.setState({
47
  status: 'downloading',
48
  availableVersion: '0.1.5',
49
+ releaseNotes: '# Versper AI Claw v0.1.5',
50
  progressPercent: 0,
51
  downloadedBytes: 1536,
52
  totalBytes: null,
desktop/src/i18n/locales/en.ts CHANGED
@@ -878,7 +878,7 @@ export const en = {
878
  'settings.general.notificationsStatusUnsupported': 'Unavailable in this environment',
879
  'settings.general.notificationsAuthorize': 'Authorize',
880
  'settings.general.notificationsOpenSettings': 'Open Settings',
881
- 'settings.general.notificationsTestTitle': 'Claude Code Haha notifications are enabled',
882
  'settings.general.notificationsTestBody': 'Permission prompts and completed agent replies will now use system notifications.',
883
  'settings.general.h5AccessTitle': 'H5 Access',
884
  'settings.general.h5AccessDescription': 'Expose the desktop H5 app on your local network. Phones connect with a QR link that includes a short-lived H5 token.',
 
878
  'settings.general.notificationsStatusUnsupported': 'Unavailable in this environment',
879
  'settings.general.notificationsAuthorize': 'Authorize',
880
  'settings.general.notificationsOpenSettings': 'Open Settings',
881
+ 'settings.general.notificationsTestTitle': 'Versper AI Claw notifications are enabled',
882
  'settings.general.notificationsTestBody': 'Permission prompts and completed agent replies will now use system notifications.',
883
  'settings.general.h5AccessTitle': 'H5 Access',
884
  'settings.general.h5AccessDescription': 'Expose the desktop H5 app on your local network. Phones connect with a QR link that includes a short-lived H5 token.',
desktop/src/i18n/locales/zh.ts CHANGED
@@ -880,7 +880,7 @@ export const zh: Record<TranslationKey, string> = {
880
  'settings.general.notificationsStatusUnsupported': '当前环境不可用',
881
  'settings.general.notificationsAuthorize': '授权通知',
882
  'settings.general.notificationsOpenSettings': '打开系统设置',
883
- 'settings.general.notificationsTestTitle': 'Claude Code Haha 通知已启用',
884
  'settings.general.notificationsTestBody': '后续授权确认和 Agent 回复完成都会通过系统通知提醒。',
885
  'settings.general.h5AccessTitle': 'H5 访问',
886
  'settings.general.h5AccessDescription': '在局域网内暴露桌面端 H5 应用。手机通过带 H5 token 的二维码快速连接。',
 
880
  'settings.general.notificationsStatusUnsupported': '当前环境不可用',
881
  'settings.general.notificationsAuthorize': '授权通知',
882
  'settings.general.notificationsOpenSettings': '打开系统设置',
883
+ 'settings.general.notificationsTestTitle': 'Versper AI Claw 通知已启用',
884
  'settings.general.notificationsTestBody': '后续授权确认和 Agent 回复完成都会通过系统通知提醒。',
885
  'settings.general.h5AccessTitle': 'H5 访问',
886
  'settings.general.h5AccessDescription': '在局域网内暴露桌面端 H5 应用。手机通过带 H5 token 的二维码快速连接。',
desktop/src/pages/ActiveSession.tsx CHANGED
@@ -408,7 +408,7 @@ export function ActiveSession() {
408
  </>
409
  ) : (
410
  <>
411
- <img src="/app-icon.png" alt="Claude Code Haha" className="mb-6 h-24 w-24" />
412
  <h1 className="mb-2 text-3xl font-extrabold tracking-tight text-[var(--color-text-primary)]" style={{ fontFamily: 'var(--font-headline)' }}>
413
  {t('empty.title')}
414
  </h1>
 
408
  </>
409
  ) : (
410
  <>
411
+ <img src="/app-icon.png" alt="Versper AI Claw" className="mb-6 h-24 w-24" />
412
  <h1 className="mb-2 text-3xl font-extrabold tracking-tight text-[var(--color-text-primary)]" style={{ fontFamily: 'var(--font-headline)' }}>
413
  {t('empty.title')}
414
  </h1>
desktop/src/pages/NewTaskModal.tsx CHANGED
@@ -25,7 +25,7 @@ export default function NewTaskModal() {
25
  <header className="bg-[var(--color-background)] flex justify-between items-center px-6 h-12 w-full z-40">
26
  <div className="flex items-center gap-6">
27
  <span className="text-sm font-bold text-[var(--color-text-primary)] uppercase tracking-tighter font-[var(--font-headline)]">
28
- Claude Code Companion
29
  </span>
30
  <nav className="hidden md:flex gap-4 font-[var(--font-headline)] font-semibold tracking-wide text-sm">
31
  <a className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors cursor-pointer">Code</a>
 
25
  <header className="bg-[var(--color-background)] flex justify-between items-center px-6 h-12 w-full z-40">
26
  <div className="flex items-center gap-6">
27
  <span className="text-sm font-bold text-[var(--color-text-primary)] uppercase tracking-tighter font-[var(--font-headline)]">
28
+ Versper AI Claw
29
  </span>
30
  <nav className="hidden md:flex gap-4 font-[var(--font-headline)] font-semibold tracking-wide text-sm">
31
  <a className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors cursor-pointer">Code</a>
desktop/src/pages/ScheduledTasksEmpty.tsx CHANGED
@@ -59,7 +59,7 @@ export function ScheduledTasksEmpty() {
59
  {/* TopAppBar */}
60
  <header className="fixed top-0 right-0 left-[280px] z-30 bg-[var(--color-background)] flex justify-between items-center px-6 h-12 w-full border-b border-[var(--color-border)]">
61
  <div className="flex items-center gap-6 h-full">
62
- <div className="text-sm font-bold text-[var(--color-text-primary)] uppercase tracking-tighter font-[Manrope,sans-serif]">Claude Code Companion</div>
63
  <nav className="flex items-center gap-4 h-full font-[Manrope,sans-serif] font-semibold tracking-wide text-sm">
64
  <span className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors cursor-pointer active:opacity-70 h-full flex items-center">{t('titlebar.code')}</span>
65
  <span className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors cursor-pointer active:opacity-70 h-full flex items-center">{t('titlebar.terminal')}</span>
 
59
  {/* TopAppBar */}
60
  <header className="fixed top-0 right-0 left-[280px] z-30 bg-[var(--color-background)] flex justify-between items-center px-6 h-12 w-full border-b border-[var(--color-border)]">
61
  <div className="flex items-center gap-6 h-full">
62
+ <div className="text-sm font-bold text-[var(--color-text-primary)] uppercase tracking-tighter font-[Manrope,sans-serif]">Versper AI Claw</div>
63
  <nav className="flex items-center gap-4 h-full font-[Manrope,sans-serif] font-semibold tracking-wide text-sm">
64
  <span className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors cursor-pointer active:opacity-70 h-full flex items-center">{t('titlebar.code')}</span>
65
  <span className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors cursor-pointer active:opacity-70 h-full flex items-center">{t('titlebar.terminal')}</span>
desktop/src/pages/ScheduledTasksList.tsx CHANGED
@@ -77,7 +77,7 @@ export function ScheduledTasksList() {
77
  {/* TopAppBar */}
78
  <header className="bg-[var(--color-background)] h-12 w-full flex justify-between items-center px-6 z-30">
79
  <div className="flex items-center gap-8">
80
- <div className="font-[Manrope,sans-serif] font-bold text-[var(--color-text-primary)] uppercase tracking-tighter text-sm">Claude Code Companion</div>
81
  <nav className="flex items-center gap-6 font-[Manrope,sans-serif] font-semibold tracking-wide text-sm">
82
  <a className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors" href="#">{t('titlebar.code')}</a>
83
  <a className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors" href="#">{t('titlebar.terminal')}</a>
 
77
  {/* TopAppBar */}
78
  <header className="bg-[var(--color-background)] h-12 w-full flex justify-between items-center px-6 z-30">
79
  <div className="flex items-center gap-8">
80
+ <div className="font-[Manrope,sans-serif] font-bold text-[var(--color-text-primary)] uppercase tracking-tighter text-sm">Versper AI Claw</div>
81
  <nav className="flex items-center gap-6 font-[Manrope,sans-serif] font-semibold tracking-wide text-sm">
82
  <a className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors" href="#">{t('titlebar.code')}</a>
83
  <a className="text-[var(--color-text-tertiary)] hover:text-[var(--color-brand)] transition-colors" href="#">{t('titlebar.terminal')}</a>
desktop/src/pages/SessionControls.tsx CHANGED
@@ -42,7 +42,7 @@ export default function SessionControls() {
42
  <header className="bg-[var(--color-background)] font-headline font-semibold tracking-wide text-sm fixed top-0 left-0 right-0 flex justify-between items-center px-6 h-12 z-40">
43
  <div className="flex items-center gap-6">
44
  <span className="text-sm font-bold text-[var(--color-text-primary)] uppercase tracking-tighter">
45
- Claude Code Companion
46
  </span>
47
  <nav className="hidden md:flex gap-4">
48
  <a className="text-[var(--color-text-primary)] border-b-2 border-[var(--color-brand)] pb-1 cursor-pointer active:opacity-70">
 
42
  <header className="bg-[var(--color-background)] font-headline font-semibold tracking-wide text-sm fixed top-0 left-0 right-0 flex justify-between items-center px-6 h-12 z-40">
43
  <div className="flex items-center gap-6">
44
  <span className="text-sm font-bold text-[var(--color-text-primary)] uppercase tracking-tighter">
45
+ Versper AI Claw
46
  </span>
47
  <nav className="hidden md:flex gap-4">
48
  <a className="text-[var(--color-text-primary)] border-b-2 border-[var(--color-brand)] pb-1 cursor-pointer active:opacity-70">
desktop/src/pages/Settings.tsx CHANGED
@@ -3557,8 +3557,8 @@ function AboutSettings() {
3557
  return (
3558
  <div className="w-full min-w-0 max-w-lg mx-auto flex flex-col items-center py-6">
3559
  {/* Logo + App Name + Version */}
3560
- <img src="/app-icon.png" alt="Claude Code Haha" className="w-20 h-20 mb-4" />
3561
- <h1 className="text-xl font-bold text-[var(--color-text-primary)]">Claude Code Haha</h1>
3562
  {version && (
3563
  <div className="mt-1 flex items-center gap-2 text-xs text-[var(--color-text-tertiary)]">
3564
  <span>{t('settings.about.version')} {version}</span>
 
3557
  return (
3558
  <div className="w-full min-w-0 max-w-lg mx-auto flex flex-col items-center py-6">
3559
  {/* Logo + App Name + Version */}
3560
+ <img src="/app-icon.png" alt="Versper AI Claw" className="w-20 h-20 mb-4" />
3561
+ <h1 className="text-xl font-bold text-[var(--color-text-primary)]">Versper AI Claw</h1>
3562
  {version && (
3563
  <div className="mt-1 flex items-center gap-2 text-xs text-[var(--color-text-tertiary)]">
3564
  <span>{t('settings.about.version')} {version}</span>
desktop/src/stores/chatStore.test.ts CHANGED
@@ -1464,7 +1464,7 @@ describe('chatStore history mapping', () => {
1464
  dedupeKey: 'permission:perm-ask-1',
1465
  cooldownScope: 'permission-prompt',
1466
  requestAttention: true,
1467
- title: 'Claude Code Haha 需要你的确认',
1468
  body: 'AskUserQuestion 请求执行,正在等待允许。',
1469
  target: { type: 'session', sessionId: TEST_SESSION_ID },
1470
  })
@@ -2557,7 +2557,7 @@ describe('chatStore history mapping', () => {
2557
  dedupeKey: 'computer-use-permission:cu-1',
2558
  cooldownScope: 'permission-prompt',
2559
  requestAttention: true,
2560
- title: 'Claude Code Haha 需要你的确认',
2561
  body: 'Open Finder and inspect a file',
2562
  target: { type: 'session', sessionId: TEST_SESSION_ID },
2563
  })
@@ -2997,7 +2997,7 @@ describe('chatStore history mapping', () => {
2997
 
2998
  expect(notifyDesktopMock).toHaveBeenCalledWith(expect.objectContaining({
2999
  cooldownScope: 'agent-completion',
3000
- title: 'Claude Code Haha 已完成回复',
3001
  body: '结果 修复完成 bun test 已通过',
3002
  target: { type: 'session', sessionId: TEST_SESSION_ID },
3003
  }))
 
1464
  dedupeKey: 'permission:perm-ask-1',
1465
  cooldownScope: 'permission-prompt',
1466
  requestAttention: true,
1467
+ title: 'Versper AI Claw 需要你的确认',
1468
  body: 'AskUserQuestion 请求执行,正在等待允许。',
1469
  target: { type: 'session', sessionId: TEST_SESSION_ID },
1470
  })
 
2557
  dedupeKey: 'computer-use-permission:cu-1',
2558
  cooldownScope: 'permission-prompt',
2559
  requestAttention: true,
2560
+ title: 'Versper AI Claw 需要你的确认',
2561
  body: 'Open Finder and inspect a file',
2562
  target: { type: 'session', sessionId: TEST_SESSION_ID },
2563
  })
 
2997
 
2998
  expect(notifyDesktopMock).toHaveBeenCalledWith(expect.objectContaining({
2999
  cooldownScope: 'agent-completion',
3000
+ title: 'Versper AI Claw 已完成回复',
3001
  body: '结果 修复完成 bun test 已通过',
3002
  target: { type: 'session', sessionId: TEST_SESSION_ID },
3003
  }))
desktop/src/stores/chatStore.ts CHANGED
@@ -560,7 +560,7 @@ function buildAgentCompletionNotification(
560
  const lastAssistant = [...messages].reverse().find((message) => message.type === 'assistant_text')
561
  const suffix = preview.length > AGENT_COMPLETION_NOTIFICATION_PREVIEW_CHARS ? '...' : ''
562
  return {
563
- title: 'Claude Code Haha 已完成回复',
564
  body: preview.slice(0, AGENT_COMPLETION_NOTIFICATION_PREVIEW_CHARS) + suffix,
565
  dedupeKey: `agent-completion:${sessionId}:${lastAssistant?.id ?? Date.now()}`,
566
  }
@@ -1240,7 +1240,7 @@ export const useChatStore = create<ChatStore>((set, get) => ({
1240
  dedupeKey: `permission:${msg.requestId}`,
1241
  cooldownScope: 'permission-prompt',
1242
  requestAttention: true,
1243
- title: 'Claude Code Haha 需要你的确认',
1244
  body: msg.toolName
1245
  ? `${msg.toolName} 请求执行,正在等待允许。`
1246
  : '有一个工具请求正在等待允许。',
@@ -1279,7 +1279,7 @@ export const useChatStore = create<ChatStore>((set, get) => ({
1279
  dedupeKey: `computer-use-permission:${msg.requestId}`,
1280
  cooldownScope: 'permission-prompt',
1281
  requestAttention: true,
1282
- title: 'Claude Code Haha 需要你的确认',
1283
  body: msg.request.reason || 'Computer Use 正在等待允许。',
1284
  target: { type: 'session', sessionId },
1285
  })
 
560
  const lastAssistant = [...messages].reverse().find((message) => message.type === 'assistant_text')
561
  const suffix = preview.length > AGENT_COMPLETION_NOTIFICATION_PREVIEW_CHARS ? '...' : ''
562
  return {
563
+ title: 'Versper AI Claw 已完成回复',
564
  body: preview.slice(0, AGENT_COMPLETION_NOTIFICATION_PREVIEW_CHARS) + suffix,
565
  dedupeKey: `agent-completion:${sessionId}:${lastAssistant?.id ?? Date.now()}`,
566
  }
 
1240
  dedupeKey: `permission:${msg.requestId}`,
1241
  cooldownScope: 'permission-prompt',
1242
  requestAttention: true,
1243
+ title: 'Versper AI Claw 需要你的确认',
1244
  body: msg.toolName
1245
  ? `${msg.toolName} 请求执行,正在等待允许。`
1246
  : '有一个工具请求正在等待允许。',
 
1279
  dedupeKey: `computer-use-permission:${msg.requestId}`,
1280
  cooldownScope: 'permission-prompt',
1281
  requestAttention: true,
1282
+ title: 'Versper AI Claw 需要你的确认',
1283
  body: msg.request.reason || 'Computer Use 正在等待允许。',
1284
  target: { type: 'session', sessionId },
1285
  })
desktop/tsconfig.tsbuildinfo ADDED
@@ -0,0 +1 @@
 
 
1
+ {"root":["./src/App.tsx","./src/main.test.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/__tests__/agentsSettings.test.tsx","./src/__tests__/diagnosticsSettings.test.tsx","./src/__tests__/generalSettings.test.tsx","./src/__tests__/mcpSettings.test.tsx","./src/__tests__/memorySettings.test.tsx","./src/__tests__/pages.test.tsx","./src/__tests__/pluginsSettings.test.tsx","./src/__tests__/skillsSettings.test.tsx","./src/__tests__/tauriCapabilities.test.ts","./src/api/activityStats.ts","./src/api/adapters.ts","./src/api/agents.ts","./src/api/cliTasks.ts","./src/api/client.test.ts","./src/api/client.ts","./src/api/computerUse.ts","./src/api/desktopUiPreferences.ts","./src/api/diagnostics.ts","./src/api/doctor.ts","./src/api/filesystem.ts","./src/api/h5Access.ts","./src/api/hahaOAuth.ts","./src/api/hahaOpenAIOAuth.ts","./src/api/mcp.ts","./src/api/memory.ts","./src/api/models.ts","./src/api/openTargets.test.ts","./src/api/openTargets.ts","./src/api/plugins.ts","./src/api/providers.ts","./src/api/search.ts","./src/api/sessions.test.ts","./src/api/sessions.ts","./src/api/settings.ts","./src/api/skills.ts","./src/api/tasks.ts","./src/api/teams.ts","./src/api/terminal.ts","./src/api/websocket.test.ts","./src/api/websocket.ts","./src/components/ErrorBoundary.test.tsx","./src/components/ErrorBoundary.tsx","./src/components/chat/AskUserQuestion.test.tsx","./src/components/chat/AskUserQuestion.tsx","./src/components/chat/AssistantMessage.tsx","./src/components/chat/AttachmentGallery.test.tsx","./src/components/chat/AttachmentGallery.tsx","./src/components/chat/ChatInput.test.tsx","./src/components/chat/ChatInput.tsx","./src/components/chat/CodeViewer.test.tsx","./src/components/chat/CodeViewer.tsx","./src/components/chat/ComposerDropOverlay.tsx","./src/components/chat/ComputerUsePermissionModal.test.tsx","./src/components/chat/ComputerUsePermissionModal.tsx","./src/components/chat/ContextUsageIndicator.test.tsx","./src/components/chat/ContextUsageIndicator.tsx","./src/components/chat/CurrentTurnChangeCard.tsx","./src/components/chat/DiffViewer.tsx","./src/components/chat/FileSearchMenu.test.tsx","./src/components/chat/FileSearchMenu.tsx","./src/components/chat/ImageGalleryModal.tsx","./src/components/chat/InlineImageGallery.tsx","./src/components/chat/InlineTaskSummary.tsx","./src/components/chat/LocalSlashCommandPanel.test.tsx","./src/components/chat/LocalSlashCommandPanel.tsx","./src/components/chat/MermaidRenderer.test.tsx","./src/components/chat/MermaidRenderer.tsx","./src/components/chat/MessageActionBar.tsx","./src/components/chat/MessageList.test.tsx","./src/components/chat/MessageList.tsx","./src/components/chat/PermissionDialog.tsx","./src/components/chat/SessionTaskBar.test.tsx","./src/components/chat/SessionTaskBar.tsx","./src/components/chat/StreamingIndicator.tsx","./src/components/chat/TerminalChrome.tsx","./src/components/chat/ThinkingBlock.tsx","./src/components/chat/ToolCallBlock.tsx","./src/components/chat/ToolCallGroup.tsx","./src/components/chat/ToolResultBlock.tsx","./src/components/chat/UserMessage.test.tsx","./src/components/chat/UserMessage.tsx","./src/components/chat/chatBlocks.test.tsx","./src/components/chat/clipboard.ts","./src/components/chat/composerUtils.test.ts","./src/components/chat/composerUtils.ts","./src/components/chat/useComposerFileDrop.ts","./src/components/companion/CompanionControls.tsx","./src/components/companion/CompanionTranscript.tsx","./src/components/companion/CompanionVideoPanel.tsx","./src/components/controls/ModelSelector.test.tsx","./src/components/controls/ModelSelector.tsx","./src/components/controls/PermissionModeSelector.test.tsx","./src/components/controls/PermissionModeSelector.tsx","./src/components/doctor/DoctorPanel.tsx","./src/components/layout/AppShell.test.tsx","./src/components/layout/AppShell.tsx","./src/components/layout/ContentRouter.test.tsx","./src/components/layout/ContentRouter.tsx","./src/components/layout/H5ConnectionView.tsx","./src/components/layout/OpenProjectMenu.test.tsx","./src/components/layout/OpenProjectMenu.tsx","./src/components/layout/Sidebar.test.tsx","./src/components/layout/Sidebar.tsx","./src/components/layout/StartupErrorView.test.tsx","./src/components/layout/StartupErrorView.tsx","./src/components/layout/StatusBar.tsx","./src/components/layout/TabBar.test.tsx","./src/components/layout/TabBar.tsx","./src/components/layout/TitleBar.tsx","./src/components/layout/WindowControls.test.tsx","./src/components/layout/WindowControls.tsx","./src/components/markdown/MarkdownRenderer.test.tsx","./src/components/markdown/MarkdownRenderer.tsx","./src/components/plugins/PluginDetail.tsx","./src/components/plugins/PluginList.tsx","./src/components/settings/ChatGPTOfficialLogin.test.tsx","./src/components/settings/ChatGPTOfficialLogin.tsx","./src/components/settings/ClaudeOfficialLogin.tsx","./src/components/shared/Button.tsx","./src/components/shared/ConfirmDialog.tsx","./src/components/shared/CopyButton.tsx","./src/components/shared/DirectoryPicker.test.tsx","./src/components/shared/DirectoryPicker.tsx","./src/components/shared/Dropdown.tsx","./src/components/shared/Input.tsx","./src/components/shared/MobileBottomSheet.tsx","./src/components/shared/Modal.test.tsx","./src/components/shared/Modal.tsx","./src/components/shared/ProjectContextChip.test.tsx","./src/components/shared/ProjectContextChip.tsx","./src/components/shared/RepositoryLaunchControls.test.tsx","./src/components/shared/RepositoryLaunchControls.tsx","./src/components/shared/Spinner.tsx","./src/components/shared/Textarea.tsx","./src/components/shared/Toast.tsx","./src/components/shared/UpdateChecker.test.tsx","./src/components/shared/UpdateChecker.tsx","./src/components/skills/SkillDetail.test.tsx","./src/components/skills/SkillDetail.tsx","./src/components/skills/SkillList.tsx","./src/components/tasks/DayOfWeekPicker.tsx","./src/components/tasks/NewTaskModal.test.tsx","./src/components/tasks/NewTaskModal.tsx","./src/components/tasks/PromptEditor.tsx","./src/components/tasks/TaskEmptyState.tsx","./src/components/tasks/TaskList.tsx","./src/components/tasks/TaskRow.tsx","./src/components/tasks/TaskRunsPanel.test.tsx","./src/components/tasks/TaskRunsPanel.tsx","./src/components/teams/TeamStatusBar.tsx","./src/components/workspace/WorkspaceCodeSurface.tsx","./src/components/workspace/WorkspacePanel.test.tsx","./src/components/workspace/WorkspacePanel.tsx","./src/config/spinnerVerbs.ts","./src/constants/modelCatalog.ts","./src/constants/openaiOfficialProvider.ts","./src/hooks/useCompanionAudio.ts","./src/hooks/useCompanionWebSocket.ts","./src/hooks/useKeyboardShortcuts.test.tsx","./src/hooks/useKeyboardShortcuts.ts","./src/hooks/useMicrophone.ts","./src/hooks/useMobileViewport.test.tsx","./src/hooks/useMobileViewport.ts","./src/hooks/useScheduledTaskDesktopNotifications.test.tsx","./src/hooks/useScheduledTaskDesktopNotifications.ts","./src/hooks/useSelectionPopoverDismiss.ts","./src/hooks/useWebcam.ts","./src/i18n/index.test.tsx","./src/i18n/index.ts","./src/i18n/locales/en.ts","./src/i18n/locales/zh.ts","./src/lib/appZoom.test.ts","./src/lib/appZoom.ts","./src/lib/audioEngine.ts","./src/lib/composerAttachments.test.ts","./src/lib/composerAttachments.ts","./src/lib/cronDescribe.ts","./src/lib/desktopNotificationNavigation.test.ts","./src/lib/desktopNotificationNavigation.ts","./src/lib/desktopNotifications.test.ts","./src/lib/desktopNotifications.ts","./src/lib/desktopRuntime.test.ts","./src/lib/desktopRuntime.ts","./src/lib/diagnosticsCapture.ts","./src/lib/doctorRepair.test.ts","./src/lib/doctorRepair.ts","./src/lib/formatBytes.ts","./src/lib/parseRunOutput.ts","./src/lib/persistenceMigrations.test.ts","./src/lib/persistenceMigrations.ts","./src/lib/providerSettingsJson.ts","./src/lib/sessionTitle.test.ts","./src/lib/sessionTitle.ts","./src/lib/__tests__/cronDescribe.test.ts","./src/lib/__tests__/providerSettingsJson.test.ts","./src/mocks/data.ts","./src/pages/ActiveSession.test.tsx","./src/pages/ActiveSession.tsx","./src/pages/ActivitySettings.test.tsx","./src/pages/ActivitySettings.tsx","./src/pages/AdapterSettings.test.tsx","./src/pages/AdapterSettings.tsx","./src/pages/AgentTeams.tsx","./src/pages/Companion.tsx","./src/pages/ComputerUseSettings.test.tsx","./src/pages/ComputerUseSettings.tsx","./src/pages/DiagnosticsSettings.tsx","./src/pages/EmptySession.test.tsx","./src/pages/EmptySession.tsx","./src/pages/McpSettings.tsx","./src/pages/MemorySettings.tsx","./src/pages/NewTaskModal.tsx","./src/pages/ScheduledTasks.tsx","./src/pages/ScheduledTasksEmpty.tsx","./src/pages/ScheduledTasksList.tsx","./src/pages/SessionControls.tsx","./src/pages/Settings.tsx","./src/pages/TerminalSettings.test.tsx","./src/pages/TerminalSettings.tsx","./src/pages/ToolInspection.tsx","./src/stores/adapterStore.test.ts","./src/stores/adapterStore.ts","./src/stores/agentStore.ts","./src/stores/chatStore.test.ts","./src/stores/chatStore.ts","./src/stores/cliTaskStore.test.ts","./src/stores/cliTaskStore.ts","./src/stores/companionStore.ts","./src/stores/hahaOAuthStore.test.ts","./src/stores/hahaOAuthStore.ts","./src/stores/hahaOpenAIOAuthStore.test.ts","./src/stores/hahaOpenAIOAuthStore.ts","./src/stores/mcpStore.ts","./src/stores/memoryStore.ts","./src/stores/openTargetStore.test.ts","./src/stores/openTargetStore.ts","./src/stores/pluginStore.test.ts","./src/stores/pluginStore.ts","./src/stores/providerStore.test.ts","./src/stores/providerStore.ts","./src/stores/sessionRuntimeStore.ts","./src/stores/sessionStore.test.ts","./src/stores/sessionStore.ts","./src/stores/settingsStore.test.ts","./src/stores/settingsStore.ts","./src/stores/skillStore.ts","./src/stores/tabStore.test.ts","./src/stores/tabStore.ts","./src/stores/taskStore.ts","./src/stores/teamStore.ts","./src/stores/terminalPanelStore.ts","./src/stores/uiStore.test.ts","./src/stores/uiStore.ts","./src/stores/updateStore.test.ts","./src/stores/updateStore.ts","./src/stores/workspaceChatContextStore.test.ts","./src/stores/workspaceChatContextStore.ts","./src/stores/workspacePanelStore.test.ts","./src/stores/workspacePanelStore.ts","./src/theme/globals.test.ts","./src/types/adapter.ts","./src/types/chat.ts","./src/types/cliTask.ts","./src/types/companion.ts","./src/types/mcp.ts","./src/types/memory.ts","./src/types/plugin.ts","./src/types/provider.ts","./src/types/providerPreset.ts","./src/types/qrcode.d.ts","./src/types/runtime.ts","./src/types/session.ts","./src/types/settings.ts","./src/types/skill.ts","./src/types/task.ts","./src/types/team.ts"],"errors":true,"version":"5.9.3"}
src/server/api/haha-oauth.ts CHANGED
@@ -106,7 +106,7 @@ function renderCallbackPage(success: boolean, errorMsg: string | null): string {
106
  return `<!doctype html>
107
  <html><head><meta charset="utf-8"><title>Login Success</title>
108
  <style>body{font-family:-apple-system,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#fafafa;color:#333}.card{text-align:center;padding:40px;background:white;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,.06)}h1{color:#16a34a;margin:0 0 12px}p{color:#666}</style>
109
- </head><body><div class="card"><h1>✓ Login Successful</h1><p>You can close this window and return to Claude Code Haha.</p></div>
110
  <script>setTimeout(() => window.close(), 1500)</script>
111
  </body></html>`
112
  }
 
106
  return `<!doctype html>
107
  <html><head><meta charset="utf-8"><title>Login Success</title>
108
  <style>body{font-family:-apple-system,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#fafafa;color:#333}.card{text-align:center;padding:40px;background:white;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,.06)}h1{color:#16a34a;margin:0 0 12px}p{color:#666}</style>
109
+ </head><body><div class="card"><h1>✓ Login Successful</h1><p>You can close this window and return to Versper AI Claw.</p></div>
110
  <script>setTimeout(() => window.close(), 1500)</script>
111
  </body></html>`
112
  }
src/server/api/haha-openai-oauth.ts CHANGED
@@ -101,7 +101,7 @@ function renderCallbackPage(success: boolean, errorMsg: string | null): string {
101
  return `<!doctype html>
102
  <html><head><meta charset="utf-8"><title>OpenAI Login Success</title>
103
  <style>body{font-family:-apple-system,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#fafafa;color:#333}.card{text-align:center;padding:40px;background:white;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,.06)}h1{color:#16a34a;margin:0 0 12px}p{color:#666}</style>
104
- </head><body><div class="card"><h1>✓ OpenAI Login Successful</h1><p>You can close this window and return to Claude Code Haha.</p></div>
105
  <script>setTimeout(() => window.close(), 1500)</script>
106
  </body></html>`
107
  }
 
101
  return `<!doctype html>
102
  <html><head><meta charset="utf-8"><title>OpenAI Login Success</title>
103
  <style>body{font-family:-apple-system,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#fafafa;color:#333}.card{text-align:center;padding:40px;background:white;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,.06)}h1{color:#16a34a;margin:0 0 12px}p{color:#666}</style>
104
+ </head><body><div class="card"><h1>✓ OpenAI Login Successful</h1><p>You can close this window and return to Versper AI Claw.</p></div>
105
  <script>setTimeout(() => window.close(), 1500)</script>
106
  </body></html>`
107
  }
src/server/services/desktopCliLauncherService.ts CHANGED
@@ -19,8 +19,8 @@ import { getShellConfigPaths } from '../../utils/shellConfig.js'
19
  import { getUserBinDir } from '../../utils/xdg.js'
20
 
21
  const DESKTOP_CLI_NAME = 'claude-haha'
22
- const PATH_BLOCK_START = '# >>> Claude Code Haha PATH >>>'
23
- const PATH_BLOCK_END = '# <<< Claude Code Haha PATH <<<'
24
  const WINDOWS_PATH_TARGET = 'Windows User PATH'
25
  const WINDOWS_USER_BIN_EXPR = '%USERPROFILE%\\.local\\bin'
26
 
 
19
  import { getUserBinDir } from '../../utils/xdg.js'
20
 
21
  const DESKTOP_CLI_NAME = 'claude-haha'
22
+ const PATH_BLOCK_START = '# >>> Versper AI Claw PATH >>>'
23
+ const PATH_BLOCK_END = '# <<< Versper AI Claw PATH <<<'
24
  const WINDOWS_PATH_TARGET = 'Windows User PATH'
25
  const WINDOWS_USER_BIN_EXPR = '%USERPROFILE%\\.local\\bin'
26
 
src/server/services/hahaOpenAIOAuthService.ts CHANGED
@@ -56,7 +56,7 @@ const SESSION_TTL_MS = 5 * 60 * 1000
56
  const HTML_SUCCESS = `<!doctype html>
57
  <html><head><meta charset="utf-8"><title>OpenAI Login Success</title>
58
  <style>body{font-family:-apple-system,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#fafafa;color:#333}.card{text-align:center;padding:40px;background:white;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,.06)}h1{color:#16a34a;margin:0 0 12px}p{color:#666}</style>
59
- </head><body><div class="card"><h1>OpenAI Login Successful</h1><p>You can close this window and return to Claude Code Haha.</p></div>
60
  <script>setTimeout(() => window.close(), 1500)</script>
61
  </body></html>`
62
 
 
56
  const HTML_SUCCESS = `<!doctype html>
57
  <html><head><meta charset="utf-8"><title>OpenAI Login Success</title>
58
  <style>body{font-family:-apple-system,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#fafafa;color:#333}.card{text-align:center;padding:40px;background:white;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,.06)}h1{color:#16a34a;margin:0 0 12px}p{color:#666}</style>
59
+ </head><body><div class="card"><h1>OpenAI Login Successful</h1><p>You can close this window and return to Versper AI Claw.</p></div>
60
  <script>setTimeout(() => window.close(), 1500)</script>
61
  </body></html>`
62