@seemseam/ccb 8.4.3 → 8.5.0
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/README/ar.md +3 -3
- package/README/de.md +3 -3
- package/README/es.md +3 -3
- package/README/fr.md +3 -3
- package/README/ja.md +3 -3
- package/README/ko.md +3 -3
- package/README/pt.md +3 -3
- package/README/ru.md +3 -3
- package/README/zh.md +15 -3
- package/README.md +15 -3
- package/VERSION +1 -1
- package/bin/ccb-npm-install.js +185 -10
- package/package.json +1 -1
package/README/ar.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**نسّق Codex وClaude وGemini وغيرهم من وكلاء CLI ضمن سير عمل مرئي وقابل للتحكم والتدخل المباشر**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ ccb update mobile
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>تفاصيل Mobile App وحدود الأمان والمصدر</b></summary>
|
|
184
184
|
|
|
185
|
-
يتضمن CCB 8.
|
|
185
|
+
يتضمن CCB 8.5.0 مصدر Flutter الخاص بـ CCB Mobile داخل [`mobile/`](../mobile/) وينشر Android APK عبر GitHub Releases:
|
|
186
186
|
|
|
187
|
-
- [تنزيل CCB Mobile v8.
|
|
187
|
+
- [تنزيل CCB Mobile v8.5.0 APK](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- مصدر التطبيق: [`mobile/app`](../mobile/app)
|
|
189
189
|
- مصدر gateway الخادم: [`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/de.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Koordiniere Codex, Claude, Gemini und andere CLI-Agenten in sichtbaren, steuerbaren Workflows, die du direkt uebernehmen kannst**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ Dieser Befehl fuehrt durch Installation und Konfiguration.
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>Mobile-App-Details, Sicherheitsgrenze und Source</b></summary>
|
|
184
184
|
|
|
185
|
-
CCB 8.
|
|
185
|
+
CCB 8.5.0 enthaelt den Flutter-Quellcode von CCB Mobile in [`mobile/`](../mobile/) und veroeffentlicht das Android APK ueber GitHub Releases:
|
|
186
186
|
|
|
187
|
-
- [CCB Mobile v8.
|
|
187
|
+
- [CCB Mobile v8.5.0 APK herunterladen](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- App-Source: [`mobile/app`](../mobile/app)
|
|
189
189
|
- Server-gateway-Source: [`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/es.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Coordina Codex, Claude, Gemini y otros agentes CLI en flujos visibles y controlables que puedes tomar directamente**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ Este comando guía la instalación y configuración.
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>Detalles de Mobile App, límite de seguridad y fuente</b></summary>
|
|
184
184
|
|
|
185
|
-
CCB 8.
|
|
185
|
+
CCB 8.5.0 incluye el código Flutter de CCB Mobile en [`mobile/`](../mobile/) y publica el APK Android mediante GitHub Releases:
|
|
186
186
|
|
|
187
|
-
- [Descargar CCB Mobile v8.
|
|
187
|
+
- [Descargar CCB Mobile v8.5.0 APK](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- Fuente de la app: [`mobile/app`](../mobile/app)
|
|
189
189
|
- Fuente del gateway del servidor: [`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/fr.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Coordonne Codex, Claude, Gemini et d'autres agents CLI dans des workflows visibles, contrôlables et reprenables directement**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ Cette commande guide l'installation et la configuration.
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>Détails de l'app mobile, frontière de sécurité et source</b></summary>
|
|
184
184
|
|
|
185
|
-
CCB 8.
|
|
185
|
+
CCB 8.5.0 inclut le code source Flutter de CCB Mobile dans [`mobile/`](../mobile/) et publie l'APK Android via GitHub Releases :
|
|
186
186
|
|
|
187
|
-
- [Télécharger l'APK CCB Mobile v8.
|
|
187
|
+
- [Télécharger l'APK CCB Mobile v8.5.0](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- Source de l'app : [`mobile/app`](../mobile/app)
|
|
189
189
|
- Source du gateway serveur : [`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/ja.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Codex、Claude、Gemini などの CLI Agent を、見える・制御できる・直接引き継げるワークフローで連携**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ ccb update mobile
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>Mobile App の詳細、安全境界、ソース</b></summary>
|
|
184
184
|
|
|
185
|
-
CCB 8.
|
|
185
|
+
CCB 8.5.0 では Flutter 版 CCB Mobile のソースが [`mobile/`](../mobile/) に含まれ、Android APK は GitHub Releases で公開されています。
|
|
186
186
|
|
|
187
|
-
- [CCB Mobile v8.
|
|
187
|
+
- [CCB Mobile v8.5.0 APK をダウンロード](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- App ソース:[`mobile/app`](../mobile/app)
|
|
189
189
|
- サーバー gateway ソース:[`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/ko.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Codex, Claude, Gemini 등 CLI Agent를 보이고 제어 가능하며 직접 이어받을 수 있는 워크플로로 조율**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ ccb update mobile
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>Mobile App 세부 정보, 안전 경계, 소스</b></summary>
|
|
184
184
|
|
|
185
|
-
CCB 8.
|
|
185
|
+
CCB 8.5.0은 Flutter CCB Mobile 소스를 [`mobile/`](../mobile/)에 포함하며 Android APK를 GitHub Releases로 배포합니다.
|
|
186
186
|
|
|
187
|
-
- [CCB Mobile v8.
|
|
187
|
+
- [CCB Mobile v8.5.0 APK 다운로드](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- 앱 소스: [`mobile/app`](../mobile/app)
|
|
189
189
|
- 서버 gateway 소스: [`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/pt.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Coordene Codex, Claude, Gemini e outros agentes CLI em fluxos visíveis e controláveis que você pode assumir diretamente**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ Esse comando orienta a instalação e a configuração.
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>Detalhes do Mobile App, limite de segurança e fonte</b></summary>
|
|
184
184
|
|
|
185
|
-
O CCB 8.
|
|
185
|
+
O CCB 8.5.0 inclui o código Flutter do CCB Mobile em [`mobile/`](../mobile/) e publica o APK Android pelo GitHub Releases:
|
|
186
186
|
|
|
187
|
-
- [Baixar CCB Mobile v8.
|
|
187
|
+
- [Baixar CCB Mobile v8.5.0 APK](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- Fonte do app: [`mobile/app`](../mobile/app)
|
|
189
189
|
- Fonte do gateway servidor: [`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/ru.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Координируйте Codex, Claude, Gemini и другие CLI Agent в видимых и управляемых процессах, которые можно напрямую взять под контроль**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -182,9 +182,9 @@ ccb update mobile
|
|
|
182
182
|
<details>
|
|
183
183
|
<summary><b>Детали Mobile App, граница безопасности и исходники</b></summary>
|
|
184
184
|
|
|
185
|
-
CCB 8.
|
|
185
|
+
CCB 8.5.0 включает Flutter source CCB Mobile в [`mobile/`](../mobile/) и публикует Android APK через GitHub Releases:
|
|
186
186
|
|
|
187
|
-
- [Скачать CCB Mobile v8.
|
|
187
|
+
- [Скачать CCB Mobile v8.5.0 APK](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
188
188
|
- Исходники app: [`mobile/app`](../mobile/app)
|
|
189
189
|
- Исходники server gateway: [`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
190
190
|
|
package/README/zh.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**让 Codex、Claude、Gemini 等 CLI Agent 可见、可控、可接管地协同工作**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -211,9 +211,9 @@ ccb update mobile
|
|
|
211
211
|
<details>
|
|
212
212
|
<summary><b>Mobile App 详情、安全边界和源码</b></summary>
|
|
213
213
|
|
|
214
|
-
CCB 8.
|
|
214
|
+
CCB 8.5.0 已把 Flutter 版 CCB Mobile 源码放入 [`mobile/`](../mobile/),并在 GitHub Release 中发布 Android APK:
|
|
215
215
|
|
|
216
|
-
- [下载 CCB Mobile v8.
|
|
216
|
+
- [下载 CCB Mobile v8.5.0 APK](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
217
217
|
- App 源码:[`mobile/app`](../mobile/app)
|
|
218
218
|
- 服务端 gateway 源码:[`lib/mobile_gateway`](../lib/mobile_gateway)
|
|
219
219
|
|
|
@@ -300,6 +300,18 @@ CCB 支持 [Agent Roles Spec](https://github.com/SeemSeam/agent-roles-spec):
|
|
|
300
300
|
## 新版本记录
|
|
301
301
|
|
|
302
302
|
<details open>
|
|
303
|
+
<summary><b>v8.5.0</b> - 精确 Pi/OMP 终止、自修复 npm 运行时、同步 Mobile 活动与更安全的托管资源</summary>
|
|
304
|
+
|
|
305
|
+
- 将 Pi 完成信号绑定到最新的 `agent_settled`,将 OMP 完成信号绑定到 `agent_end.isTerminal=true`,并在进程退出且输出关闭后才进入终态。
|
|
306
|
+
- 对缺少原生终止证据、缺少最终结果、JSONL 损坏或截断、Provider 错误和非零退出安全拒绝;OMP 的终态 `yield` 仍作为受支持的成功结果。
|
|
307
|
+
- 安装时自动创建并修复 npm 托管 Python 环境,正式版运行依赖不再依靠不完整的系统 Python 兜底;linked Git worktree 仍会被正确识别为源码安装。
|
|
308
|
+
- 让 sidebar 设置入口能够恢复正式版受管运行时,并可靠打开 Config UI。
|
|
309
|
+
- 将 Mobile 的 ask/Provider 活动与服务端精确状态同步,稳定完成通知,并隐藏自动重连过程中的无意义提示。
|
|
310
|
+
- 收紧托管 Provider 资源的单向投影边界,并加入内置 Qoder 控制技能,托管侧不会获得改写用户全局状态的通道。
|
|
311
|
+
|
|
312
|
+
</details>
|
|
313
|
+
|
|
314
|
+
<details>
|
|
303
315
|
<summary><b>v8.4.3</b> - Provider 认证隔离、必备控制技能与可靠的 Mobile 配对和终端恢复</summary>
|
|
304
316
|
|
|
305
317
|
- 将可变认证、账号、session 和存储状态隔离到每个托管 Provider 的私有 home,visible 与 headless 执行使用同一边界。
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Coordinate Codex, Claude, Gemini, and other CLI agents in visible, controllable workflows you can take over**
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<img src="https://img.shields.io/badge/version-8.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-8.5.0-orange.svg" alt="version">
|
|
10
10
|
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WSL-lightgrey.svg" alt="platform">
|
|
11
11
|
<img src="https://img.shields.io/badge/providers-17%20CLI%20families-0B7285.svg" alt="providers">
|
|
12
12
|
</p>
|
|
@@ -220,9 +220,9 @@ This command guides installation and configuration.
|
|
|
220
220
|
<details>
|
|
221
221
|
<summary><b>Mobile App details, safety boundary, and source</b></summary>
|
|
222
222
|
|
|
223
|
-
CCB 8.
|
|
223
|
+
CCB 8.5.0 includes the Flutter CCB Mobile source in [`mobile/`](mobile/) and publishes the Android APK through GitHub Releases:
|
|
224
224
|
|
|
225
|
-
- [Download CCB Mobile v8.
|
|
225
|
+
- [Download CCB Mobile v8.5.0 APK](https://github.com/SeemSeam/claude_codex_bridge/releases/download/v8.5.0/ccb-mobile-v8.5.0.apk)
|
|
226
226
|
- App source: [`mobile/app`](mobile/app)
|
|
227
227
|
- Server gateway source: [`lib/mobile_gateway`](lib/mobile_gateway)
|
|
228
228
|
|
|
@@ -309,6 +309,18 @@ Thanks to [tmux-agent-sidebar](https://github.com/hiroppy/tmux-agent-sidebar) fo
|
|
|
309
309
|
## Release Notes
|
|
310
310
|
|
|
311
311
|
<details open>
|
|
312
|
+
<summary><b>v8.5.0</b> - Exact Pi/OMP completion, self-healing npm runtime, synchronized Mobile activity, and safer managed assets</summary>
|
|
313
|
+
|
|
314
|
+
- Bound Pi completion to the latest `agent_settled` event and OMP completion to `agent_end.isTerminal=true`, while waiting for process exit and output closure before terminalizing.
|
|
315
|
+
- Failed closed on missing native terminal evidence, missing final outcomes, malformed or truncated JSONL, provider errors, and nonzero exits; terminal OMP `yield` remains a supported successful result.
|
|
316
|
+
- Bootstrapped and repaired the npm-managed Python environment during install, so release runtime dependencies no longer depend on an incomplete system Python fallback; linked Git worktrees remain correctly classified as source installs.
|
|
317
|
+
- Made the sidebar settings launcher recover its release-managed runtime and reliably open Config UI.
|
|
318
|
+
- Synchronized Mobile ask/provider activity with exact server-side state, stable completion notifications, and quieter automatic reconnect behavior.
|
|
319
|
+
- Tightened one-way managed Provider asset projection and added packaged Qoder control skills without exposing user-global state to managed mutation.
|
|
320
|
+
|
|
321
|
+
</details>
|
|
322
|
+
|
|
323
|
+
<details>
|
|
312
324
|
<summary><b>v8.4.3</b> - Isolated Provider auth, guaranteed control skills, and reliable Mobile pairing and terminal recovery</summary>
|
|
313
325
|
|
|
314
326
|
- Isolated mutable authentication, account, session, and storage state inside each managed Provider home for visible and headless execution.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
8.
|
|
1
|
+
8.5.0
|
package/bin/ccb-npm-install.js
CHANGED
|
@@ -12,6 +12,19 @@ const root = path.resolve(__dirname, "..");
|
|
|
12
12
|
const manifest = require(path.join(root, "package.json"));
|
|
13
13
|
const version = manifest.version;
|
|
14
14
|
const vendorRoot = path.join(root, ".ccb-release");
|
|
15
|
+
const installLock = path.join(root, ".ccb-install.lock");
|
|
16
|
+
const runtimeProbe = [
|
|
17
|
+
"import sys",
|
|
18
|
+
"if sys.version_info < (3, 10):",
|
|
19
|
+
" raise SystemExit(1)",
|
|
20
|
+
"try:",
|
|
21
|
+
" import tomllib",
|
|
22
|
+
"except ModuleNotFoundError:",
|
|
23
|
+
" import tomli",
|
|
24
|
+
"import aiohttp",
|
|
25
|
+
"from cryptography.hazmat.primitives.asymmetric import ed25519, x25519",
|
|
26
|
+
"from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305",
|
|
27
|
+
].join("\n");
|
|
15
28
|
|
|
16
29
|
function artifactForHost() {
|
|
17
30
|
if (process.platform === "darwin") {
|
|
@@ -42,14 +55,39 @@ function executablePath(command = "ccb") {
|
|
|
42
55
|
return command === "ccb" ? path.join(base, "ccb") : path.join(base, "bin", command);
|
|
43
56
|
}
|
|
44
57
|
|
|
45
|
-
function
|
|
58
|
+
function runtimePythonPath(info) {
|
|
59
|
+
return path.join(installDir(info), ".venv", "bin", "python");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isReleaseInstalled(info) {
|
|
46
63
|
const dir = installDir(info);
|
|
47
64
|
const versionFile = path.join(dir, "VERSION");
|
|
48
65
|
const ccbPath = path.join(dir, "ccb");
|
|
49
66
|
if (!fs.existsSync(versionFile) || !fs.existsSync(ccbPath)) {
|
|
50
67
|
return false;
|
|
51
68
|
}
|
|
52
|
-
|
|
69
|
+
try {
|
|
70
|
+
fs.accessSync(ccbPath, fs.constants.X_OK);
|
|
71
|
+
return fs.readFileSync(versionFile, "utf8").trim() === version;
|
|
72
|
+
} catch (_error) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isRuntimeReady(info) {
|
|
78
|
+
const pythonPath = runtimePythonPath(info);
|
|
79
|
+
if (!fs.existsSync(pythonPath)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
const completed = childProcess.spawnSync(pythonPath, ["-c", runtimeProbe], {
|
|
83
|
+
stdio: "ignore",
|
|
84
|
+
timeout: 15000,
|
|
85
|
+
});
|
|
86
|
+
return !completed.error && completed.status === 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function isInstalled(info) {
|
|
90
|
+
return isReleaseInstalled(info) && isRuntimeReady(info);
|
|
53
91
|
}
|
|
54
92
|
|
|
55
93
|
function download(url, destination, redirects = 0) {
|
|
@@ -100,9 +138,10 @@ function sha256File(filePath) {
|
|
|
100
138
|
return hash.digest("hex");
|
|
101
139
|
}
|
|
102
140
|
|
|
103
|
-
function run(command, args) {
|
|
141
|
+
function run(command, args, options = {}) {
|
|
104
142
|
const completed = childProcess.spawnSync(command, args, {
|
|
105
143
|
stdio: "inherit",
|
|
144
|
+
...options,
|
|
106
145
|
});
|
|
107
146
|
if (completed.error) {
|
|
108
147
|
throw completed.error;
|
|
@@ -112,16 +151,119 @@ function run(command, args) {
|
|
|
112
151
|
}
|
|
113
152
|
}
|
|
114
153
|
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
154
|
+
function bootstrapRuntime(info) {
|
|
155
|
+
const dir = installDir(info);
|
|
156
|
+
const installerPath = path.join(dir, "install.sh");
|
|
157
|
+
if (!isReleaseInstalled(info)) {
|
|
158
|
+
throw new Error(`Cannot bootstrap an incomplete CCB release at ${dir}`);
|
|
119
159
|
}
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
160
|
+
if (!fs.existsSync(installerPath)) {
|
|
161
|
+
throw new Error(`CCB runtime bootstrap installer not found at ${installerPath}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const env = {
|
|
165
|
+
...process.env,
|
|
166
|
+
CODEX_INSTALL_PREFIX: dir,
|
|
167
|
+
CODEX_BIN_DIR: path.join(dir, ".npm-runtime-bin"),
|
|
168
|
+
CCB_SOURCE_KIND: "release",
|
|
169
|
+
CCB_USE_MANAGED_VENV: "1",
|
|
170
|
+
CCB_INSTALL_TOMLI: "1",
|
|
171
|
+
CCB_INSTALL_MOBILE_RELAY_DEPS: "1",
|
|
172
|
+
CCB_INSTALL_ROLES: "0",
|
|
173
|
+
CCB_INSTALL_NEOVIM: "0",
|
|
174
|
+
};
|
|
175
|
+
run("bash", [installerPath, "runtime-bootstrap"], { env });
|
|
176
|
+
if (!isRuntimeReady(info)) {
|
|
177
|
+
throw new Error(`CCB managed Python runtime is not usable at ${runtimePythonPath(info)}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function sleep(milliseconds) {
|
|
182
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function processIsAlive(pid) {
|
|
186
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
process.kill(pid, 0);
|
|
191
|
+
return true;
|
|
192
|
+
} catch (error) {
|
|
193
|
+
return error && error.code === "EPERM";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function readLockOwner() {
|
|
198
|
+
try {
|
|
199
|
+
return JSON.parse(fs.readFileSync(path.join(installLock, "owner.json"), "utf8"));
|
|
200
|
+
} catch (_error) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function reclaimStaleInstallLock() {
|
|
206
|
+
const owner = readLockOwner();
|
|
207
|
+
if (owner && processIsAlive(Number(owner.pid))) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
const ageMs = Date.now() - fs.statSync(installLock).mtimeMs;
|
|
212
|
+
if (!owner && ageMs < 30000) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
fs.rmSync(installLock, { recursive: true, force: true });
|
|
216
|
+
return true;
|
|
217
|
+
} catch (_error) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function acquireInstallLock() {
|
|
223
|
+
const configuredTimeout = Number(process.env.CCB_NPM_INSTALL_LOCK_TIMEOUT_MS);
|
|
224
|
+
const timeoutMs =
|
|
225
|
+
Number.isFinite(configuredTimeout) && configuredTimeout > 0
|
|
226
|
+
? configuredTimeout
|
|
227
|
+
: 15 * 60 * 1000;
|
|
228
|
+
const deadline = Date.now() + timeoutMs;
|
|
229
|
+
const token = crypto.randomBytes(16).toString("hex");
|
|
230
|
+
|
|
231
|
+
while (true) {
|
|
232
|
+
try {
|
|
233
|
+
fs.mkdirSync(installLock);
|
|
234
|
+
} catch (error) {
|
|
235
|
+
if (!error || error.code !== "EEXIST") {
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
if (reclaimStaleInstallLock()) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (Date.now() >= deadline) {
|
|
242
|
+
throw new Error(`Timed out waiting for CCB npm install lock: ${installLock}`);
|
|
243
|
+
}
|
|
244
|
+
await sleep(200);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
fs.writeFileSync(
|
|
250
|
+
path.join(installLock, "owner.json"),
|
|
251
|
+
JSON.stringify({ pid: process.pid, token, createdAt: new Date().toISOString() })
|
|
252
|
+
);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
fs.rmSync(installLock, { recursive: true, force: true });
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
return () => {
|
|
258
|
+
const owner = readLockOwner();
|
|
259
|
+
if (owner && owner.token === token) {
|
|
260
|
+
fs.rmSync(installLock, { recursive: true, force: true });
|
|
261
|
+
}
|
|
262
|
+
};
|
|
123
263
|
}
|
|
264
|
+
}
|
|
124
265
|
|
|
266
|
+
async function downloadRelease(info) {
|
|
125
267
|
const baseUrl =
|
|
126
268
|
process.env.CCB_NPM_RELEASE_BASE_URL ||
|
|
127
269
|
`https://github.com/SeemSeam/claude_codex_bridge/releases/download/v${version}`;
|
|
@@ -154,6 +296,32 @@ async function install() {
|
|
|
154
296
|
}
|
|
155
297
|
}
|
|
156
298
|
|
|
299
|
+
async function install() {
|
|
300
|
+
const info = artifactForHost();
|
|
301
|
+
if (isInstalled(info)) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const releaseLock = await acquireInstallLock();
|
|
306
|
+
try {
|
|
307
|
+
if (isInstalled(info)) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (!isReleaseInstalled(info)) {
|
|
311
|
+
if (process.env.CCB_NPM_SKIP_DOWNLOAD === "1") {
|
|
312
|
+
console.warn("Skipping CCB release download because CCB_NPM_SKIP_DOWNLOAD=1.");
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
await downloadRelease(info);
|
|
316
|
+
}
|
|
317
|
+
if (!isRuntimeReady(info)) {
|
|
318
|
+
bootstrapRuntime(info);
|
|
319
|
+
}
|
|
320
|
+
} finally {
|
|
321
|
+
releaseLock();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
157
325
|
if (require.main === module) {
|
|
158
326
|
install().catch((error) => {
|
|
159
327
|
console.error(error.message || error);
|
|
@@ -162,6 +330,13 @@ if (require.main === module) {
|
|
|
162
330
|
}
|
|
163
331
|
|
|
164
332
|
module.exports = {
|
|
333
|
+
artifactForHost,
|
|
334
|
+
bootstrapRuntime,
|
|
165
335
|
executablePath,
|
|
166
336
|
install,
|
|
337
|
+
installDir,
|
|
338
|
+
isInstalled,
|
|
339
|
+
isReleaseInstalled,
|
|
340
|
+
isRuntimeReady,
|
|
341
|
+
runtimePythonPath,
|
|
167
342
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seemseam/ccb",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.5.0",
|
|
4
4
|
"description": "Lightweight multi-agent TUI and stable cross-provider collaboration layer for Codex, Claude, Gemini, Grok, Kimi, DeepSeek, and other CLI agents.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"homepage": "https://github.com/SeemSeam/claude_codex_bridge#readme",
|