bingocode 1.0.3 → 1.0.4
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.
- package/package.json +1 -1
- package/desktop/README.md +0 -30
- package/desktop/bunfig.toml +0 -1
- package/desktop/index.html +0 -17
- package/desktop/package.json +0 -55
- package/desktop/pnpm-lock.yaml +0 -3832
- package/desktop/public/app-icon.jpg +0 -0
- package/desktop/public/fonts/inter-latin-ext.woff2 +0 -0
- package/desktop/public/fonts/inter-latin.woff2 +0 -0
- package/desktop/public/fonts/jetbrains-mono-latin-ext.woff2 +0 -0
- package/desktop/public/fonts/jetbrains-mono-latin.woff2 +0 -0
- package/desktop/public/fonts/manrope-latin-ext.woff2 +0 -0
- package/desktop/public/fonts/manrope-latin.woff2 +0 -0
- package/desktop/public/fonts/material-symbols-outlined.woff2 +0 -0
- package/desktop/public/icons/bilibili.svg +0 -1
- package/desktop/public/icons/douyin.svg +0 -1
- package/desktop/public/icons/github.svg +0 -3
- package/desktop/public/icons/xiaohongshu.svg +0 -1
- package/desktop/scripts/build-macos-arm64.sh +0 -270
- package/desktop/scripts/build-sidecars.ts +0 -183
- package/desktop/scripts/build-windows-x64.ps1 +0 -295
- package/desktop/scripts/scan-missing-imports.ts +0 -235
- package/desktop/sidecars/claude-sidecar.ts +0 -156
- package/desktop/src/App.tsx +0 -5
- package/desktop/src/__tests__/agentsSettings.test.tsx +0 -349
- package/desktop/src/__tests__/pages.test.tsx +0 -290
- package/desktop/src/__tests__/skillsSettings.test.tsx +0 -205
- package/desktop/src/api/adapters.ts +0 -12
- package/desktop/src/api/agents.ts +0 -36
- package/desktop/src/api/cliTasks.ts +0 -28
- package/desktop/src/api/client.ts +0 -63
- package/desktop/src/api/computerUse.ts +0 -76
- package/desktop/src/api/filesystem.ts +0 -30
- package/desktop/src/api/hahaOAuth.ts +0 -38
- package/desktop/src/api/models.ts +0 -28
- package/desktop/src/api/providers.ts +0 -63
- package/desktop/src/api/search.ts +0 -29
- package/desktop/src/api/sessions.ts +0 -56
- package/desktop/src/api/settings.ts +0 -20
- package/desktop/src/api/skills.ts +0 -19
- package/desktop/src/api/tasks.ts +0 -36
- package/desktop/src/api/teams.ts +0 -44
- package/desktop/src/api/websocket.ts +0 -164
- package/desktop/src/components/chat/AskUserQuestion.tsx +0 -268
- package/desktop/src/components/chat/AssistantMessage.tsx +0 -29
- package/desktop/src/components/chat/AttachmentGallery.tsx +0 -113
- package/desktop/src/components/chat/ChatInput.tsx +0 -622
- package/desktop/src/components/chat/CodeViewer.tsx +0 -161
- package/desktop/src/components/chat/ComputerUsePermissionModal.test.tsx +0 -174
- package/desktop/src/components/chat/ComputerUsePermissionModal.tsx +0 -311
- package/desktop/src/components/chat/DiffViewer.tsx +0 -157
- package/desktop/src/components/chat/FileSearchMenu.tsx +0 -198
- package/desktop/src/components/chat/ImageGalleryModal.tsx +0 -91
- package/desktop/src/components/chat/InlineImageGallery.tsx +0 -106
- package/desktop/src/components/chat/InlineTaskSummary.tsx +0 -60
- package/desktop/src/components/chat/MermaidRenderer.test.tsx +0 -98
- package/desktop/src/components/chat/MermaidRenderer.tsx +0 -361
- package/desktop/src/components/chat/MessageActionBar.tsx +0 -27
- package/desktop/src/components/chat/MessageList.test.tsx +0 -313
- package/desktop/src/components/chat/MessageList.tsx +0 -249
- package/desktop/src/components/chat/PermissionDialog.tsx +0 -262
- package/desktop/src/components/chat/SessionTaskBar.test.tsx +0 -99
- package/desktop/src/components/chat/SessionTaskBar.tsx +0 -159
- package/desktop/src/components/chat/StreamingIndicator.tsx +0 -41
- package/desktop/src/components/chat/TerminalChrome.tsx +0 -35
- package/desktop/src/components/chat/ThinkingBlock.tsx +0 -87
- package/desktop/src/components/chat/ToolCallBlock.tsx +0 -247
- package/desktop/src/components/chat/ToolCallGroup.tsx +0 -617
- package/desktop/src/components/chat/ToolResultBlock.tsx +0 -107
- package/desktop/src/components/chat/UserMessage.tsx +0 -38
- package/desktop/src/components/chat/chatBlocks.test.tsx +0 -136
- package/desktop/src/components/chat/clipboard.ts +0 -25
- package/desktop/src/components/chat/composerUtils.test.ts +0 -55
- package/desktop/src/components/chat/composerUtils.ts +0 -149
- package/desktop/src/components/controls/ModelSelector.tsx +0 -156
- package/desktop/src/components/controls/PermissionModeSelector.tsx +0 -229
- package/desktop/src/components/layout/AppShell.tsx +0 -107
- package/desktop/src/components/layout/ContentRouter.tsx +0 -27
- package/desktop/src/components/layout/ProjectFilter.tsx +0 -126
- package/desktop/src/components/layout/Sidebar.test.tsx +0 -158
- package/desktop/src/components/layout/Sidebar.tsx +0 -384
- package/desktop/src/components/layout/StatusBar.tsx +0 -31
- package/desktop/src/components/layout/TabBar.test.tsx +0 -136
- package/desktop/src/components/layout/TabBar.tsx +0 -318
- package/desktop/src/components/layout/TitleBar.tsx +0 -96
- package/desktop/src/components/layout/WindowControls.test.tsx +0 -69
- package/desktop/src/components/layout/WindowControls.tsx +0 -89
- package/desktop/src/components/markdown/MarkdownRenderer.test.tsx +0 -100
- package/desktop/src/components/markdown/MarkdownRenderer.tsx +0 -229
- package/desktop/src/components/settings/ClaudeOfficialLogin.tsx +0 -107
- package/desktop/src/components/shared/Button.tsx +0 -63
- package/desktop/src/components/shared/CopyButton.tsx +0 -58
- package/desktop/src/components/shared/DirectoryPicker.tsx +0 -316
- package/desktop/src/components/shared/Dropdown.tsx +0 -91
- package/desktop/src/components/shared/Input.tsx +0 -38
- package/desktop/src/components/shared/Modal.tsx +0 -65
- package/desktop/src/components/shared/ProjectContextChip.tsx +0 -30
- package/desktop/src/components/shared/Spinner.tsx +0 -30
- package/desktop/src/components/shared/Textarea.tsx +0 -38
- package/desktop/src/components/shared/Toast.tsx +0 -47
- package/desktop/src/components/shared/UpdateChecker.tsx +0 -90
- package/desktop/src/components/skills/SkillDetail.test.tsx +0 -89
- package/desktop/src/components/skills/SkillDetail.tsx +0 -403
- package/desktop/src/components/skills/SkillList.tsx +0 -254
- package/desktop/src/components/tasks/DayOfWeekPicker.tsx +0 -57
- package/desktop/src/components/tasks/NewTaskModal.tsx +0 -407
- package/desktop/src/components/tasks/PromptEditor.tsx +0 -74
- package/desktop/src/components/tasks/TaskEmptyState.tsx +0 -30
- package/desktop/src/components/tasks/TaskList.tsx +0 -46
- package/desktop/src/components/tasks/TaskRow.tsx +0 -253
- package/desktop/src/components/tasks/TaskRunsPanel.tsx +0 -195
- package/desktop/src/components/teams/TeamStatusBar.tsx +0 -147
- package/desktop/src/config/providerPresets.ts +0 -78
- package/desktop/src/config/spinnerVerbs.ts +0 -193
- package/desktop/src/hooks/useKeyboardShortcuts.ts +0 -60
- package/desktop/src/i18n/index.ts +0 -54
- package/desktop/src/i18n/locales/en.ts +0 -670
- package/desktop/src/i18n/locales/zh.ts +0 -670
- package/desktop/src/lib/__tests__/cronDescribe.test.ts +0 -93
- package/desktop/src/lib/cronDescribe.ts +0 -188
- package/desktop/src/lib/desktopRuntime.ts +0 -54
- package/desktop/src/lib/parseRunOutput.ts +0 -79
- package/desktop/src/main.tsx +0 -13
- package/desktop/src/mocks/data.ts +0 -202
- package/desktop/src/pages/ActiveSession.test.tsx +0 -181
- package/desktop/src/pages/ActiveSession.tsx +0 -219
- package/desktop/src/pages/AdapterSettings.tsx +0 -375
- package/desktop/src/pages/AgentTeams.tsx +0 -200
- package/desktop/src/pages/ComputerUseSettings.tsx +0 -420
- package/desktop/src/pages/EmptySession.tsx +0 -518
- package/desktop/src/pages/NewTaskModal.tsx +0 -346
- package/desktop/src/pages/ScheduledTasks.tsx +0 -66
- package/desktop/src/pages/ScheduledTasksEmpty.tsx +0 -152
- package/desktop/src/pages/ScheduledTasksList.tsx +0 -416
- package/desktop/src/pages/SessionControls.tsx +0 -460
- package/desktop/src/pages/Settings.tsx +0 -1448
- package/desktop/src/pages/ToolInspection.tsx +0 -235
- package/desktop/src/stores/adapterStore.ts +0 -106
- package/desktop/src/stores/agentStore.ts +0 -34
- package/desktop/src/stores/chatStore.test.ts +0 -505
- package/desktop/src/stores/chatStore.ts +0 -850
- package/desktop/src/stores/cliTaskStore.ts +0 -152
- package/desktop/src/stores/hahaOAuthStore.test.ts +0 -77
- package/desktop/src/stores/hahaOAuthStore.ts +0 -97
- package/desktop/src/stores/providerStore.ts +0 -101
- package/desktop/src/stores/sessionStore.test.ts +0 -63
- package/desktop/src/stores/sessionStore.ts +0 -102
- package/desktop/src/stores/settingsStore.ts +0 -120
- package/desktop/src/stores/skillStore.ts +0 -51
- package/desktop/src/stores/tabStore.ts +0 -169
- package/desktop/src/stores/taskStore.ts +0 -68
- package/desktop/src/stores/teamStore.ts +0 -344
- package/desktop/src/stores/uiStore.ts +0 -100
- package/desktop/src/stores/updateStore.test.ts +0 -71
- package/desktop/src/stores/updateStore.ts +0 -221
- package/desktop/src/theme/globals.css +0 -465
- package/desktop/src/types/adapter.ts +0 -33
- package/desktop/src/types/chat.ts +0 -152
- package/desktop/src/types/cliTask.ts +0 -24
- package/desktop/src/types/provider.ts +0 -62
- package/desktop/src/types/session.ts +0 -27
- package/desktop/src/types/settings.ts +0 -22
- package/desktop/src/types/skill.ts +0 -38
- package/desktop/src/types/task.ts +0 -56
- package/desktop/src/types/team.ts +0 -38
- package/desktop/src-tauri/Cargo.lock +0 -5549
- package/desktop/src-tauri/Cargo.toml +0 -20
- package/desktop/src-tauri/app-icon.svg +0 -13
- package/desktop/src-tauri/build.rs +0 -3
- package/desktop/src-tauri/capabilities/default.json +0 -106
- package/desktop/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml +0 -5
- package/desktop/src-tauri/icons/android/values/ic_launcher_background.xml +0 -4
- package/desktop/src-tauri/icons/icon.icns +0 -0
- package/desktop/src-tauri/icons/icon.ico +0 -0
- package/desktop/src-tauri/src/lib.rs +0 -408
- package/desktop/src-tauri/src/main.rs +0 -6
- package/desktop/src-tauri/tauri.conf.json +0 -78
- package/desktop/src-tauri/tauri.macos.conf.json +0 -18
- package/desktop/src-tauri/tauri.release-ci.json +0 -5
- package/desktop/src-tauri/tauri.windows.conf.json +0 -16
- package/desktop/src-tauri/windows-installer-hooks.nsh +0 -17
- package/desktop/tsconfig.json +0 -25
- package/desktop/vite.config.ts +0 -26
- package/desktop/vitest.config.ts +0 -18
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
[CmdletBinding()]
|
|
2
|
-
param(
|
|
3
|
-
[Parameter(ValueFromRemainingArguments = $true)]
|
|
4
|
-
[string[]]$TauriArgs
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
$ErrorActionPreference = 'Stop'
|
|
8
|
-
Set-StrictMode -Version Latest
|
|
9
|
-
|
|
10
|
-
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
11
|
-
$desktopDir = (Resolve-Path (Join-Path $scriptDir '..')).Path
|
|
12
|
-
$repoRoot = (Resolve-Path (Join-Path $desktopDir '..')).Path
|
|
13
|
-
|
|
14
|
-
$targetTriple = 'x86_64-pc-windows-msvc'
|
|
15
|
-
$tauriTargetDir = Join-Path $desktopDir 'src-tauri\target'
|
|
16
|
-
$canonicalOutputDir = Join-Path $desktopDir 'build-artifacts\windows-x64'
|
|
17
|
-
$activeOutputDir = $canonicalOutputDir
|
|
18
|
-
|
|
19
|
-
function Write-Step {
|
|
20
|
-
param([string]$Message)
|
|
21
|
-
Write-Host "[build-windows-x64] $Message"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function Assert-WindowsHost {
|
|
25
|
-
if ($env:OS -ne 'Windows_NT') {
|
|
26
|
-
throw '[build-windows-x64] This script must run on Windows.'
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function Assert-Command {
|
|
31
|
-
param([string]$Name)
|
|
32
|
-
|
|
33
|
-
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
|
|
34
|
-
throw "[build-windows-x64] Missing required command: $Name"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function Import-VsDevEnvironment {
|
|
39
|
-
$vswhere = 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe'
|
|
40
|
-
if (-not (Test-Path $vswhere)) {
|
|
41
|
-
throw '[build-windows-x64] Could not find vswhere.exe. Install Visual Studio 2022 Build Tools with the C++ workload.'
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
$installationPath = & $vswhere `
|
|
45
|
-
-products * `
|
|
46
|
-
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
|
|
47
|
-
-property installationPath |
|
|
48
|
-
Select-Object -First 1
|
|
49
|
-
|
|
50
|
-
if (-not $installationPath) {
|
|
51
|
-
throw '[build-windows-x64] Missing Visual C++ build tools. Install the "Desktop development with C++" / VC.Tools.x86.x64 workload first.'
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
$vsDevCmd = Join-Path $installationPath 'Common7\Tools\VsDevCmd.bat'
|
|
55
|
-
if (-not (Test-Path $vsDevCmd)) {
|
|
56
|
-
throw "[build-windows-x64] Could not find VsDevCmd.bat under $installationPath"
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
Write-Step "Importing MSVC environment from $vsDevCmd"
|
|
60
|
-
|
|
61
|
-
$env:VSCMD_SKIP_SENDTELEMETRY = '1'
|
|
62
|
-
$envDump = & cmd.exe /d /s /c "`"$vsDevCmd`" -arch=x64 -host_arch=x64 >nul && set"
|
|
63
|
-
if ($LASTEXITCODE -ne 0) {
|
|
64
|
-
throw "[build-windows-x64] Failed to initialize Visual Studio build environment (exit $LASTEXITCODE)"
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
foreach ($line in $envDump) {
|
|
68
|
-
if ($line -match '^(.*?)=(.*)$') {
|
|
69
|
-
[Environment]::SetEnvironmentVariable($matches[1], $matches[2], 'Process')
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function Get-RustCargoBinDir {
|
|
75
|
-
return Join-Path $env:USERPROFILE '.cargo\bin'
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function Ensure-RustInPath {
|
|
79
|
-
$cargoBinDir = Get-RustCargoBinDir
|
|
80
|
-
if ((Test-Path $cargoBinDir) -and -not (($env:Path -split ';') -contains $cargoBinDir)) {
|
|
81
|
-
$env:Path = "$cargoBinDir;$env:Path"
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function Get-LatestArtifact {
|
|
86
|
-
param(
|
|
87
|
-
[string[]]$SearchRoots,
|
|
88
|
-
[string[]]$Patterns
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
foreach ($root in $SearchRoots) {
|
|
92
|
-
if (-not (Test-Path $root)) {
|
|
93
|
-
continue
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
foreach ($pattern in $Patterns) {
|
|
97
|
-
$match = Get-ChildItem -Path $root -File -Filter $pattern -ErrorAction SilentlyContinue |
|
|
98
|
-
Sort-Object Name |
|
|
99
|
-
Select-Object -Last 1
|
|
100
|
-
|
|
101
|
-
if ($match) {
|
|
102
|
-
return $match
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return $null
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function Resolve-OutputDirectory {
|
|
111
|
-
param([string]$PreferredPath)
|
|
112
|
-
|
|
113
|
-
New-Item -ItemType Directory -Force -Path $PreferredPath | Out-Null
|
|
114
|
-
|
|
115
|
-
$existingArtifacts = Get-ChildItem -Path $PreferredPath -Force -ErrorAction SilentlyContinue
|
|
116
|
-
foreach ($artifact in $existingArtifacts) {
|
|
117
|
-
try {
|
|
118
|
-
Remove-Item -LiteralPath $artifact.FullName -Force -Recurse
|
|
119
|
-
} catch {
|
|
120
|
-
$fallbackPath = "$PreferredPath-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
|
121
|
-
Write-Step "Could not clear locked artifact '$($artifact.FullName)'. Using fallback output directory: $fallbackPath"
|
|
122
|
-
New-Item -ItemType Directory -Force -Path $fallbackPath | Out-Null
|
|
123
|
-
return $fallbackPath
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return $PreferredPath
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
Assert-WindowsHost
|
|
131
|
-
Assert-Command bun
|
|
132
|
-
|
|
133
|
-
Ensure-RustInPath
|
|
134
|
-
Import-VsDevEnvironment
|
|
135
|
-
|
|
136
|
-
Assert-Command cargo
|
|
137
|
-
Assert-Command rustc
|
|
138
|
-
Assert-Command bunx
|
|
139
|
-
|
|
140
|
-
if ($env:SKIP_INSTALL -ne '1') {
|
|
141
|
-
Write-Step 'Installing root dependencies...'
|
|
142
|
-
Push-Location $repoRoot
|
|
143
|
-
try {
|
|
144
|
-
& bun install
|
|
145
|
-
if ($LASTEXITCODE -ne 0) {
|
|
146
|
-
throw "[build-windows-x64] bun install failed in repo root (exit $LASTEXITCODE)"
|
|
147
|
-
}
|
|
148
|
-
} finally {
|
|
149
|
-
Pop-Location
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
Write-Step 'Installing desktop dependencies...'
|
|
153
|
-
Push-Location $desktopDir
|
|
154
|
-
try {
|
|
155
|
-
& bun install
|
|
156
|
-
if ($LASTEXITCODE -ne 0) {
|
|
157
|
-
throw "[build-windows-x64] bun install failed in desktop (exit $LASTEXITCODE)"
|
|
158
|
-
}
|
|
159
|
-
} finally {
|
|
160
|
-
Pop-Location
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
$adaptersDir = Join-Path $repoRoot 'adapters'
|
|
164
|
-
if (Test-Path (Join-Path $adaptersDir 'package.json')) {
|
|
165
|
-
Write-Step 'Installing adapter dependencies...'
|
|
166
|
-
Push-Location $adaptersDir
|
|
167
|
-
try {
|
|
168
|
-
& bun install
|
|
169
|
-
if ($LASTEXITCODE -ne 0) {
|
|
170
|
-
throw "[build-windows-x64] bun install failed in adapters (exit $LASTEXITCODE)"
|
|
171
|
-
}
|
|
172
|
-
} finally {
|
|
173
|
-
Pop-Location
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
$tauriBuildArgs = @(
|
|
179
|
-
'tauri',
|
|
180
|
-
'build',
|
|
181
|
-
'--target',
|
|
182
|
-
$targetTriple,
|
|
183
|
-
'--bundles',
|
|
184
|
-
'nsis,msi',
|
|
185
|
-
'--ci'
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
$tempConfigPath = $null
|
|
189
|
-
if (-not $env:TAURI_SIGNING_PRIVATE_KEY) {
|
|
190
|
-
$tempConfigPath = Join-Path ([System.IO.Path]::GetTempPath()) 'cc-haha.tauri.local.windows.json'
|
|
191
|
-
$tempConfig = @{
|
|
192
|
-
bundle = @{
|
|
193
|
-
createUpdaterArtifacts = $false
|
|
194
|
-
}
|
|
195
|
-
} | ConvertTo-Json -Depth 10
|
|
196
|
-
Set-Content -Path $tempConfigPath -Value $tempConfig -Encoding UTF8
|
|
197
|
-
Write-Step 'TAURI_SIGNING_PRIVATE_KEY not set, disabling updater artifacts for local build'
|
|
198
|
-
$tauriBuildArgs += @('--config', $tempConfigPath)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if ($null -ne $TauriArgs) {
|
|
202
|
-
$remainingArgs = @($TauriArgs)
|
|
203
|
-
if ($remainingArgs.Count -gt 0) {
|
|
204
|
-
$tauriBuildArgs += $remainingArgs
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
Write-Step "Building Windows desktop app for $targetTriple"
|
|
209
|
-
|
|
210
|
-
Push-Location $desktopDir
|
|
211
|
-
try {
|
|
212
|
-
$env:TAURI_ENV_TARGET_TRIPLE = $targetTriple
|
|
213
|
-
& bunx @tauriBuildArgs
|
|
214
|
-
if ($LASTEXITCODE -ne 0) {
|
|
215
|
-
throw "[build-windows-x64] tauri build failed (exit $LASTEXITCODE)"
|
|
216
|
-
}
|
|
217
|
-
} finally {
|
|
218
|
-
Pop-Location
|
|
219
|
-
if ($tempConfigPath -and (Test-Path $tempConfigPath)) {
|
|
220
|
-
Remove-Item -LiteralPath $tempConfigPath -Force
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
$activeOutputDir = Resolve-OutputDirectory -PreferredPath $canonicalOutputDir
|
|
225
|
-
|
|
226
|
-
$bundleRoots = @(
|
|
227
|
-
(Join-Path $tauriTargetDir "$targetTriple\release\bundle"),
|
|
228
|
-
(Join-Path $tauriTargetDir 'release\bundle')
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
$artifactPatterns = @('*.exe', '*.msi', '*.zip', '*.sig', 'latest.json')
|
|
232
|
-
$copiedArtifacts = New-Object System.Collections.Generic.List[string]
|
|
233
|
-
|
|
234
|
-
foreach ($root in $bundleRoots) {
|
|
235
|
-
if (-not (Test-Path $root)) {
|
|
236
|
-
continue
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
foreach ($pattern in $artifactPatterns) {
|
|
240
|
-
$artifacts = Get-ChildItem -Path $root -Recurse -File -Filter $pattern -ErrorAction SilentlyContinue
|
|
241
|
-
foreach ($artifact in $artifacts) {
|
|
242
|
-
$destination = Join-Path $activeOutputDir $artifact.Name
|
|
243
|
-
Copy-Item -LiteralPath $artifact.FullName -Destination $destination -Force
|
|
244
|
-
if (-not $copiedArtifacts.Contains($destination)) {
|
|
245
|
-
$copiedArtifacts.Add($destination) | Out-Null
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
$nsisInstaller = Get-LatestArtifact -SearchRoots @(
|
|
252
|
-
(Join-Path $tauriTargetDir "$targetTriple\release\bundle\nsis"),
|
|
253
|
-
(Join-Path $tauriTargetDir 'release\bundle\nsis')
|
|
254
|
-
) -Patterns @('*.exe')
|
|
255
|
-
|
|
256
|
-
$msiInstaller = Get-LatestArtifact -SearchRoots @(
|
|
257
|
-
(Join-Path $tauriTargetDir "$targetTriple\release\bundle\msi"),
|
|
258
|
-
(Join-Path $tauriTargetDir 'release\bundle\msi')
|
|
259
|
-
) -Patterns @('*.msi')
|
|
260
|
-
|
|
261
|
-
$nsisInstallerPath = if ($nsisInstaller) { $nsisInstaller.FullName } else { 'not found' }
|
|
262
|
-
$msiInstallerPath = if ($msiInstaller) { $msiInstaller.FullName } else { 'not found' }
|
|
263
|
-
|
|
264
|
-
$buildInfo = @(
|
|
265
|
-
"Target triple: $targetTriple"
|
|
266
|
-
"Canonical output: $canonicalOutputDir"
|
|
267
|
-
"Actual output: $activeOutputDir"
|
|
268
|
-
"NSIS installer: $nsisInstallerPath"
|
|
269
|
-
"MSI installer: $msiInstallerPath"
|
|
270
|
-
"Artifacts copied: $($copiedArtifacts.Count)"
|
|
271
|
-
"Built at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss zzz')"
|
|
272
|
-
)
|
|
273
|
-
|
|
274
|
-
Set-Content -Path (Join-Path $activeOutputDir 'BUILD_INFO.txt') -Value $buildInfo -Encoding UTF8
|
|
275
|
-
|
|
276
|
-
Write-Host ''
|
|
277
|
-
Write-Step 'Build finished.'
|
|
278
|
-
Write-Step "Artifacts output: $activeOutputDir"
|
|
279
|
-
if ($nsisInstaller) {
|
|
280
|
-
Write-Step "NSIS installer source: $($nsisInstaller.FullName)"
|
|
281
|
-
} else {
|
|
282
|
-
Write-Step 'No NSIS installer found under bundle directories.'
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if ($msiInstaller) {
|
|
286
|
-
Write-Step "MSI installer source: $($msiInstaller.FullName)"
|
|
287
|
-
} else {
|
|
288
|
-
Write-Step 'No MSI installer found under bundle directories.'
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
Write-Step "Canonical output: $canonicalOutputDir"
|
|
292
|
-
|
|
293
|
-
if ($env:OPEN_OUTPUT -eq '1') {
|
|
294
|
-
Invoke-Item $canonicalOutputDir
|
|
295
|
-
}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* scan-missing-imports.ts
|
|
3
|
-
*
|
|
4
|
-
* 在编译 sidecar 之前,扫描 src/ 里所有相对路径的 import / require / 类型 import
|
|
5
|
-
* specifier,找出磁盘上不存在的目标,给它们生成最小 stub 文件。
|
|
6
|
-
*
|
|
7
|
-
* 为什么需要:本 fork 的 src/ 大量使用 ant-internal 的 feature() macro 配
|
|
8
|
-
* dynamic require/import,gating 一堆只在 Anthropic 内部 build 才存在的源文件。
|
|
9
|
-
* bun build --compile 在 DCE 之前必须先把所有 import specifier 都 resolve 到
|
|
10
|
-
* 实际文件,找不到就直接 fail。
|
|
11
|
-
*
|
|
12
|
-
* Stub 文件内容是一个 Proxy,任何属性读、函数调用、构造调用都返回安全 noop。
|
|
13
|
-
* 由于这些代码路径都被 feature(...) === false 的 DCE 干掉了,stub 在运行时
|
|
14
|
-
* 永远不会真的被求值 —— 它只是给 resolver 的"占位符"。
|
|
15
|
-
*
|
|
16
|
-
* 生成的 stub 标记 `// @generated stub from scan-missing-imports` 让脚本可以
|
|
17
|
-
* 安全地覆写它们而不会动到真实代码。
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { readdir, stat, readFile, writeFile, mkdir } from 'node:fs/promises'
|
|
21
|
-
import { existsSync } from 'node:fs'
|
|
22
|
-
import path from 'node:path'
|
|
23
|
-
|
|
24
|
-
const repoRoot = path.resolve(import.meta.dir, '../..')
|
|
25
|
-
const srcRoot = path.join(repoRoot, 'src')
|
|
26
|
-
const adaptersRoot = path.join(repoRoot, 'adapters')
|
|
27
|
-
|
|
28
|
-
// 扫描 + 创建 stub 时允许的根目录。stub 写到这些目录之外会被拒绝,
|
|
29
|
-
// 防止意外往 node_modules / 系统路径写文件。
|
|
30
|
-
const ALLOWED_STUB_ROOTS = [srcRoot, adaptersRoot]
|
|
31
|
-
|
|
32
|
-
const STUB_MARKER_TS = '// @generated stub from scan-missing-imports'
|
|
33
|
-
const STUB_MARKER_TEXT = '<!-- @generated stub from scan-missing-imports -->'
|
|
34
|
-
|
|
35
|
-
const TS_STUB_CONTENT = `${STUB_MARKER_TS}
|
|
36
|
-
// 该文件自动生成,对应 ant-internal 的 feature() gated 模块。
|
|
37
|
-
// 所有外部 build 的代码路径在 DCE 后都不会真的执行这里的代码,这只是
|
|
38
|
-
// bun build resolver 的占位符。
|
|
39
|
-
const __target = function noop() {}
|
|
40
|
-
const __handler: ProxyHandler<any> = {
|
|
41
|
-
get(_t, prop) {
|
|
42
|
-
if (prop === '__esModule') return true
|
|
43
|
-
if (prop === 'default') return new Proxy(__target, __handler)
|
|
44
|
-
if (prop === Symbol.toPrimitive) return () => undefined
|
|
45
|
-
if (prop === Symbol.iterator) return function* () {}
|
|
46
|
-
if (prop === Symbol.asyncIterator) return async function* () {}
|
|
47
|
-
if (prop === 'then') return undefined
|
|
48
|
-
return new Proxy(__target, __handler)
|
|
49
|
-
},
|
|
50
|
-
apply() {
|
|
51
|
-
return new Proxy(__target, __handler)
|
|
52
|
-
},
|
|
53
|
-
construct() {
|
|
54
|
-
return new Proxy(__target, __handler)
|
|
55
|
-
},
|
|
56
|
-
}
|
|
57
|
-
const stub: any = new Proxy(__target, __handler)
|
|
58
|
-
export default stub
|
|
59
|
-
export const __stubMissing = true
|
|
60
|
-
// 兼容常见的命名导出 —— 没列在这里的也会通过 default Proxy 兜底
|
|
61
|
-
export const createCachedMCState = stub
|
|
62
|
-
export const isCachedMicrocompactEnabled = stub
|
|
63
|
-
export const isModelSupportedForCacheEditing = stub
|
|
64
|
-
export const getCachedMCConfig = stub
|
|
65
|
-
export const markToolsSentToAPI = stub
|
|
66
|
-
export const resetCachedMCState = stub
|
|
67
|
-
export const checkProtectedNamespace = stub
|
|
68
|
-
export const getCoordinatorUserContext = stub
|
|
69
|
-
`
|
|
70
|
-
|
|
71
|
-
// 文本类资源(.md / .txt / .json 等)通过 Bun 的 text/json loader 内联,
|
|
72
|
-
// stub 内容只要是合法的对应格式且非空即可。
|
|
73
|
-
const TEXT_STUB_CONTENT = `${STUB_MARKER_TEXT}\nstub\n`
|
|
74
|
-
const JSON_STUB_CONTENT = `{"__stubMissing": true}\n`
|
|
75
|
-
|
|
76
|
-
const TEXT_EXTS = new Set(['.md', '.markdown', '.txt'])
|
|
77
|
-
const JSON_EXTS = new Set(['.json', '.json5'])
|
|
78
|
-
|
|
79
|
-
const IMPORT_PATTERNS = [
|
|
80
|
-
// import X from './foo'
|
|
81
|
-
/from\s+['"](\.[^'"]+)['"]/g,
|
|
82
|
-
// import('./foo')
|
|
83
|
-
/import\s*\(\s*['"](\.[^'"]+)['"]/g,
|
|
84
|
-
// require('./foo')
|
|
85
|
-
/require\s*\(\s*['"](\.[^'"]+)['"]/g,
|
|
86
|
-
// import './foo' (side-effect only)
|
|
87
|
-
/import\s+['"](\.[^'"]+)['"]/g,
|
|
88
|
-
// typeof import('./foo')
|
|
89
|
-
/typeof\s+import\s*\(\s*['"](\.[^'"]+)['"]/g,
|
|
90
|
-
]
|
|
91
|
-
|
|
92
|
-
const SOURCE_EXT = new Set(['.ts', '.tsx', '.js', '.jsx', '.mts', '.cts', '.mjs', '.cjs'])
|
|
93
|
-
|
|
94
|
-
async function* walk(dir: string): AsyncGenerator<string> {
|
|
95
|
-
const entries = await readdir(dir, { withFileTypes: true })
|
|
96
|
-
for (const entry of entries) {
|
|
97
|
-
if (entry.name.startsWith('.')) continue
|
|
98
|
-
if (entry.name === 'node_modules') continue
|
|
99
|
-
if (entry.name === '__tests__') continue
|
|
100
|
-
const full = path.join(dir, entry.name)
|
|
101
|
-
if (entry.isDirectory()) {
|
|
102
|
-
yield* walk(full)
|
|
103
|
-
} else if (entry.isFile() && SOURCE_EXT.has(path.extname(entry.name))) {
|
|
104
|
-
yield full
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function resolveCandidates(importer: string, spec: string): string[] {
|
|
110
|
-
const importerDir = path.dirname(importer)
|
|
111
|
-
const base = path.resolve(importerDir, spec)
|
|
112
|
-
return [
|
|
113
|
-
base,
|
|
114
|
-
base + '.ts',
|
|
115
|
-
base + '.tsx',
|
|
116
|
-
base + '.mts',
|
|
117
|
-
base + '.cts',
|
|
118
|
-
base + '.js',
|
|
119
|
-
base + '.jsx',
|
|
120
|
-
base + '.mjs',
|
|
121
|
-
base + '.cjs',
|
|
122
|
-
base.replace(/\.(m|c)?js$/, '.ts'),
|
|
123
|
-
base.replace(/\.(m|c)?js$/, '.tsx'),
|
|
124
|
-
path.join(base, 'index.ts'),
|
|
125
|
-
path.join(base, 'index.tsx'),
|
|
126
|
-
path.join(base, 'index.js'),
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function pickStubPath(importer: string, spec: string): string {
|
|
131
|
-
const importerDir = path.dirname(importer)
|
|
132
|
-
const base = path.resolve(importerDir, spec)
|
|
133
|
-
// 把 .js 还原成 .ts —— TS 源里写 .js 是 ESM-on-Node 的惯例
|
|
134
|
-
if (base.endsWith('.js')) return base.slice(0, -3) + '.ts'
|
|
135
|
-
if (base.endsWith('.jsx')) return base.slice(0, -4) + '.tsx'
|
|
136
|
-
if (path.extname(base) === '') return base + '.ts'
|
|
137
|
-
return base
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function pickStubContent(stubPath: string): { content: string; marker: string } {
|
|
141
|
-
const ext = path.extname(stubPath).toLowerCase()
|
|
142
|
-
if (TEXT_EXTS.has(ext)) {
|
|
143
|
-
return { content: TEXT_STUB_CONTENT, marker: STUB_MARKER_TEXT }
|
|
144
|
-
}
|
|
145
|
-
if (JSON_EXTS.has(ext)) {
|
|
146
|
-
return { content: JSON_STUB_CONTENT, marker: '"__stubMissing"' }
|
|
147
|
-
}
|
|
148
|
-
return { content: TS_STUB_CONTENT, marker: STUB_MARKER_TS }
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
async function* walkRoots(roots: string[]): AsyncGenerator<string> {
|
|
152
|
-
for (const root of roots) {
|
|
153
|
-
if (!existsSync(root)) continue
|
|
154
|
-
yield* walk(root)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async function main() {
|
|
159
|
-
const missing = new Map<string, Set<string>>() // stubPath → set of importers
|
|
160
|
-
let scannedFiles = 0
|
|
161
|
-
|
|
162
|
-
for await (const file of walkRoots([srcRoot, adaptersRoot])) {
|
|
163
|
-
scannedFiles++
|
|
164
|
-
let contents: string
|
|
165
|
-
try {
|
|
166
|
-
contents = await readFile(file, 'utf8')
|
|
167
|
-
} catch {
|
|
168
|
-
continue
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
for (const pattern of IMPORT_PATTERNS) {
|
|
172
|
-
pattern.lastIndex = 0
|
|
173
|
-
let match: RegExpExecArray | null
|
|
174
|
-
while ((match = pattern.exec(contents)) !== null) {
|
|
175
|
-
const spec = match[1]!
|
|
176
|
-
if (!spec.startsWith('.')) continue
|
|
177
|
-
const candidates = resolveCandidates(file, spec)
|
|
178
|
-
let exists = false
|
|
179
|
-
for (const c of candidates) {
|
|
180
|
-
if (existsSync(c)) {
|
|
181
|
-
exists = true
|
|
182
|
-
break
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
if (exists) continue
|
|
186
|
-
const stubPath = pickStubPath(file, spec)
|
|
187
|
-
if (!missing.has(stubPath)) missing.set(stubPath, new Set())
|
|
188
|
-
missing.get(stubPath)!.add(path.relative(repoRoot, file))
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
console.log(`[scan] scanned ${scannedFiles} source files`)
|
|
194
|
-
console.log(`[scan] missing ${missing.size} stub targets`)
|
|
195
|
-
|
|
196
|
-
let createdCount = 0
|
|
197
|
-
let skippedCount = 0
|
|
198
|
-
for (const [stubPath, importers] of missing) {
|
|
199
|
-
// 安全检查:只在 ALLOWED_STUB_ROOTS(src/、adapters/)下创建,
|
|
200
|
-
// 且如果文件已存在但不是 stub 就跳过
|
|
201
|
-
const isAllowed = ALLOWED_STUB_ROOTS.some(
|
|
202
|
-
(root) => stubPath.startsWith(root + path.sep),
|
|
203
|
-
)
|
|
204
|
-
if (!isAllowed) {
|
|
205
|
-
console.warn(`[scan] skip out-of-tree stub target: ${stubPath}`)
|
|
206
|
-
continue
|
|
207
|
-
}
|
|
208
|
-
const { content, marker } = pickStubContent(stubPath)
|
|
209
|
-
if (existsSync(stubPath)) {
|
|
210
|
-
try {
|
|
211
|
-
const existing = await readFile(stubPath, 'utf8')
|
|
212
|
-
if (!existing.includes(marker) && !existing.includes(STUB_MARKER_TS)) {
|
|
213
|
-
console.warn(
|
|
214
|
-
`[scan] skip non-stub existing file: ${path.relative(repoRoot, stubPath)}`,
|
|
215
|
-
)
|
|
216
|
-
skippedCount++
|
|
217
|
-
continue
|
|
218
|
-
}
|
|
219
|
-
} catch {
|
|
220
|
-
// ignore
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
await mkdir(path.dirname(stubPath), { recursive: true })
|
|
224
|
-
await writeFile(stubPath, content, 'utf8')
|
|
225
|
-
createdCount++
|
|
226
|
-
const rel = path.relative(repoRoot, stubPath)
|
|
227
|
-
const sample = [...importers].slice(0, 2).join(', ')
|
|
228
|
-
console.log(
|
|
229
|
-
`[scan] stub: ${rel} (referenced from ${sample}${importers.size > 2 ? `, +${importers.size - 2}` : ''})`,
|
|
230
|
-
)
|
|
231
|
-
}
|
|
232
|
-
console.log(`[scan] created ${createdCount} stubs, skipped ${skippedCount}`)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
await main()
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Code 桌面端合并 sidecar 入口。
|
|
3
|
-
*
|
|
4
|
-
* 历史上 server / cli / IM adapters 是各自独立的进程。每个 bun-compile
|
|
5
|
-
* 二进制都要带一份 ~55MB 的 bun runtime,光这一项就重复占了 100MB+。
|
|
6
|
-
* 把所有运行模式合并到同一个二进制里,runtime 只保留一份;调用方通过
|
|
7
|
-
* 第一个 positional 参数选择模式:
|
|
8
|
-
*
|
|
9
|
-
* claude-sidecar server --app-root <path> --host 127.0.0.1 --port 12345
|
|
10
|
-
* claude-sidecar cli --app-root <path> [其它 CLI 参数...]
|
|
11
|
-
* claude-sidecar adapters --app-root <path> [--feishu] [--telegram]
|
|
12
|
-
*
|
|
13
|
-
* 任何模式都必须先做 process.env / process.argv 设置,再 await 进入相应的
|
|
14
|
-
* 子模块树。原因:src/server/index.ts、src/entrypoints/cli.tsx、以及
|
|
15
|
-
* adapters/feishu/index.ts 等顶层都会立即读 process.argv / process.env,
|
|
16
|
-
* 必须在它们求值前 splice 掉 --app-root、mode、--feishu/--telegram 这些
|
|
17
|
-
* launcher-only 参数。
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const rawArgs = process.argv.slice(2)
|
|
21
|
-
if (rawArgs.length === 0) {
|
|
22
|
-
console.error('claude-sidecar: missing mode argument (expected "server", "cli" or "adapters")')
|
|
23
|
-
process.exit(2)
|
|
24
|
-
}
|
|
25
|
-
const mode = rawArgs[0]!
|
|
26
|
-
const restArgs = rawArgs.slice(1)
|
|
27
|
-
|
|
28
|
-
if (mode === 'adapters') {
|
|
29
|
-
await runAdapters(restArgs)
|
|
30
|
-
} else {
|
|
31
|
-
const { appRoot, args } = parseLauncherArgs(restArgs)
|
|
32
|
-
|
|
33
|
-
process.env.CLAUDE_APP_ROOT = appRoot
|
|
34
|
-
process.env.CALLER_DIR ||= process.cwd()
|
|
35
|
-
process.argv = [process.argv[0]!, process.argv[1]!, ...args]
|
|
36
|
-
|
|
37
|
-
await import('../../preload.ts')
|
|
38
|
-
|
|
39
|
-
if (mode === 'server') {
|
|
40
|
-
const { startServer } = await import('../../src/server/index.ts')
|
|
41
|
-
startServer()
|
|
42
|
-
} else if (mode === 'cli') {
|
|
43
|
-
await import('../../src/entrypoints/cli.tsx')
|
|
44
|
-
} else {
|
|
45
|
-
console.error(`claude-sidecar: unknown mode "${mode}" (expected "server", "cli" or "adapters")`)
|
|
46
|
-
process.exit(2)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function runAdapters(rawArgs: string[]): Promise<void> {
|
|
51
|
-
// adapters 模式的参数解析独立于 server/cli —— 这里只接受 --feishu /
|
|
52
|
-
// --telegram 选择启用哪个适配器,再加可选的 --app-root(透传给
|
|
53
|
-
// adapters/common/config.ts 内的 process.env 读取)。
|
|
54
|
-
let appRoot: string | null = process.env.CLAUDE_APP_ROOT ?? null
|
|
55
|
-
let enableFeishu = false
|
|
56
|
-
let enableTelegram = false
|
|
57
|
-
|
|
58
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
59
|
-
const arg = rawArgs[i]
|
|
60
|
-
if (arg === '--app-root') {
|
|
61
|
-
appRoot = rawArgs[i + 1] ?? null
|
|
62
|
-
i += 1
|
|
63
|
-
continue
|
|
64
|
-
}
|
|
65
|
-
if (arg === '--feishu') {
|
|
66
|
-
enableFeishu = true
|
|
67
|
-
continue
|
|
68
|
-
}
|
|
69
|
-
if (arg === '--telegram') {
|
|
70
|
-
enableTelegram = true
|
|
71
|
-
continue
|
|
72
|
-
}
|
|
73
|
-
console.warn(`claude-sidecar adapters: ignoring unknown arg "${arg}"`)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (!enableFeishu && !enableTelegram) {
|
|
77
|
-
console.error(
|
|
78
|
-
'claude-sidecar adapters: must enable at least one of --feishu / --telegram',
|
|
79
|
-
)
|
|
80
|
-
process.exit(2)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (appRoot) {
|
|
84
|
-
process.env.CLAUDE_APP_ROOT = appRoot
|
|
85
|
-
}
|
|
86
|
-
process.env.CALLER_DIR ||= process.cwd()
|
|
87
|
-
|
|
88
|
-
await import('../../preload.ts')
|
|
89
|
-
|
|
90
|
-
// 在 import adapter 之前先用同一份 loadConfig() 检查凭据。adapter 的
|
|
91
|
-
// top-level 代码里已经有 if (!cred) process.exit(1),但那会把整个
|
|
92
|
-
// 进程拖死 —— 包括另一个本来正常的 adapter。这里提前 gate 一下,
|
|
93
|
-
// 缺凭据的 adapter 直接跳过、不 import。
|
|
94
|
-
const { loadConfig } = await import('../../adapters/common/config.ts')
|
|
95
|
-
const config = loadConfig()
|
|
96
|
-
|
|
97
|
-
let started = 0
|
|
98
|
-
|
|
99
|
-
if (enableFeishu) {
|
|
100
|
-
if (!config.feishu.appId || !config.feishu.appSecret) {
|
|
101
|
-
console.warn(
|
|
102
|
-
'[claude-sidecar] --feishu requested but FEISHU_APP_ID / FEISHU_APP_SECRET missing in env or ~/.claude/adapters.json — skipping',
|
|
103
|
-
)
|
|
104
|
-
} else {
|
|
105
|
-
console.log('[claude-sidecar] starting Feishu adapter')
|
|
106
|
-
// 副作用 import:feishu/index.ts 顶层会自动 new WSClient + start()
|
|
107
|
-
await import('../../adapters/feishu/index.ts')
|
|
108
|
-
started += 1
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (enableTelegram) {
|
|
113
|
-
if (!config.telegram.botToken) {
|
|
114
|
-
console.warn(
|
|
115
|
-
'[claude-sidecar] --telegram requested but TELEGRAM_BOT_TOKEN missing in env or ~/.claude/adapters.json — skipping',
|
|
116
|
-
)
|
|
117
|
-
} else {
|
|
118
|
-
console.log('[claude-sidecar] starting Telegram adapter')
|
|
119
|
-
// 副作用 import:telegram/index.ts 顶层会自动 bot.start()
|
|
120
|
-
await import('../../adapters/telegram/index.ts')
|
|
121
|
-
started += 1
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (started === 0) {
|
|
126
|
-
console.error(
|
|
127
|
-
'[claude-sidecar] no adapter could be started — check credentials in env or ~/.claude/adapters.json',
|
|
128
|
-
)
|
|
129
|
-
process.exit(1)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// 让进程保持存活:两个 adapter 都通过 long-lived WebSocket(Lark WSClient
|
|
133
|
-
// / grammY long-polling)持有 event loop,自然不会退出。这里不需要额外
|
|
134
|
-
// setInterval 兜底。两个 adapter 自己注册的 SIGINT handler 都会触发。
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function parseLauncherArgs(rawArgs: string[]): { appRoot: string; args: string[] } {
|
|
138
|
-
const nextArgs: string[] = []
|
|
139
|
-
let appRoot: string | null = process.env.CLAUDE_APP_ROOT ?? null
|
|
140
|
-
|
|
141
|
-
for (let index = 0; index < rawArgs.length; index++) {
|
|
142
|
-
const arg = rawArgs[index]
|
|
143
|
-
if (arg === '--app-root') {
|
|
144
|
-
appRoot = rawArgs[index + 1] ?? null
|
|
145
|
-
index += 1
|
|
146
|
-
continue
|
|
147
|
-
}
|
|
148
|
-
nextArgs.push(arg!)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (!appRoot) {
|
|
152
|
-
throw new Error('Missing --app-root for claude-sidecar')
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return { appRoot, args: nextArgs }
|
|
156
|
-
}
|