bingocode 1.0.26 → 1.0.28
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/config/bingo-defaults/settings.json +2 -1
- package/package.json +1 -2
- package/src/server/services/providerService.ts +104 -0
- package/src/utils/managedEnv.ts +1 -17
- package/.github/FUNDING.yml +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -44
- package/.github/ISSUE_TEMPLATE/config.yml +0 -1
- package/.github/ISSUE_TEMPLATE/question.md +0 -40
- package/.github/workflows/build-desktop-dev.yml +0 -210
- package/.github/workflows/deploy-docs.yml +0 -59
- package/.github/workflows/release-desktop.yml +0 -162
- package/.spine/user.yaml +0 -5
- package/.spine/workspace.yaml +0 -1
- package/adapters/common/__tests__/chat-queue.test.ts +0 -61
- package/adapters/common/__tests__/format.test.ts +0 -148
- package/adapters/common/__tests__/http-client.test.ts +0 -105
- package/adapters/common/__tests__/message-buffer.test.ts +0 -84
- package/adapters/common/__tests__/message-dedup.test.ts +0 -57
- package/adapters/common/__tests__/session-store.test.ts +0 -62
- package/adapters/common/__tests__/ws-bridge.test.ts +0 -177
- package/adapters/common/attachment/__tests__/attachment-limits.test.ts +0 -52
- package/adapters/common/attachment/__tests__/attachment-store.test.ts +0 -108
- package/adapters/common/attachment/__tests__/image-block-watcher.test.ts +0 -115
- package/adapters/feishu/__tests__/card-errors.test.ts +0 -194
- package/adapters/feishu/__tests__/cardkit.test.ts +0 -295
- package/adapters/feishu/__tests__/extract-payload.test.ts +0 -77
- package/adapters/feishu/__tests__/feishu.test.ts +0 -907
- package/adapters/feishu/__tests__/flush-controller.test.ts +0 -290
- package/adapters/feishu/__tests__/markdown-style.test.ts +0 -353
- package/adapters/feishu/__tests__/media.test.ts +0 -120
- package/adapters/feishu/__tests__/streaming-card.test.ts +0 -914
- package/adapters/telegram/__tests__/media.test.ts +0 -86
- package/adapters/telegram/__tests__/telegram.test.ts +0 -115
- package/adapters/tsconfig.json +0 -18
- package/bunfig.toml +0 -1
- package/preload.ts +0 -30
- package/scripts/count-app-loc.ts +0 -256
- package/scripts/release.ts +0 -130
- package/src/server/__tests__/conversation-service.test.ts +0 -173
- package/src/server/__tests__/conversations.test.ts +0 -458
- package/src/server/__tests__/cron-scheduler.test.ts +0 -575
- package/src/server/__tests__/e2e/business-flow.test.ts +0 -841
- package/src/server/__tests__/e2e/full-flow.test.ts +0 -357
- package/src/server/__tests__/fixtures/mock-sdk-cli.ts +0 -123
- package/src/server/__tests__/haha-oauth-api.test.ts +0 -146
- package/src/server/__tests__/haha-oauth-service.test.ts +0 -185
- package/src/server/__tests__/providers-real.test.ts +0 -244
- package/src/server/__tests__/providers.test.ts +0 -579
- package/src/server/__tests__/proxy-streaming.test.ts +0 -317
- package/src/server/__tests__/proxy-transform.test.ts +0 -469
- package/src/server/__tests__/real-llm-test.ts +0 -526
- package/src/server/__tests__/scheduled-tasks.test.ts +0 -371
- package/src/server/__tests__/sessions.test.ts +0 -786
- package/src/server/__tests__/settings.test.ts +0 -376
- package/src/server/__tests__/skills.test.ts +0 -125
- package/src/server/__tests__/tasks.test.ts +0 -171
- package/src/server/__tests__/team-watcher.test.ts +0 -400
- package/src/server/__tests__/teams.test.ts +0 -627
- package/src/server/middleware/cors.test.ts +0 -27
- package/src/utils/__tests__/cronFrequency.test.ts +0 -153
- package/src/utils/__tests__/cronTasks.test.ts +0 -204
- package/src/utils/computerUse/permissions.test.ts +0 -44
- package/stubs/ant-claude-for-chrome-mcp.ts +0 -24
- package/stubs/color-diff-napi.ts +0 -45
- package/tsconfig.json +0 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bingocode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claude": "bin/claude-win.cjs",
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"auto-bind": "^5.0.1",
|
|
37
37
|
"axios": "^1.14.0",
|
|
38
38
|
"bidi-js": "^1.0.3",
|
|
39
|
-
"bingocode": "^1.0.4",
|
|
40
39
|
"chalk": "^5.6.2",
|
|
41
40
|
"chokidar": "^5.0.0",
|
|
42
41
|
"cli-boxes": "^4.0.1",
|
|
@@ -263,6 +263,103 @@ export class ProviderService {
|
|
|
263
263
|
await this.writeSettings(settings)
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Sync settings.json based on the current slot table.
|
|
268
|
+
*
|
|
269
|
+
* Examines all configured slots to determine whether the CLI should connect
|
|
270
|
+
* through the local proxy or directly. If ANY slot uses a non-anthropic format
|
|
271
|
+
* (openai_chat, openai_responses), the proxy is required and settings.json is
|
|
272
|
+
* written with:
|
|
273
|
+
* - ANTHROPIC_BASE_URL → http://127.0.0.1:{port}/proxy
|
|
274
|
+
* - ANTHROPIC_AUTH_TOKEN → "proxy-managed"
|
|
275
|
+
*
|
|
276
|
+
* Model env vars (ANTHROPIC_MODEL, ANTHROPIC_DEFAULT_*_MODEL) are populated
|
|
277
|
+
* from the slot table so the CLI requests the correct model names, which the
|
|
278
|
+
* proxy's identifySlot() then routes to the right provider.
|
|
279
|
+
*
|
|
280
|
+
* If ALL configured slots use native anthropic format, we write the main
|
|
281
|
+
* slot's provider info directly (no proxy needed).
|
|
282
|
+
*
|
|
283
|
+
* If no slots are configured at all, settings.json is left unchanged.
|
|
284
|
+
*/
|
|
285
|
+
private async syncSettingsForSlots(slots: SlotTable): Promise<void> {
|
|
286
|
+
const index = await this.readIndex()
|
|
287
|
+
|
|
288
|
+
// Collect resolved slot info
|
|
289
|
+
type ResolvedSlot = { slot: SlotName; provider: SavedProvider; modelId: string; label?: string | null }
|
|
290
|
+
const resolved: ResolvedSlot[] = []
|
|
291
|
+
for (const slotName of ['main', 'haiku', 'sonnet', 'opus'] as const) {
|
|
292
|
+
const entry = slots[slotName]
|
|
293
|
+
if (!entry) continue
|
|
294
|
+
const provider = index.providers.find((p) => p.id === entry.providerId)
|
|
295
|
+
if (!provider) continue
|
|
296
|
+
resolved.push({ slot: slotName, provider, modelId: entry.modelId, label: entry.label })
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// No slots configured at all — don't touch settings.json
|
|
300
|
+
if (resolved.length === 0) return
|
|
301
|
+
|
|
302
|
+
const needsProxy = resolved.some(
|
|
303
|
+
(r) => r.provider.apiFormat != null && r.provider.apiFormat !== 'anthropic',
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
const settings = await this.readSettings()
|
|
307
|
+
const existingEnv = (settings.env as Record<string, string>) || {}
|
|
308
|
+
|
|
309
|
+
// Build model env vars from slot table.
|
|
310
|
+
//
|
|
311
|
+
// The proxy's identifySlot() routes requests by looking for keywords
|
|
312
|
+
// (haiku/sonnet/opus) in the model name the CLI sends. If the actual
|
|
313
|
+
// model ID (e.g., "deepseek-chat") doesn't contain the keyword, the
|
|
314
|
+
// proxy would misroute to "main". To fix this, we ensure the env var
|
|
315
|
+
// value always contains the slot keyword so identifySlot() can match.
|
|
316
|
+
const modelEnv: Record<string, string> = {}
|
|
317
|
+
for (const r of resolved) {
|
|
318
|
+
const rawName = r.label || r.modelId
|
|
319
|
+
switch (r.slot) {
|
|
320
|
+
case 'main':
|
|
321
|
+
modelEnv.ANTHROPIC_MODEL = rawName
|
|
322
|
+
break
|
|
323
|
+
case 'haiku': {
|
|
324
|
+
// Ensure the value contains "haiku" for identifySlot() routing
|
|
325
|
+
const name = /haiku/i.test(rawName) ? rawName : `${rawName}-haiku`
|
|
326
|
+
modelEnv.ANTHROPIC_DEFAULT_HAIKU_MODEL = name
|
|
327
|
+
break
|
|
328
|
+
}
|
|
329
|
+
case 'sonnet': {
|
|
330
|
+
const name = /sonnet/i.test(rawName) ? rawName : `${rawName}-sonnet`
|
|
331
|
+
modelEnv.ANTHROPIC_DEFAULT_SONNET_MODEL = name
|
|
332
|
+
break
|
|
333
|
+
}
|
|
334
|
+
case 'opus': {
|
|
335
|
+
const name = /opus/i.test(rawName) ? rawName : `${rawName}-opus`
|
|
336
|
+
modelEnv.ANTHROPIC_DEFAULT_OPUS_MODEL = name
|
|
337
|
+
break
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (needsProxy) {
|
|
343
|
+
settings.env = {
|
|
344
|
+
...existingEnv,
|
|
345
|
+
ANTHROPIC_BASE_URL: `http://127.0.0.1:${ProviderService.serverPort}/proxy`,
|
|
346
|
+
ANTHROPIC_AUTH_TOKEN: 'proxy-managed',
|
|
347
|
+
...modelEnv,
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
// All slots are native anthropic — use main slot's provider directly
|
|
351
|
+
const mainSlot = resolved.find((r) => r.slot === 'main') || resolved[0]
|
|
352
|
+
settings.env = {
|
|
353
|
+
...existingEnv,
|
|
354
|
+
ANTHROPIC_BASE_URL: mainSlot.provider.baseUrl,
|
|
355
|
+
ANTHROPIC_AUTH_TOKEN: mainSlot.provider.apiKey,
|
|
356
|
+
...modelEnv,
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
await this.writeSettings(settings)
|
|
361
|
+
}
|
|
362
|
+
|
|
266
363
|
// --- Auth status ---
|
|
267
364
|
|
|
268
365
|
/**
|
|
@@ -356,6 +453,13 @@ export class ProviderService {
|
|
|
356
453
|
const slots = await this.readSlots()
|
|
357
454
|
slots[slot] = entry
|
|
358
455
|
await this.writeSlots(slots)
|
|
456
|
+
|
|
457
|
+
// Auto-sync settings.json so the CLI knows where to connect.
|
|
458
|
+
// When any slot uses a non-anthropic provider, the CLI must go through
|
|
459
|
+
// the local proxy; when all slots are anthropic (or empty), we can
|
|
460
|
+
// write direct provider info instead.
|
|
461
|
+
await this.syncSettingsForSlots(slots)
|
|
462
|
+
|
|
359
463
|
return slots
|
|
360
464
|
}
|
|
361
465
|
|
package/src/utils/managedEnv.ts
CHANGED
|
@@ -109,23 +109,7 @@ function getBingoSettingsEnv(): Record<string, string> {
|
|
|
109
109
|
try {
|
|
110
110
|
const raw = readFileSync(settingsPath, 'utf-8')
|
|
111
111
|
const parsed = JSON.parse(raw) as { env?: Record<string, string> }
|
|
112
|
-
if (parsed.env)
|
|
113
|
-
const env = { ...parsed.env }
|
|
114
|
-
// The packaged placeholder settings.json uses a sentinel token
|
|
115
|
-
// ("pending-provider-setup") to prevent isOfficialMode() from
|
|
116
|
-
// returning true (which would trigger the OAuth flow on new
|
|
117
|
-
// computers before a provider is activated). However, the
|
|
118
|
-
// accompanying ANTHROPIC_BASE_URL (e.g. http://127.0.0.1:3456)
|
|
119
|
-
// must NOT be injected into process.env — it would cause a
|
|
120
|
-
// FailedToOpenSocket error when no local server is running.
|
|
121
|
-
// Strip ANTHROPIC_BASE_URL when the token is still the sentinel;
|
|
122
|
-
// the token itself is kept so isAnthropicAuthEnabled() returns
|
|
123
|
-
// false (preventing OAuth).
|
|
124
|
-
if (env.ANTHROPIC_AUTH_TOKEN === 'pending-provider-setup') {
|
|
125
|
-
delete env.ANTHROPIC_BASE_URL
|
|
126
|
-
}
|
|
127
|
-
return env
|
|
128
|
-
}
|
|
112
|
+
if (parsed.env) return parsed.env
|
|
129
113
|
} catch {
|
|
130
114
|
continue
|
|
131
115
|
}
|
package/.github/FUNDING.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
github: NanmiCoder
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Bug 反馈
|
|
3
|
-
about: 创建一个 Bug 报告以帮助 cc-haha 项目改进
|
|
4
|
-
title: '[BUG] '
|
|
5
|
-
labels: bug
|
|
6
|
-
assignees: ''
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 🔍 问题检查清单
|
|
10
|
-
<!-- 请在提交 issue 前确认以下事项 -->
|
|
11
|
-
|
|
12
|
-
- [ ] 我已经仔细阅读了 [README 常见问题](https://github.com/NanmiCoder/cc-haha#常见问题) 部分
|
|
13
|
-
- [ ] 我已经搜索并查看了[已关闭的 issues](https://github.com/NanmiCoder/cc-haha/issues?q=is%3Aissue+is%3Aclosed)
|
|
14
|
-
- [ ] 我确认这不是由于 API Key 配置错误、API 端点不兼容、Bun 版本过低等常见原因导致的问题
|
|
15
|
-
|
|
16
|
-
## 🐛 问题描述
|
|
17
|
-
<!-- 请详细描述你遇到的问题 -->
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## 📝 复现步骤
|
|
21
|
-
1.
|
|
22
|
-
2.
|
|
23
|
-
3.
|
|
24
|
-
|
|
25
|
-
## 💻 运行环境
|
|
26
|
-
- 操作系统:
|
|
27
|
-
- Bun 版本 (`bun --version`):
|
|
28
|
-
- Node 版本 (`node --version`):
|
|
29
|
-
- API 提供商 (如 MiniMax / OpenRouter / Anthropic 官方等):
|
|
30
|
-
- 使用的模型:
|
|
31
|
-
- 启动方式 (TUI / --print / Recovery CLI):
|
|
32
|
-
|
|
33
|
-
## 📋 错误日志
|
|
34
|
-
<!-- 请提供完整的错误日志信息 -->
|
|
35
|
-
```shell
|
|
36
|
-
在此粘贴错误日志
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## 📷 错误截图
|
|
40
|
-
<!-- 如有,请提供错误截图 -->
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
<!-- 🤖 Dosu 机器人将自动响应此 issue -->
|
|
44
|
-
@dosubot
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
blank_issues_enabled: false
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: 使用问题咨询
|
|
3
|
-
about: 提交使用过程中遇到的问题
|
|
4
|
-
title: '[问题] '
|
|
5
|
-
labels: question
|
|
6
|
-
assignees: ''
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## ⚠️ 提交前确认
|
|
10
|
-
<!-- 请确认以下事项 -->
|
|
11
|
-
- [ ] 我已经仔细阅读了 [README 常见问题](https://github.com/NanmiCoder/cc-haha#常见问题) 部分
|
|
12
|
-
- [ ] 我已经阅读了[第三方模型使用指南](https://github.com/NanmiCoder/cc-haha/blob/main/docs/guide/third-party-models.md)
|
|
13
|
-
- [ ] 我已经搜索并查看了[已关闭的 issues](https://github.com/NanmiCoder/cc-haha/issues?q=is%3Aissue+is%3Aclosed)
|
|
14
|
-
|
|
15
|
-
## ❓ 问题描述
|
|
16
|
-
<!-- 清晰简洁地描述你遇到的问题 -->
|
|
17
|
-
|
|
18
|
-
## 🔍 使用场景
|
|
19
|
-
<!-- 描述你在使用哪个功能时遇到的问题 -->
|
|
20
|
-
- 使用功能: (如:TUI 交互 / --print 无头模式 / MCP 服务器 / Skills 等)
|
|
21
|
-
- API 提供商: (如:MiniMax / OpenRouter / Anthropic 官方 / LiteLLM 代理等)
|
|
22
|
-
|
|
23
|
-
## 💻 环境信息
|
|
24
|
-
- 操作系统:
|
|
25
|
-
- Bun 版本 (`bun --version`):
|
|
26
|
-
- Node 版本 (`node --version`):
|
|
27
|
-
- API 提供商:
|
|
28
|
-
- 使用的模型:
|
|
29
|
-
|
|
30
|
-
## 📋 错误日志
|
|
31
|
-
```shell
|
|
32
|
-
在此粘贴完整的错误日志
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## 📷 错误截图
|
|
36
|
-
<!-- 如有,请提供错误截图 -->
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
<!-- 🤖 Dosu 机器人将自动响应此 issue -->
|
|
40
|
-
@dosubot
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
name: Build Desktop (Dev)
|
|
2
|
-
|
|
3
|
-
# 开发阶段构建 — 不创建 Release,只上传 Artifacts 供下载测试
|
|
4
|
-
on:
|
|
5
|
-
workflow_dispatch:
|
|
6
|
-
inputs:
|
|
7
|
-
platforms:
|
|
8
|
-
description: 'Build platforms'
|
|
9
|
-
required: true
|
|
10
|
-
default: 'all'
|
|
11
|
-
type: choice
|
|
12
|
-
options:
|
|
13
|
-
- all
|
|
14
|
-
- macos-arm64
|
|
15
|
-
- macos-x64
|
|
16
|
-
- windows-x64
|
|
17
|
-
- linux-x64
|
|
18
|
-
- linux-arm64
|
|
19
|
-
|
|
20
|
-
permissions:
|
|
21
|
-
contents: read
|
|
22
|
-
|
|
23
|
-
concurrency:
|
|
24
|
-
group: build-desktop-dev-${{ github.ref }}
|
|
25
|
-
cancel-in-progress: true
|
|
26
|
-
|
|
27
|
-
jobs:
|
|
28
|
-
# ── 动态生成构建矩阵 ──────────────────────────────────────
|
|
29
|
-
prepare:
|
|
30
|
-
runs-on: ubuntu-latest
|
|
31
|
-
outputs:
|
|
32
|
-
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
33
|
-
steps:
|
|
34
|
-
- id: set-matrix
|
|
35
|
-
run: |
|
|
36
|
-
ALL='[{"platform":"macos-latest","rust_target":"aarch64-apple-darwin","tauri_args":"--target aarch64-apple-darwin","bundles":"app,dmg","label":"macOS-ARM64","artifact_name":"macos-arm64"},{"platform":"macos-latest","rust_target":"x86_64-apple-darwin","tauri_args":"--target x86_64-apple-darwin","bundles":"app,dmg","label":"macOS-x64","artifact_name":"macos-x64"},{"platform":"windows-latest","rust_target":"x86_64-pc-windows-msvc","tauri_args":"","bundles":"nsis,msi","label":"Windows-x64","artifact_name":"windows-x64"},{"platform":"ubuntu-22.04","rust_target":"x86_64-unknown-linux-gnu","tauri_args":"","bundles":"deb","label":"Linux-x64","artifact_name":"linux-x64"},{"platform":"ubuntu-22.04-arm","rust_target":"aarch64-unknown-linux-gnu","tauri_args":"","bundles":"deb","label":"Linux-ARM64","artifact_name":"linux-arm64"}]'
|
|
37
|
-
|
|
38
|
-
SELECTED="${{ inputs.platforms }}"
|
|
39
|
-
if [ "$SELECTED" = "all" ]; then
|
|
40
|
-
MATRIX=$(echo "$ALL" | jq -c '{include: .}')
|
|
41
|
-
else
|
|
42
|
-
MATRIX=$(echo "$ALL" | jq -c --arg sel "$SELECTED" '{include: [.[] | select(
|
|
43
|
-
($sel == "macos-arm64" and .label == "macOS-ARM64") or
|
|
44
|
-
($sel == "macos-x64" and .label == "macOS-x64") or
|
|
45
|
-
($sel == "windows-x64" and .label == "Windows-x64") or
|
|
46
|
-
($sel == "linux-x64" and .label == "Linux-x64") or
|
|
47
|
-
($sel == "linux-arm64" and .label == "Linux-ARM64")
|
|
48
|
-
)]}')
|
|
49
|
-
fi
|
|
50
|
-
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
|
|
51
|
-
|
|
52
|
-
# ── 构建 ────────────────────────────────────────────────────
|
|
53
|
-
build:
|
|
54
|
-
needs: prepare
|
|
55
|
-
strategy:
|
|
56
|
-
fail-fast: false
|
|
57
|
-
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
|
|
58
|
-
|
|
59
|
-
runs-on: ${{ matrix.platform }}
|
|
60
|
-
name: Build (${{ matrix.label }})
|
|
61
|
-
|
|
62
|
-
steps:
|
|
63
|
-
- name: Checkout
|
|
64
|
-
uses: actions/checkout@v4
|
|
65
|
-
|
|
66
|
-
# ── 读取版本号 ───────────────────────────────────────────
|
|
67
|
-
- name: Read version
|
|
68
|
-
id: version
|
|
69
|
-
shell: bash
|
|
70
|
-
run: |
|
|
71
|
-
VERSION=$(jq -r '.version' desktop/src-tauri/tauri.conf.json)
|
|
72
|
-
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
73
|
-
|
|
74
|
-
# ── 系统依赖 (Linux) ─────────────────────────────────────
|
|
75
|
-
# libfuse2 是 AppImage 运行时依赖:linuxdeploy 工具链本身是 AppImage 格式,
|
|
76
|
-
# 运行时需要 libfuse2,Ubuntu 22.04 默认未安装。
|
|
77
|
-
- name: Install Linux dependencies
|
|
78
|
-
if: contains(matrix.platform, 'ubuntu')
|
|
79
|
-
run: |
|
|
80
|
-
sudo apt-get update
|
|
81
|
-
sudo apt-get install -y \
|
|
82
|
-
build-essential curl wget file \
|
|
83
|
-
libxdo-dev libssl-dev \
|
|
84
|
-
libwebkit2gtk-4.1-dev \
|
|
85
|
-
libayatana-appindicator3-dev \
|
|
86
|
-
librsvg2-dev patchelf \
|
|
87
|
-
libfuse2
|
|
88
|
-
|
|
89
|
-
# ── Bun ──────────────────────────────────────────────────
|
|
90
|
-
- name: Setup Bun
|
|
91
|
-
uses: oven-sh/setup-bun@v2
|
|
92
|
-
with:
|
|
93
|
-
bun-version: latest
|
|
94
|
-
|
|
95
|
-
# ── Node.js ──────────────────────────────────────────────
|
|
96
|
-
- name: Setup Node.js
|
|
97
|
-
uses: actions/setup-node@v4
|
|
98
|
-
with:
|
|
99
|
-
node-version: 20
|
|
100
|
-
|
|
101
|
-
# ── Rust ─────────────────────────────────────────────────
|
|
102
|
-
- name: Setup Rust
|
|
103
|
-
uses: dtolnay/rust-toolchain@stable
|
|
104
|
-
with:
|
|
105
|
-
targets: ${{ matrix.rust_target }}
|
|
106
|
-
|
|
107
|
-
- name: Rust cache
|
|
108
|
-
uses: swatinem/rust-cache@v2
|
|
109
|
-
with:
|
|
110
|
-
workspaces: 'desktop/src-tauri -> target'
|
|
111
|
-
shared-key: ${{ matrix.rust_target }}
|
|
112
|
-
|
|
113
|
-
# ── 安装依赖 ─────────────────────────────────────────────
|
|
114
|
-
- name: Install root dependencies
|
|
115
|
-
run: bun install
|
|
116
|
-
|
|
117
|
-
- name: Install desktop dependencies
|
|
118
|
-
working-directory: desktop
|
|
119
|
-
run: bun install
|
|
120
|
-
|
|
121
|
-
- name: Install adapter dependencies
|
|
122
|
-
working-directory: adapters
|
|
123
|
-
run: bun install
|
|
124
|
-
|
|
125
|
-
# ── 构建 sidecars ────────────────────────────────────────
|
|
126
|
-
- name: Build sidecars
|
|
127
|
-
working-directory: desktop
|
|
128
|
-
env:
|
|
129
|
-
TAURI_ENV_TARGET_TRIPLE: ${{ matrix.rust_target }}
|
|
130
|
-
run: bun run build:sidecars
|
|
131
|
-
|
|
132
|
-
# ── 构建 Tauri (无签名、无 updater) ──────────────────────
|
|
133
|
-
- name: Build Tauri app
|
|
134
|
-
working-directory: desktop
|
|
135
|
-
env:
|
|
136
|
-
TAURI_ENV_TARGET_TRIPLE: ${{ matrix.rust_target }}
|
|
137
|
-
run: |
|
|
138
|
-
# 开发构建: 禁用 updater artifacts (不需要签名密钥)
|
|
139
|
-
echo '{"bundle":{"createUpdaterArtifacts":false}}' > /tmp/dev-build.json
|
|
140
|
-
|
|
141
|
-
ARGS=(bunx tauri build --bundles ${{ matrix.bundles }} --ci --config /tmp/dev-build.json)
|
|
142
|
-
|
|
143
|
-
if [ -n "${{ matrix.tauri_args }}" ]; then
|
|
144
|
-
ARGS+=(${{ matrix.tauri_args }})
|
|
145
|
-
fi
|
|
146
|
-
|
|
147
|
-
"${ARGS[@]}"
|
|
148
|
-
shell: bash
|
|
149
|
-
|
|
150
|
-
# ── 收集产物 ─────────────────────────────────────────────
|
|
151
|
-
- name: Collect artifacts
|
|
152
|
-
id: collect
|
|
153
|
-
shell: bash
|
|
154
|
-
run: |
|
|
155
|
-
BUNDLE_DIR="desktop/src-tauri/target/${{ matrix.rust_target }}/release/bundle"
|
|
156
|
-
FALLBACK_DIR="desktop/src-tauri/target/release/bundle"
|
|
157
|
-
|
|
158
|
-
# 优先使用带 target 的路径
|
|
159
|
-
if [ -d "$BUNDLE_DIR" ]; then
|
|
160
|
-
SEARCH_DIR="$BUNDLE_DIR"
|
|
161
|
-
else
|
|
162
|
-
SEARCH_DIR="$FALLBACK_DIR"
|
|
163
|
-
fi
|
|
164
|
-
|
|
165
|
-
STAGING="desktop/build-artifacts/ci-Claude-Code-Haha-v${{ steps.version.outputs.version }}-${{ matrix.artifact_name }}"
|
|
166
|
-
mkdir -p "$STAGING"
|
|
167
|
-
|
|
168
|
-
echo "Searching for artifacts in: $SEARCH_DIR"
|
|
169
|
-
if [ -d "$SEARCH_DIR" ]; then
|
|
170
|
-
find "$SEARCH_DIR" \
|
|
171
|
-
\( -type f \( \
|
|
172
|
-
-name "*.dmg" -o -name "*.exe" -o -name "*.msi" -o \
|
|
173
|
-
-name "*.deb" -o -name "*.AppImage" -o -name "*.zip" \
|
|
174
|
-
\) \) -o \
|
|
175
|
-
\( -type d -name "*.app" \) | while read -r f; do
|
|
176
|
-
echo " Copying: $(basename "$f")"
|
|
177
|
-
cp -R "$f" "$STAGING/"
|
|
178
|
-
done
|
|
179
|
-
fi
|
|
180
|
-
|
|
181
|
-
echo "staging_dir=$STAGING" >> "$GITHUB_OUTPUT"
|
|
182
|
-
echo "=== Collected artifacts ==="
|
|
183
|
-
ls -lh "$STAGING/" 2>/dev/null || echo "(empty)"
|
|
184
|
-
|
|
185
|
-
# ── 上传为 GitHub Artifact ───────────────────────────────
|
|
186
|
-
- name: Upload artifacts
|
|
187
|
-
uses: actions/upload-artifact@v4
|
|
188
|
-
with:
|
|
189
|
-
name: Claude-Code-Haha-v${{ steps.version.outputs.version }}-${{ matrix.artifact_name }}
|
|
190
|
-
path: ${{ steps.collect.outputs.staging_dir }}
|
|
191
|
-
retention-days: 7
|
|
192
|
-
if-no-files-found: warn
|
|
193
|
-
|
|
194
|
-
# ── 构建完成汇总 ────────────────────────────────────────────
|
|
195
|
-
summary:
|
|
196
|
-
needs: build
|
|
197
|
-
runs-on: ubuntu-latest
|
|
198
|
-
if: always()
|
|
199
|
-
steps:
|
|
200
|
-
- name: Build summary
|
|
201
|
-
run: |
|
|
202
|
-
echo "## Desktop Dev Build Summary" >> $GITHUB_STEP_SUMMARY
|
|
203
|
-
echo "" >> $GITHUB_STEP_SUMMARY
|
|
204
|
-
echo "| Platform | Status |" >> $GITHUB_STEP_SUMMARY
|
|
205
|
-
echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
|
|
206
|
-
echo "Branch: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
|
|
207
|
-
echo "Commit: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
|
|
208
|
-
echo "" >> $GITHUB_STEP_SUMMARY
|
|
209
|
-
echo "📦 Artifacts are available for download from the **Artifacts** section above." >> $GITHUB_STEP_SUMMARY
|
|
210
|
-
echo "Artifacts will be retained for **7 days**." >> $GITHUB_STEP_SUMMARY
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
name: Deploy VitePress Docs
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
paths:
|
|
7
|
-
- 'docs/**'
|
|
8
|
-
- 'package.json'
|
|
9
|
-
- '.github/workflows/deploy-docs.yml'
|
|
10
|
-
workflow_dispatch:
|
|
11
|
-
|
|
12
|
-
permissions:
|
|
13
|
-
contents: read
|
|
14
|
-
pages: write
|
|
15
|
-
id-token: write
|
|
16
|
-
|
|
17
|
-
concurrency:
|
|
18
|
-
group: pages
|
|
19
|
-
cancel-in-progress: true
|
|
20
|
-
|
|
21
|
-
jobs:
|
|
22
|
-
build:
|
|
23
|
-
runs-on: ubuntu-latest
|
|
24
|
-
steps:
|
|
25
|
-
- name: Checkout
|
|
26
|
-
uses: actions/checkout@v4
|
|
27
|
-
with:
|
|
28
|
-
fetch-depth: 0
|
|
29
|
-
|
|
30
|
-
- name: Setup Node
|
|
31
|
-
uses: actions/setup-node@v4
|
|
32
|
-
with:
|
|
33
|
-
node-version: 20
|
|
34
|
-
cache: npm
|
|
35
|
-
|
|
36
|
-
- name: Setup Pages
|
|
37
|
-
uses: actions/configure-pages@v4
|
|
38
|
-
|
|
39
|
-
- name: Install dependencies
|
|
40
|
-
run: npm ci
|
|
41
|
-
|
|
42
|
-
- name: Build with VitePress
|
|
43
|
-
run: npm run docs:build
|
|
44
|
-
|
|
45
|
-
- name: Upload artifact
|
|
46
|
-
uses: actions/upload-pages-artifact@v3
|
|
47
|
-
with:
|
|
48
|
-
path: docs/.vitepress/dist
|
|
49
|
-
|
|
50
|
-
deploy:
|
|
51
|
-
environment:
|
|
52
|
-
name: github-pages
|
|
53
|
-
url: ${{ steps.deployment.outputs.page_url }}
|
|
54
|
-
needs: build
|
|
55
|
-
runs-on: ubuntu-latest
|
|
56
|
-
steps:
|
|
57
|
-
- name: Deploy to GitHub Pages
|
|
58
|
-
id: deployment
|
|
59
|
-
uses: actions/deploy-pages@v4
|