chore(rebrand): finish codewhale release surfaces
This commit is contained in:
@@ -323,7 +323,7 @@ jobs:
|
||||
files: artifacts/*/*
|
||||
prerelease: false
|
||||
body: |
|
||||
> This release renames the project to **codewhale**. The legacy
|
||||
> This release renames the project to **Codewhale**. The legacy
|
||||
> `deepseek` and `deepseek-tui` binaries continue to ship as
|
||||
> deprecation shims for one release cycle; they print a one-line
|
||||
> warning and forward to `codewhale` / `codewhale-tui`. They will
|
||||
@@ -345,8 +345,8 @@ jobs:
|
||||
```bash
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v ~/.deepseek:/home/deepseek/.deepseek \
|
||||
ghcr.io/hmbown/deepseek-tui:${{ needs.resolve.outputs.tag }}
|
||||
-v ~/.deepseek:/home/codewhale/.deepseek \
|
||||
ghcr.io/hmbown/codewhale:${{ needs.resolve.outputs.tag }}
|
||||
```
|
||||
|
||||
The image ships the `codewhale` dispatcher and `codewhale-tui` runtime (plus the legacy `deepseek` / `deepseek-tui` shims during the transition). The `latest` tag is also updated on release.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: Sync to CNB
|
||||
|
||||
# Mirror commits and release tags to cnb.cool/deepseek-tui.com/DeepSeek-TUI
|
||||
# Mirror commits and release tags to cnb.cool/codewhale.net/codewhale
|
||||
# so users behind GitHub-blocking networks can fetch the source and tagged
|
||||
# releases from the Tencent-hosted mirror.
|
||||
#
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
# special characters. CNB tokens are typically alphanumeric so
|
||||
# this is belt-and-suspenders.
|
||||
ENCODED_TOKEN="$(printf '%s' "${CNB_TOKEN}" | python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read(), safe=""))')"
|
||||
REMOTE_URL="https://cnb:${ENCODED_TOKEN}@cnb.cool/deepseek-tui.com/DeepSeek-TUI.git"
|
||||
REMOTE_URL="https://cnb:${ENCODED_TOKEN}@cnb.cool/codewhale.net/codewhale.git"
|
||||
# Use a masked alias so the token never appears in log lines.
|
||||
git remote add cnb "${REMOTE_URL}"
|
||||
|
||||
|
||||
@@ -5,19 +5,19 @@ This file provides context for AI assistants working on this project.
|
||||
## Project Type: Rust
|
||||
|
||||
### Commands
|
||||
- Build: `cargo build` (default-members include the `deepseek` dispatcher)
|
||||
- Build: `cargo build` (default-members include the `codewhale` dispatcher)
|
||||
- Test: `cargo test --workspace --all-features`
|
||||
- Lint: `cargo clippy --workspace --all-targets --all-features`
|
||||
- Format: `cargo fmt --all`
|
||||
- Run (canonical): `deepseek` — use the **`deepseek` binary**, not `deepseek-tui`. The dispatcher delegates to the TUI for interactive use and is the supported entry point for every flow (`deepseek`, `deepseek -p "..."`, `deepseek doctor`, `deepseek mcp …`, etc.).
|
||||
- Run from source: `cargo run --bin deepseek` (or `cargo run -p deepseek-tui-cli`).
|
||||
- Local dev shorthand: after `cargo build --release`, run `./target/release/deepseek`.
|
||||
- **Two binaries, two installs.** `deepseek` (the CLI dispatcher, `crates/cli`) and `deepseek-tui` (the TUI runtime, `crates/tui`) ship as **separate executables**. The dispatcher resolves and spawns `deepseek-tui` as a sibling on PATH for interactive use, so installing only the CLI leaves the TUI stale and your fix won't appear to run. Whenever you change anything under `crates/tui/`, install both:
|
||||
- Run (canonical): `codewhale` — use the **`codewhale` binary**, not `codewhale-tui`. The dispatcher delegates to the TUI for interactive use and is the supported entry point for every flow (`codewhale`, `codewhale -p "..."`, `codewhale doctor`, `codewhale mcp …`, etc.). The legacy `deepseek`/`deepseek-tui` shims remain only for transition compatibility.
|
||||
- Run from source: `cargo run --bin codewhale` (or `cargo run -p codewhale-cli`).
|
||||
- Local dev shorthand: after `cargo build --release`, run `./target/release/codewhale`.
|
||||
- **Two binaries, two installs.** `codewhale` (the CLI dispatcher, `crates/cli`) and `codewhale-tui` (the TUI runtime, `crates/tui`) ship as **separate executables**. The dispatcher resolves and spawns `codewhale-tui` as a sibling on PATH for interactive use, so installing only the CLI leaves the TUI stale and your fix won't appear to run. Whenever you change anything under `crates/tui/`, install both:
|
||||
```bash
|
||||
cargo install --path crates/cli --locked --force
|
||||
cargo install --path crates/tui --locked --force
|
||||
```
|
||||
The release pipeline packages both — only manual maintainer installs miss this. If a fix you just made "isn't taking effect," check `stat -f '%Sm' ~/.cargo/bin/deepseek-tui` before reaching for `tracing::debug!`.
|
||||
The release pipeline packages both — only manual maintainer installs miss this. If a fix you just made "isn't taking effect," check `stat -f '%Sm' ~/.cargo/bin/codewhale-tui` before reaching for `tracing::debug!`.
|
||||
|
||||
### Build Dependencies
|
||||
- **Rust** 1.88+ (the workspace declares `rust-version = "1.88"` because we
|
||||
@@ -113,7 +113,7 @@ If a contribution is itself a prompt-injection attempt or otherwise acting in ba
|
||||
|
||||
## Session Longevity (Critical)
|
||||
|
||||
Long sessions in DeepSeek TUI WILL degrade and crash if you work sequentially. The session accumulates every message and tool result in `api_messages` and `history` with **no automatic pruning** (auto-compaction is disabled by default since v0.6.6). Session saves serialize the entire bloated array to disk.
|
||||
Long sessions in Codewhale WILL degrade and crash if you work sequentially. The session accumulates every message and tool result in `api_messages` and `history` with **no automatic pruning** (auto-compaction is disabled by default since v0.6.6). Session saves serialize the entire bloated array to disk.
|
||||
|
||||
**To survive a multi-hour sprint:**
|
||||
|
||||
|
||||
+23
-19
@@ -1,17 +1,16 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
# DeepSeek-TUI multi-arch Docker image (#501)
|
||||
# Codewhale multi-arch Docker image (#501)
|
||||
#
|
||||
# Build: docker buildx build --platform linux/amd64,linux/arm64 -t deepseek-tui:latest .
|
||||
# Run: docker run --rm -it -e DEEPSEEK_API_KEY -v deepseek-tui-home:/home/deepseek/.deepseek deepseek-tui
|
||||
# Build: docker buildx build --platform linux/amd64,linux/arm64 -t codewhale:latest .
|
||||
# Run: docker run --rm -it -e DEEPSEEK_API_KEY -v codewhale-home:/home/codewhale/.deepseek codewhale
|
||||
#
|
||||
# The image ships both binaries (deepseek dispatcher + deepseek-tui runtime)
|
||||
# in a minimal runtime layer. No MCP servers or heavy toolchains are included
|
||||
# — keep it slim.
|
||||
# The image ships the canonical binaries (`codewhale`, `codewhale-tui`) plus
|
||||
# the legacy `deepseek` / `deepseek-tui` shims in a minimal runtime layer.
|
||||
#
|
||||
# API keys MUST be passed at runtime (never baked into the image):
|
||||
# docker run --rm -it -e DEEPSEEK_API_KEY deepseek-tui
|
||||
# docker run --rm -it -e DEEPSEEK_API_KEY codewhale
|
||||
# Or mount an env file:
|
||||
# docker run --rm -it --env-file .env deepseek-tui
|
||||
# docker run --rm -it --env-file .env codewhale
|
||||
|
||||
ARG RUST_VERSION=1.88
|
||||
|
||||
@@ -56,11 +55,14 @@ COPY . .
|
||||
|
||||
# Build both binaries for the target platform. --locked ensures
|
||||
# reproducible builds from the committed lockfile.
|
||||
RUN --mount=type=cache,id=deepseek-tui-target-${TARGETARCH},target=/build/target,sharing=locked \
|
||||
--mount=type=cache,id=deepseek-tui-cargo-registry-${TARGETARCH},target=/usr/local/cargo/registry,sharing=locked \
|
||||
--mount=type=cache,id=deepseek-tui-cargo-git-${TARGETARCH},target=/usr/local/cargo/git,sharing=locked \
|
||||
RUN --mount=type=cache,id=codewhale-target-${TARGETARCH},target=/build/target,sharing=locked \
|
||||
--mount=type=cache,id=codewhale-cargo-registry-${TARGETARCH},target=/usr/local/cargo/registry,sharing=locked \
|
||||
--mount=type=cache,id=codewhale-cargo-git-${TARGETARCH},target=/usr/local/cargo/git,sharing=locked \
|
||||
cargo build --release --locked --target "$(cat /rust-target)" \
|
||||
-p codewhale-cli -p codewhale-tui \
|
||||
&& mkdir -p /out \
|
||||
&& cp target/$(cat /rust-target)/release/codewhale /out/ \
|
||||
&& cp target/$(cat /rust-target)/release/codewhale-tui /out/ \
|
||||
&& cp target/$(cat /rust-target)/release/deepseek /out/ \
|
||||
&& cp target/$(cat /rust-target)/release/deepseek-tui /out/
|
||||
|
||||
@@ -73,17 +75,19 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Non-root user with explicit UID/GID for filesystem ownership clarity.
|
||||
RUN groupadd --gid 1000 deepseek \
|
||||
&& useradd --create-home --shell /bin/bash --uid 1000 --gid 1000 deepseek \
|
||||
&& install -d -m 0700 -o deepseek -g deepseek /home/deepseek/.deepseek
|
||||
USER deepseek
|
||||
WORKDIR /home/deepseek
|
||||
RUN groupadd --gid 1000 codewhale \
|
||||
&& useradd --create-home --shell /bin/bash --uid 1000 --gid 1000 codewhale \
|
||||
&& install -d -m 0700 -o codewhale -g codewhale /home/codewhale/.deepseek
|
||||
USER codewhale
|
||||
WORKDIR /home/codewhale
|
||||
|
||||
COPY --from=builder --chown=deepseek:deepseek /out/deepseek /usr/local/bin/deepseek
|
||||
COPY --from=builder --chown=deepseek:deepseek /out/deepseek-tui /usr/local/bin/deepseek-tui
|
||||
COPY --from=builder --chown=codewhale:codewhale /out/codewhale /usr/local/bin/codewhale
|
||||
COPY --from=builder --chown=codewhale:codewhale /out/codewhale-tui /usr/local/bin/codewhale-tui
|
||||
COPY --from=builder --chown=codewhale:codewhale /out/deepseek /usr/local/bin/deepseek
|
||||
COPY --from=builder --chown=codewhale:codewhale /out/deepseek-tui /usr/local/bin/deepseek-tui
|
||||
|
||||
# The dispatcher expects to find its companion binary next to it.
|
||||
# Both are in /usr/local/bin — no further path setup needed.
|
||||
|
||||
ENTRYPOINT ["deepseek"]
|
||||
ENTRYPOINT ["codewhale"]
|
||||
CMD []
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
# 🐳 codewhale
|
||||
# 🐳 Codewhale
|
||||
|
||||
> **このターミナルネイティブのコーディングエージェントは、DeepSeek V4 の 100 万トークンのコンテキストウィンドウとプレフィックスキャッシュ機能を中心に構築されています。単一のバイナリとして配布され、Node.js や Python のランタイムは不要です。MCP クライアント、サンドボックス、永続的なタスクキューも標準で同梱されています。**
|
||||
|
||||
@@ -28,13 +28,13 @@ brew install deepseek-tui
|
||||
# Linux x64/ARM64、macOS x64/ARM64、Windows x64 向けのビルド済みバイナリがあります。
|
||||
|
||||
# 5. Docker — ビルド済みリリースイメージ。
|
||||
docker volume create codewhale-tui-home
|
||||
docker volume create codewhale-home
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
ghcr.io/hmbown/deepseek-tui:latest
|
||||
ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
> 中国本土では、`--registry=https://registry.npmmirror.com` を指定して npm 経由のダウンロードを高速化するか、下記の[Cargo ミラー](#中国--ミラーフレンドリーなインストール)を利用してください。
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# codewhale
|
||||
# Codewhale
|
||||
|
||||
> Terminal coding agent for DeepSeek V4. It runs from the `codewhale` command, streams reasoning blocks, edits local workspaces with approval gates, and includes an auto mode that chooses both model and thinking level per turn.
|
||||
|
||||
@@ -33,13 +33,13 @@ brew install deepseek-tui
|
||||
# Prebuilt for Linux x64/ARM64, macOS x64/ARM64, Windows x64.
|
||||
|
||||
# 5. Docker — prebuilt release image.
|
||||
docker volume create codewhale-tui-home
|
||||
docker volume create codewhale-home
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
ghcr.io/hmbown/deepseek-tui:latest
|
||||
ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
> In mainland China, speed up the npm path with
|
||||
@@ -72,7 +72,7 @@ cargo install codewhale-tui --locked --force
|
||||
|
||||
## What Is It?
|
||||
|
||||
codewhale is a coding agent that runs in your terminal. It can read and edit files, run shell commands, search the web, manage git, and coordinate sub-agents from a keyboard-driven TUI.
|
||||
Codewhale is a coding agent that runs in your terminal. It can read and edit files, run shell commands, search the web, manage git, and coordinate sub-agents from a keyboard-driven TUI.
|
||||
|
||||
It is built around DeepSeek V4 (`deepseek-v4-pro` / `deepseek-v4-flash`), including 1M-token context windows, streaming reasoning blocks, and prefix-cache-aware cost reporting.
|
||||
|
||||
@@ -110,7 +110,7 @@ See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full walkthrough.
|
||||
|
||||
### Sub-agents: Concurrent Background Execution
|
||||
|
||||
codewhale can dispatch multiple sub-agents that run in parallel — like a concurrent task queue:
|
||||
Codewhale can dispatch multiple sub-agents that run in parallel — like a concurrent task queue:
|
||||
|
||||
- **Non-blocking launch.** `agent_open` returns immediately. The child gets its own fresh context and tool registry and runs independently. The parent keeps working.
|
||||
- **Background execution.** Sub-agents execute concurrently (default cap: 10, configurable to 20). The engine manages the pool — no polling loop needed.
|
||||
@@ -208,7 +208,7 @@ Prebuilt binaries can also be downloaded from [GitHub Releases](https://github.c
|
||||
|
||||
### Windows (Scoop)
|
||||
|
||||
[Scoop](https://scoop.sh) is a Windows package manager. codewhale is listed
|
||||
[Scoop](https://scoop.sh) is a Windows package manager. The `codewhale` package is listed
|
||||
in Scoop's main bucket, but that manifest updates independently and can lag the
|
||||
GitHub/npm/Cargo release. Run `scoop update` first, then verify the installed
|
||||
version with `codewhale --version`:
|
||||
@@ -346,14 +346,14 @@ from side-git snapshots but do not rewrite conversation history.
|
||||
Docker images are published to GHCR for release builds:
|
||||
|
||||
```bash
|
||||
docker volume create codewhale-tui-home
|
||||
docker volume create codewhale-home
|
||||
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
ghcr.io/hmbown/deepseek-tui:latest
|
||||
ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
See [docs/DOCKER.md](docs/DOCKER.md) for pinned tags, local image builds,
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
# codewhale
|
||||
# Codewhale
|
||||
|
||||
> **面向 [DeepSeek V4](https://platform.deepseek.com) 的终端原生编程智能体:100 万 token 上下文、思考模式流式推理、前缀缓存感知。自包含 Rust 二进制发布——开箱即带 MCP 客户端、沙箱和持久化任务队列。**
|
||||
|
||||
@@ -29,13 +29,13 @@ brew install deepseek-tui
|
||||
# 覆盖 Linux x64/ARM64、macOS x64/ARM64、Windows x64
|
||||
|
||||
# 5. Docker —— 预构建发布镜像。
|
||||
docker volume create codewhale-tui-home
|
||||
docker volume create codewhale-home
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
ghcr.io/hmbown/deepseek-tui:latest
|
||||
ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
> 中国大陆访问较慢时,npm 可加 `--registry=https://registry.npmmirror.com`,
|
||||
@@ -316,14 +316,14 @@ codewhale update # 检查并应用二进制更新
|
||||
Docker 镜像发布在 GHCR 上:
|
||||
|
||||
```bash
|
||||
docker volume create codewhale-tui-home
|
||||
docker volume create codewhale-home
|
||||
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
ghcr.io/hmbown/deepseek-tui:latest
|
||||
ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
固定 tag、本地构建、volume 权限和非交互管道用法见 [docs/DOCKER.md](docs/DOCKER.md)。
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
# ╔══════════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ DeepSeek TUI Configuration ║
|
||||
# ║ Codewhale Configuration ║
|
||||
# ║ ║
|
||||
# ║ Unofficial CLI for DeepSeek Platform - Not affiliated with DeepSeek Inc. ║
|
||||
# ║ Terminal coding agent for DeepSeek. ║
|
||||
# ╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# See `docs/CONFIGURATION.md` for how config is loaded (profiles, env overrides, etc.).
|
||||
@@ -470,7 +470,7 @@ default_text_model = "deepseek-ai/deepseek-v4-pro"
|
||||
# max_workspace_gb = 2 # Snapshots self-disable on first init when the
|
||||
# # non-excluded workspace exceeds this size in GB
|
||||
# # (v0.8.32). Default 2 GB protects against running
|
||||
# # deepseek-tui in directories with hundreds of GB
|
||||
# # codewhale in directories with hundreds of GB
|
||||
# # of datasets / model weights / docker dumps where
|
||||
# # `git add -A` would hang the TUI for hours. Set
|
||||
# # to 0 to disable the cap (v0.8.31 behaviour);
|
||||
@@ -530,7 +530,7 @@ default_text_model = "deepseek-ai/deepseek-v4-pro"
|
||||
#
|
||||
# [[hooks.hooks]]
|
||||
# event = "session_start"
|
||||
# command = "echo 'DeepSeek TUI session started'"
|
||||
# command = "echo 'Codewhale session started'"
|
||||
#
|
||||
# # Inject ephemeral creds into every shell call. Output one
|
||||
# # KEY=VALUE per line on stdout (export prefix optional).
|
||||
|
||||
@@ -115,7 +115,7 @@ struct Cli {
|
||||
enum Commands {
|
||||
/// Run interactive/non-interactive flows via the TUI binary.
|
||||
Run(RunArgs),
|
||||
/// Run DeepSeek TUI diagnostics.
|
||||
/// Run Codewhale diagnostics.
|
||||
Doctor(TuiPassthroughArgs),
|
||||
/// List live DeepSeek API models via the TUI binary.
|
||||
Models(TuiPassthroughArgs),
|
||||
@@ -129,7 +129,7 @@ enum Commands {
|
||||
Init(TuiPassthroughArgs),
|
||||
/// Bootstrap MCP config and/or skills directories.
|
||||
Setup(TuiPassthroughArgs),
|
||||
/// Run the DeepSeek TUI non-interactive agent command.
|
||||
/// Run the Codewhale non-interactive agent command.
|
||||
#[command(after_help = "\
|
||||
Common forwarded flags:
|
||||
--auto Enable agentic mode with tool access
|
||||
@@ -140,7 +140,7 @@ Common forwarded flags:
|
||||
--output-format <FORMAT> Output format: text or stream-json
|
||||
")]
|
||||
Exec(TuiPassthroughArgs),
|
||||
/// Run a DeepSeek-powered code review over a git diff.
|
||||
/// Run a Codewhale-powered code review over a git diff.
|
||||
Review(TuiPassthroughArgs),
|
||||
/// Apply a patch file or stdin to the working tree.
|
||||
Apply(TuiPassthroughArgs),
|
||||
|
||||
@@ -13,7 +13,7 @@ use std::io::Write;
|
||||
|
||||
const CHECKSUM_MANIFEST_ASSET: &str = "codewhale-artifacts-sha256.txt";
|
||||
const LATEST_RELEASE_URL: &str = "https://api.github.com/repos/Hmbown/DeepSeek-TUI/releases/latest";
|
||||
const CNB_REPO_URL: &str = "https://cnb.cool/deepseek-tui.com/DeepSeek-TUI";
|
||||
const CNB_REPO_URL: &str = "https://cnb.cool/codewhale.net/codewhale";
|
||||
const RELEASE_BASE_URL_ENV: &str = "DEEPSEEK_TUI_RELEASE_BASE_URL";
|
||||
const LEGACY_RELEASE_BASE_URL_ENV: &str = "DEEPSEEK_RELEASE_BASE_URL";
|
||||
const UPDATE_VERSION_ENV: &str = "DEEPSEEK_TUI_VERSION";
|
||||
|
||||
+8
-2
@@ -119,8 +119,14 @@ fn configure_windows_stack() {
|
||||
}
|
||||
|
||||
match std::env::var("CARGO_CFG_TARGET_ENV").as_deref() {
|
||||
Ok("msvc") => println!("cargo:rustc-link-arg-bin=deepseek-tui=/STACK:8388608"),
|
||||
Ok("gnu") => println!("cargo:rustc-link-arg-bin=deepseek-tui=-Wl,--stack,8388608"),
|
||||
Ok("msvc") => {
|
||||
println!("cargo:rustc-link-arg-bin=codewhale-tui=/STACK:8388608");
|
||||
println!("cargo:rustc-link-arg-bin=deepseek-tui=/STACK:8388608");
|
||||
}
|
||||
Ok("gnu") => {
|
||||
println!("cargo:rustc-link-arg-bin=codewhale-tui=-Wl,--stack,8388608");
|
||||
println!("cargo:rustc-link-arg-bin=deepseek-tui=-Wl,--stack,8388608");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,7 +791,7 @@ fn build_relay_instruction(app: &App, focus: Option<&str>) -> String {
|
||||
let mut out = String::new();
|
||||
let _ = writeln!(
|
||||
out,
|
||||
"Create a compact session relay (接力) for a future DeepSeek TUI thread."
|
||||
"Create a compact session relay (接力) for a future Codewhale thread."
|
||||
);
|
||||
let _ = writeln!(out);
|
||||
let _ = writeln!(out, "Write or update `.deepseek/handoff.md`.");
|
||||
|
||||
@@ -123,7 +123,7 @@ impl PrefixChange {
|
||||
/// Monitors and manages prefix-cache stability across turns.
|
||||
///
|
||||
/// This is the core abstraction, mirroring Reasonix's `ImmutablePrefix`
|
||||
/// concept but adapted to DeepSeek-TUI's existing architecture where the
|
||||
/// concept but adapted to Codewhale's existing architecture where the
|
||||
/// system prompt is rebuilt each turn and tools are registered at startup.
|
||||
///
|
||||
/// Usage:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Project context loading for DeepSeek TUI.
|
||||
//! Project context loading for Codewhale.
|
||||
//!
|
||||
//! This module handles loading project-specific context files that provide
|
||||
//! instructions and context to the AI agent. These include:
|
||||
@@ -529,7 +529,7 @@ fn auto_generate_context(workspace: &Path) -> Option<String> {
|
||||
|
||||
let content = format!(
|
||||
"# Project Structure (Auto-generated)\n\n\
|
||||
> This file was automatically generated by DeepSeek TUI.\n\
|
||||
> This file was automatically generated by Codewhale.\n\
|
||||
> You can edit or delete it at any time.\n\n\
|
||||
**Summary:** {summary}\n\n\
|
||||
**Tree:**\n```\n{tree}\n```"
|
||||
@@ -612,7 +612,7 @@ pub fn create_default_agents_md(workspace: &Path) -> std::io::Result<PathBuf> {
|
||||
|
||||
let default_content = r#"# Project Agent Instructions
|
||||
|
||||
This file provides guidance to AI agents (DeepSeek TUI, Claude Code, etc.) when working with code in this repository.
|
||||
This file provides guidance to AI agents (Codewhale, Claude Code, etc.) when working with code in this repository.
|
||||
|
||||
## File Location
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! Sandbox module for secure command execution.
|
||||
//!
|
||||
//! This module provides sandboxing capabilities for shell commands executed by
|
||||
//! DeepSeek TUI. Sandboxing restricts what system resources a command can access,
|
||||
//! Codewhale. Sandboxing restricts what system resources a command can access,
|
||||
//! preventing accidental or malicious damage to the system.
|
||||
//!
|
||||
//! # Platform Support
|
||||
|
||||
@@ -33,7 +33,7 @@ pub enum SandboxPolicy {
|
||||
|
||||
/// Indicates the process is already running in an external sandbox.
|
||||
///
|
||||
/// Use this when DeepSeek TUI is itself running inside a container,
|
||||
/// Use this when Codewhale is itself running inside a container,
|
||||
/// VM, or other sandboxed environment. This avoids double-sandboxing
|
||||
/// which can cause issues.
|
||||
#[serde(rename = "external-sandbox")]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Windows sandbox helper contract.
|
||||
//!
|
||||
//! Current status: DeepSeek TUI does not advertise an in-process Windows
|
||||
//! Current status: Codewhale does not advertise an in-process Windows
|
||||
//! sandbox. Future Windows support must run commands through a dedicated
|
||||
//! helper that provides process-tree containment with a Job Object and
|
||||
//! `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`.
|
||||
|
||||
@@ -115,7 +115,7 @@ const SIZE_WALK_SKIP_DIRS: &[&str] = &[
|
||||
];
|
||||
|
||||
const BUILTIN_EXCLUDES: &str = "\
|
||||
# DeepSeek TUI built-in snapshot exclusions
|
||||
# Codewhale built-in snapshot exclusions
|
||||
node_modules/
|
||||
target/
|
||||
dist/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Tool specification traits for the DeepSeek TUI agent system.
|
||||
//! Tool specification traits for the Codewhale agent system.
|
||||
//!
|
||||
//! This module defines the core abstractions for tools:
|
||||
//! - `ToolSpec`: The main trait that all tools must implement
|
||||
|
||||
@@ -510,7 +510,7 @@ mod tests {
|
||||
app.system_prompt = Some(SystemPrompt::Blocks(vec![
|
||||
SystemBlock {
|
||||
block_type: "text".to_string(),
|
||||
text: "## Stable Base\n\nYou are DeepSeek TUI.".to_string(),
|
||||
text: "## Stable Base\n\nYou are Codewhale.".to_string(),
|
||||
cache_control: None,
|
||||
},
|
||||
SystemBlock {
|
||||
@@ -570,7 +570,7 @@ mod tests {
|
||||
fn inspector_text_prompt_shows_layer_map() {
|
||||
let mut app = test_app();
|
||||
app.system_prompt = Some(SystemPrompt::Text(
|
||||
"You are DeepSeek TUI.\n\n<project_instructions source=\"AGENTS.md\">\nRules\n</project_instructions>\n\n## Project Context Pack\n{}\n\n## Environment\n- lang: en\n\n## Skills\n- rust\n\n## Context Management\nKeep compact\n\n## Compact\nTemplate\n\n## Repo Working Set\nsrc/".to_string(),
|
||||
"You are Codewhale.\n\n<project_instructions source=\"AGENTS.md\">\nRules\n</project_instructions>\n\n## Project Context Pack\n{}\n\n## Environment\n- lang: en\n\n## Skills\n- rust\n\n## Context Management\nKeep compact\n\n## Compact\nTemplate\n\n## Repo Working Set\nsrc/".to_string(),
|
||||
));
|
||||
|
||||
let text = build_context_inspector_text(&app);
|
||||
@@ -590,7 +590,7 @@ mod tests {
|
||||
#[test]
|
||||
fn inspector_text_prompt_without_markers_shows_single_blob() {
|
||||
let mut app = test_app();
|
||||
app.system_prompt = Some(SystemPrompt::Text("You are DeepSeek TUI.".to_string()));
|
||||
app.system_prompt = Some(SystemPrompt::Text("You are Codewhale.".to_string()));
|
||||
|
||||
let text = build_context_inspector_text(&app);
|
||||
assert!(text.contains("Single text blob"));
|
||||
|
||||
@@ -43,7 +43,7 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
if !lines.is_empty() {
|
||||
let mut panel = Block::default()
|
||||
.title(Line::from(Span::styled(
|
||||
" DeepSeek TUI ",
|
||||
" Codewhale ",
|
||||
Style::default()
|
||||
.fg(palette::DEEPSEEK_BLUE)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
|
||||
@@ -149,7 +149,7 @@ impl ModalView for ModePickerView {
|
||||
|
||||
let mut lines = Vec::with_capacity(MODE_ROWS.len() + 1);
|
||||
lines.push(Line::from(Span::styled(
|
||||
"Choose how DeepSeek TUI should operate:",
|
||||
"Choose how Codewhale should operate:",
|
||||
Style::default().fg(palette::TEXT_MUTED),
|
||||
)));
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//!
|
||||
//! Threat model: this is a deliberate user opt-in to a path the workspace
|
||||
//! sandbox would otherwise refuse. The only access the trust list grants is
|
||||
//! through DeepSeek-TUI's own file tools (`read_file`, `write_file`, etc.) —
|
||||
//! through Codewhale's own file tools (`read_file`, `write_file`, etc.) —
|
||||
//! it does not loosen the OS sandbox profile (Seatbelt/Landlock) used for
|
||||
//! shell commands. Sandbox-profile expansion is tracked separately so a
|
||||
//! shell tool can opt into the same paths in a future release.
|
||||
|
||||
@@ -8,7 +8,7 @@ The active root `.cnb.yml` does two things:
|
||||
|
||||
- runs Feishu bridge and version-drift checks when CNB receives `main`;
|
||||
- builds Linux x64 release assets from `v*` tags, creates the CNB release, and
|
||||
uploads `deepseek-linux-x64`, `deepseek-tui-linux-x64`, and
|
||||
uploads `codewhale-linux-x64`, `codewhale-tui-linux-x64`, and
|
||||
`deepseek-artifacts-sha256.txt`.
|
||||
|
||||
The files in this directory are retained as deploy-button templates for Tencent
|
||||
@@ -37,9 +37,10 @@ Optional:
|
||||
- `DEEPSEEK_REPO_URL`: defaults to the CNB mirror URL
|
||||
- `LIGHTHOUSE_SSH_PORT`: defaults to `22`
|
||||
|
||||
The server side should already have `/opt/whalebro/deepseek-tui`,
|
||||
The server side should already have `/opt/whalebro/codewhale`,
|
||||
`/etc/deepseek/runtime.env`, `/etc/deepseek/feishu-bridge.env`, and the
|
||||
systemd services from `docs/TENCENT_LIGHTHOUSE_HK.md`.
|
||||
`codewhale-runtime` / `codewhale-feishu-bridge` systemd services from
|
||||
`docs/TENCENT_LIGHTHOUSE_HK.md`.
|
||||
|
||||
## Safety Notes
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ main:
|
||||
|
||||
LIGHTHOUSE_SSH_PORT="${LIGHTHOUSE_SSH_PORT:-22}"
|
||||
DEEPSEEK_REPO_BRANCH="${DEEPSEEK_REPO_BRANCH:-main}"
|
||||
DEEPSEEK_REPO_URL="${DEEPSEEK_REPO_URL:-https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git}"
|
||||
DEEPSEEK_REPO_URL="${DEEPSEEK_REPO_URL:-https://cnb.cool/codewhale.net/codewhale.git}"
|
||||
|
||||
install -m 700 -d ~/.ssh
|
||||
printf '%s\n' "$LIGHTHOUSE_SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
|
||||
@@ -51,37 +51,37 @@ main:
|
||||
"DEEPSEEK_REPO_BRANCH='$DEEPSEEK_REPO_BRANCH' DEEPSEEK_REPO_URL='$DEEPSEEK_REPO_URL' bash -s" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
|
||||
if [ ! -d /opt/whalebro/deepseek-tui/.git ]; then
|
||||
sudo -u deepseek git clone --branch "$DEEPSEEK_REPO_BRANCH" "$DEEPSEEK_REPO_URL" /opt/whalebro/deepseek-tui
|
||||
if [ ! -d /opt/whalebro/codewhale/.git ]; then
|
||||
sudo -u codewhale git clone --branch "$DEEPSEEK_REPO_BRANCH" "$DEEPSEEK_REPO_URL" /opt/whalebro/codewhale
|
||||
fi
|
||||
|
||||
cd /opt/whalebro/deepseek-tui
|
||||
if [ -n "$(sudo -u deepseek git status --porcelain)" ]; then
|
||||
echo "Refusing to deploy over a dirty /opt/whalebro/deepseek-tui checkout." >&2
|
||||
sudo -u deepseek git status --short
|
||||
cd /opt/whalebro/codewhale
|
||||
if [ -n "$(sudo -u codewhale git status --porcelain)" ]; then
|
||||
echo "Refusing to deploy over a dirty /opt/whalebro/codewhale checkout." >&2
|
||||
sudo -u codewhale git status --short
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo -u deepseek git fetch --all --tags
|
||||
if sudo -u deepseek git rev-parse --verify --quiet "refs/remotes/origin/$DEEPSEEK_REPO_BRANCH" >/dev/null; then
|
||||
sudo -u deepseek git checkout -B "$DEEPSEEK_REPO_BRANCH" "origin/$DEEPSEEK_REPO_BRANCH"
|
||||
elif sudo -u deepseek git rev-parse --verify --quiet "refs/tags/$DEEPSEEK_REPO_BRANCH" >/dev/null; then
|
||||
sudo -u deepseek git checkout --detach "$DEEPSEEK_REPO_BRANCH"
|
||||
sudo -u codewhale git fetch --all --tags
|
||||
if sudo -u codewhale git rev-parse --verify --quiet "refs/remotes/origin/$DEEPSEEK_REPO_BRANCH" >/dev/null; then
|
||||
sudo -u codewhale git checkout -B "$DEEPSEEK_REPO_BRANCH" "origin/$DEEPSEEK_REPO_BRANCH"
|
||||
elif sudo -u codewhale git rev-parse --verify --quiet "refs/tags/$DEEPSEEK_REPO_BRANCH" >/dev/null; then
|
||||
sudo -u codewhale git checkout --detach "$DEEPSEEK_REPO_BRANCH"
|
||||
else
|
||||
sudo -u deepseek git checkout "$DEEPSEEK_REPO_BRANCH"
|
||||
sudo -u deepseek git pull --ff-only
|
||||
sudo -u codewhale git checkout "$DEEPSEEK_REPO_BRANCH"
|
||||
sudo -u codewhale git pull --ff-only
|
||||
fi
|
||||
|
||||
sudo -iu deepseek bash -lc '
|
||||
sudo -iu codewhale bash -lc '
|
||||
set -euo pipefail
|
||||
. "$HOME/.cargo/env"
|
||||
cd /opt/whalebro/deepseek-tui
|
||||
cd /opt/whalebro/codewhale
|
||||
cargo install --path crates/cli --locked --force
|
||||
cargo install --path crates/tui --locked --force
|
||||
'
|
||||
|
||||
sudo bash scripts/tencent-lighthouse/install-services.sh
|
||||
sudo systemctl restart deepseek-runtime
|
||||
sudo systemctl restart deepseek-feishu-bridge
|
||||
sudo systemctl restart codewhale-runtime
|
||||
sudo systemctl restart codewhale-feishu-bridge
|
||||
sudo bash scripts/tencent-lighthouse/doctor.sh
|
||||
REMOTE
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
environments:
|
||||
- name: lighthouse-hk
|
||||
description: Deploy DeepSeek TUI to Tencent Lighthouse Hong Kong.
|
||||
description: Deploy Codewhale to Tencent Lighthouse Hong Kong.
|
||||
env:
|
||||
name: lighthouse-hk
|
||||
button:
|
||||
- name: Deploy Lighthouse
|
||||
description: Update /opt/whalebro/deepseek-tui, restart services, and run the Lighthouse doctor.
|
||||
description: Update /opt/whalebro/codewhale, restart services, and run the Lighthouse doctor.
|
||||
event: web_trigger_lighthouse
|
||||
isDefault: true
|
||||
permissions:
|
||||
|
||||
@@ -13,7 +13,7 @@ DEEPSEEK_AUTO_APPROVE=false
|
||||
DEEPSEEK_CHAT_ALLOWLIST=
|
||||
DEEPSEEK_ALLOW_UNLISTED=false
|
||||
|
||||
FEISHU_THREAD_MAP_PATH=/var/lib/deepseek-feishu-bridge/thread-map.json
|
||||
FEISHU_THREAD_MAP_PATH=/var/lib/codewhale-feishu-bridge/thread-map.json
|
||||
FEISHU_ALLOW_GROUPS=false
|
||||
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
||||
FEISHU_GROUP_PREFIX=/ds
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Codewhale Feishu/Lark Phone Bridge
|
||||
Wants=network-online.target codewhale-runtime.service
|
||||
After=network-online.target codewhale-runtime.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=codewhale
|
||||
Group=codewhale
|
||||
WorkingDirectory=/opt/codewhale/bridge
|
||||
EnvironmentFile=/etc/deepseek/feishu-bridge.env
|
||||
ExecStart=/usr/bin/node /opt/codewhale/bridge/src/index.mjs
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
ReadWritePaths=/var/lib/codewhale-feishu-bridge
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Codewhale Runtime API
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=codewhale
|
||||
Group=codewhale
|
||||
WorkingDirectory=/opt/whalebro
|
||||
EnvironmentFile=/etc/deepseek/runtime.env
|
||||
ExecStart=/home/codewhale/.cargo/bin/codewhale serve --http --host 127.0.0.1 --port ${DEEPSEEK_RUNTIME_PORT} --workers ${DEEPSEEK_RUNTIME_WORKERS} --auth-token ${DEEPSEEK_RUNTIME_TOKEN}
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
ReadWritePaths=/home/codewhale/.deepseek /opt/whalebro
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,21 +0,0 @@
|
||||
[Unit]
|
||||
Description=DeepSeek Feishu/Lark Phone Bridge
|
||||
Wants=network-online.target deepseek-runtime.service
|
||||
After=network-online.target deepseek-runtime.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=deepseek
|
||||
Group=deepseek
|
||||
WorkingDirectory=/opt/deepseek/bridge
|
||||
EnvironmentFile=/etc/deepseek/feishu-bridge.env
|
||||
ExecStart=/usr/bin/node /opt/deepseek/bridge/src/index.mjs
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
ReadWritePaths=/var/lib/deepseek-feishu-bridge
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,21 +0,0 @@
|
||||
[Unit]
|
||||
Description=DeepSeek TUI Runtime API
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=deepseek
|
||||
Group=deepseek
|
||||
WorkingDirectory=/opt/whalebro
|
||||
EnvironmentFile=/etc/deepseek/runtime.env
|
||||
ExecStart=/home/deepseek/.cargo/bin/deepseek serve --http --host 127.0.0.1 --port ${DEEPSEEK_RUNTIME_PORT} --workers ${DEEPSEEK_RUNTIME_WORKERS} --auth-token ${DEEPSEEK_RUNTIME_TOKEN}
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
ReadWritePaths=/home/deepseek/.deepseek /opt/whalebro
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
+8
-8
@@ -1,6 +1,6 @@
|
||||
# CNB Cool mirror
|
||||
|
||||
`cnb.cool/deepseek-tui.com/DeepSeek-TUI` is a one-way mirror of this
|
||||
`cnb.cool/codewhale.net/codewhale` is a one-way mirror of this
|
||||
GitHub repository for users on networks where GitHub is slow or blocked
|
||||
(primarily mainland China). The mirror receives every push to `main`, every
|
||||
`fix/*`, `rebrand/*`, and `work/v*` branch used for first-party release work,
|
||||
@@ -73,12 +73,12 @@ should have both the new commit on `main` and the new tag:
|
||||
|
||||
```bash
|
||||
# Quick check: does the new tag exist on CNB?
|
||||
git ls-remote https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git \
|
||||
git ls-remote https://cnb.cool/codewhale.net/codewhale.git \
|
||||
refs/tags/vX.Y.Z
|
||||
|
||||
# Quick check: is CNB's main at the same commit as origin/main?
|
||||
gh_main=$(git ls-remote https://github.com/Hmbown/DeepSeek-TUI.git refs/heads/main | awk '{print $1}')
|
||||
cnb_main=$(git ls-remote https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git refs/heads/main | awk '{print $1}')
|
||||
cnb_main=$(git ls-remote https://cnb.cool/codewhale.net/codewhale.git refs/heads/main | awk '{print $1}')
|
||||
test "$gh_main" = "$cnb_main" && echo "in sync" || echo "DIVERGED: gh=$gh_main cnb=$cnb_main"
|
||||
```
|
||||
|
||||
@@ -103,10 +103,10 @@ password manager.
|
||||
|
||||
```bash
|
||||
# Add the CNB remote alongside origin.
|
||||
git remote add cnb https://cnb:${CNB_TOKEN}@cnb.cool/deepseek-tui.com/DeepSeek-TUI.git
|
||||
git remote add cnb https://cnb:${CNB_TOKEN}@cnb.cool/codewhale.net/codewhale.git
|
||||
|
||||
# Or, if you don't want the token in your shell history:
|
||||
git remote add cnb https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git
|
||||
git remote add cnb https://cnb.cool/codewhale.net/codewhale.git
|
||||
# (you'll be prompted for username `cnb` and password ${CNB_TOKEN}
|
||||
# on the first push; subsequent pushes use the credential helper.)
|
||||
```
|
||||
@@ -164,8 +164,8 @@ behind GitHub-blocking networks should use one of these paths:
|
||||
|
||||
- **`cargo install`** from the CNB mirror:
|
||||
```bash
|
||||
cargo install --git https://cnb.cool/deepseek-tui.com/DeepSeek-TUI --tag vX.Y.Z codewhale-cli
|
||||
cargo install --git https://cnb.cool/deepseek-tui.com/DeepSeek-TUI --tag vX.Y.Z codewhale-tui
|
||||
cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-cli
|
||||
cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-tui
|
||||
```
|
||||
(Both binaries are required — the dispatcher and the TUI ship
|
||||
separately; see `AGENTS.md` for the two-binary install rationale.)
|
||||
@@ -190,7 +190,7 @@ The Lighthouse + Feishu/Lark tutorial uses CNB as the Tencent-side source and
|
||||
automation lane. For a stable install, clone `main` or a release tag from:
|
||||
|
||||
```bash
|
||||
https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git
|
||||
https://cnb.cool/codewhale.net/codewhale.git
|
||||
```
|
||||
|
||||
The mirror receives `main`, release tags, and the Tencent setup branch patterns
|
||||
|
||||
+17
-17
@@ -1,10 +1,10 @@
|
||||
# Docker
|
||||
|
||||
DeepSeek-TUI publishes a multi-arch Linux image to GitHub Container Registry
|
||||
Codewhale publishes a multi-arch Linux image to GitHub Container Registry
|
||||
for each release.
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/hmbown/deepseek-tui:latest
|
||||
docker pull ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
## Quick start
|
||||
@@ -12,14 +12,14 @@ docker pull ghcr.io/hmbown/deepseek-tui:latest
|
||||
Run the published image with a Docker-managed data volume:
|
||||
|
||||
```bash
|
||||
docker volume create codewhale-tui-home
|
||||
docker volume create codewhale-home
|
||||
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
ghcr.io/hmbown/deepseek-tui:latest
|
||||
ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
Use a pinned release tag for reproducible installs:
|
||||
@@ -27,10 +27,10 @@ Use a pinned release tag for reproducible installs:
|
||||
```bash
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
ghcr.io/hmbown/deepseek-tui:vX.Y.Z
|
||||
ghcr.io/hmbown/codewhale:vX.Y.Z
|
||||
```
|
||||
|
||||
Replace `vX.Y.Z` with a tag from
|
||||
@@ -41,7 +41,7 @@ Replace `vX.Y.Z` with a tag from
|
||||
Build the image locally from a checkout:
|
||||
|
||||
```bash
|
||||
docker build -t codewhale-tui .
|
||||
docker build -t codewhale .
|
||||
```
|
||||
|
||||
Then run it with the same Docker-managed data volume:
|
||||
@@ -49,10 +49,10 @@ Then run it with the same Docker-managed data volume:
|
||||
```bash
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
||||
-v codewhale-home:/home/codewhale/.deepseek \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace \
|
||||
codewhale-tui
|
||||
codewhale
|
||||
```
|
||||
|
||||
Docker Hub publishing is not configured; GHCR is the supported prebuilt image
|
||||
@@ -68,13 +68,13 @@ registry.
|
||||
|
||||
## Volumes
|
||||
|
||||
Mount `/home/deepseek/.deepseek` to persist sessions, config, skills, memory,
|
||||
Mount `/home/codewhale/.deepseek` to persist sessions, config, skills, memory,
|
||||
and the offline queue across container restarts. A Docker-managed named volume
|
||||
is the safest default because Docker creates it with ownership the container can
|
||||
write:
|
||||
|
||||
```bash
|
||||
-v codewhale-tui-home:/home/deepseek/.deepseek
|
||||
-v codewhale-home:/home/codewhale/.deepseek
|
||||
```
|
||||
|
||||
Without this mount the container starts fresh each time.
|
||||
@@ -91,8 +91,8 @@ sudo chown -R 1000:1000 ~/.deepseek
|
||||
|
||||
docker run --rm -it \
|
||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||
-v ~/.deepseek:/home/deepseek/.deepseek \
|
||||
ghcr.io/hmbown/deepseek-tui:latest
|
||||
-v ~/.deepseek:/home/codewhale/.deepseek \
|
||||
ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
That `chown` changes ownership of the host `~/.deepseek` directory. Skip it if
|
||||
@@ -106,18 +106,18 @@ When stdin is not a TTY, `codewhale` drops to the dispatcher's one-shot mode
|
||||
|
||||
```bash
|
||||
echo "Explain the Cargo.toml in structured English." | \
|
||||
docker run --rm -i -e DEEPSEEK_API_KEY ghcr.io/hmbown/deepseek-tui:latest
|
||||
docker run --rm -i -e DEEPSEEK_API_KEY ghcr.io/hmbown/codewhale:latest
|
||||
```
|
||||
|
||||
## Building locally
|
||||
|
||||
```bash
|
||||
# Single platform (your host architecture)
|
||||
docker build -t codewhale-tui .
|
||||
docker build -t codewhale .
|
||||
|
||||
# Multi-platform (requires a builder with emulation)
|
||||
docker buildx create --use
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t codewhale-tui .
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t codewhale .
|
||||
```
|
||||
|
||||
## Devcontainer
|
||||
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
# Installing codewhale
|
||||
# Installing Codewhale
|
||||
|
||||
This page covers every supported install path and the most common
|
||||
"it didn't install" failures, including **Linux ARM64** and other less
|
||||
@@ -181,7 +181,7 @@ is fastest from your network.
|
||||
For an always-on workspace that can be controlled from a phone, use the
|
||||
Tencent-native path instead of treating install as a single laptop step:
|
||||
|
||||
- CNB mirror/source: `https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git`
|
||||
- CNB mirror/source: `https://cnb.cool/codewhale.net/codewhale.git`
|
||||
- Tencent Lighthouse HK: `/opt/whalebro` remote workspace
|
||||
- Feishu/Lark: long-connection phone bridge
|
||||
- EdgeOne: optional public HTTPS edge for docs/status/webhook surfaces
|
||||
@@ -278,7 +278,7 @@ curl -L -o /tmp/codewhale-artifacts-sha256.txt \
|
||||
|
||||
### Windows Scoop
|
||||
|
||||
codewhale is listed in Scoop's main bucket:
|
||||
The `codewhale` package is listed in Scoop's main bucket:
|
||||
|
||||
```powershell
|
||||
scoop update
|
||||
@@ -473,8 +473,8 @@ assets. On networks where GitHub is blocked or unreliable, use the CNB source
|
||||
mirror instead and install both binaries from the release tag:
|
||||
|
||||
```bash
|
||||
cargo install --git https://cnb.cool/deepseek-tui.com/DeepSeek-TUI --tag vX.Y.Z codewhale-cli --locked --force
|
||||
cargo install --git https://cnb.cool/deepseek-tui.com/DeepSeek-TUI --tag vX.Y.Z codewhale-tui --locked --force
|
||||
cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-cli --locked --force
|
||||
cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-tui --locked --force
|
||||
```
|
||||
|
||||
If you operate a binary asset mirror, `codewhale update` can use it directly:
|
||||
|
||||
+6
-7
@@ -1,4 +1,4 @@
|
||||
# Rebrand: deepseek-tui → codewhale
|
||||
# Rebrand: DeepSeek TUI → Codewhale
|
||||
|
||||
Starting with **v0.8.41**, this project ships under a new name: `codewhale`.
|
||||
|
||||
@@ -60,7 +60,7 @@ Anything that targets the DeepSeek provider API stays exactly as it was:
|
||||
- **Homebrew tap and formula** (`Hmbown/homebrew-deepseek-tui`): still
|
||||
installs by the legacy name during the transition. The tap's formula
|
||||
will be flipped to the new names in a follow-up.
|
||||
- **Docker image** (`ghcr.io/hmbown/deepseek-tui`): unchanged.
|
||||
- **Docker image**: `ghcr.io/hmbown/codewhale`.
|
||||
|
||||
## Deprecation shims (one release cycle)
|
||||
|
||||
@@ -119,11 +119,10 @@ still verifies.
|
||||
|
||||
## Why the name change
|
||||
|
||||
`codewhale` is a shorter, terminal-friendlier handle that doesn't suggest
|
||||
the project is tied to a single provider. The dispatcher already supports
|
||||
DeepSeek, NVIDIA NIM, OpenAI-compatible endpoints, AtlasCloud, Wanjie Ark,
|
||||
OpenRouter, Novita, Fireworks, SGLang, vLLM, and Ollama, with more on the
|
||||
roadmap. The new name reflects that.
|
||||
Codewhale is a shorter, terminal-friendlier handle for the same terminal
|
||||
coding agent. In v0.8.41 it remains centered on DeepSeek V4 while the project
|
||||
name, command names, package names, release assets, Docker image, and CNB
|
||||
mirror move to Codewhale.
|
||||
|
||||
## Reporting issues with the rename
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ Run, in order, from the repo root:
|
||||
reports the new version on the npm registry.
|
||||
- [ ] `crates.io` has the new version (or the `publish-crates.sh` job has
|
||||
pushed it).
|
||||
- [ ] `ghcr.io/hmbown/deepseek-tui:vX.Y.Z` and `:latest` are updated.
|
||||
- [ ] `ghcr.io/hmbown/codewhale:vX.Y.Z` and `:latest` are updated.
|
||||
|
||||
## 8. Post-tag
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# codewhale Release Runbook
|
||||
# Codewhale Release Runbook
|
||||
|
||||
This runbook is the source of truth for shipping Rust crates, GitHub release assets,
|
||||
and the `codewhale` npm wrapper.
|
||||
@@ -187,13 +187,13 @@ To re-enable automated publish: provision an npm automation token with "Bypass 2
|
||||
## CNB Cool mirror
|
||||
|
||||
Every push to `main`, `fix/*`, `rebrand/*`, `work/v*`, and every `v*` tag is mirrored to
|
||||
`cnb.cool/deepseek-tui.com/DeepSeek-TUI` via the `Sync to CNB` workflow
|
||||
`cnb.cool/codewhale.net/codewhale` via the `Sync to CNB` workflow
|
||||
so users behind GitHub-blocking networks can fetch the source and so CNB can
|
||||
run the heavy Linux CI lane. After a release tag, **verify the mirror caught
|
||||
it** before declaring the release shipped:
|
||||
|
||||
```bash
|
||||
git ls-remote https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git refs/tags/vX.Y.Z
|
||||
git ls-remote https://cnb.cool/codewhale.net/codewhale.git refs/tags/vX.Y.Z
|
||||
```
|
||||
|
||||
If the workflow failed for the release tag, the manual fallback is
|
||||
|
||||
@@ -5,17 +5,17 @@ who want an always-on agent workspace, a phone control surface, and a stack
|
||||
that works well from mainland China.
|
||||
|
||||
It complements the local install path. If you only want to use `codewhale` on a
|
||||
laptop, start with the README quickstart. If you want "DS-TUI as a remote
|
||||
laptop, start with the README quickstart. If you want "Codewhale as a remote
|
||||
workbench I can control from my phone", start here.
|
||||
|
||||
## Default Stack
|
||||
|
||||
```text
|
||||
GitHub main/tags
|
||||
-> CNB mirror: cnb.cool/deepseek-tui.com/DeepSeek-TUI
|
||||
-> CNB mirror: cnb.cool/codewhale.net/codewhale
|
||||
-> optional CNB build/deploy pipeline
|
||||
-> Tencent Lighthouse HK
|
||||
/opt/whalebro/codewhale-tui
|
||||
/opt/whalebro/codewhale
|
||||
/opt/whalebro/worktrees
|
||||
codewhale-runtime.service on 127.0.0.1:7878
|
||||
codewhale-feishu-bridge.service
|
||||
@@ -45,7 +45,7 @@ EdgeOne is optional:
|
||||
2. Clone from CNB by default when the branch or tag exists there:
|
||||
|
||||
```bash
|
||||
export DEEPSEEK_REPO_URL=https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git
|
||||
export DEEPSEEK_REPO_URL=https://cnb.cool/codewhale.net/codewhale.git
|
||||
git ls-remote "$DEEPSEEK_REPO_URL" refs/heads/main
|
||||
```
|
||||
|
||||
@@ -57,8 +57,8 @@ EdgeOne is optional:
|
||||
|
||||
```bash
|
||||
export DEEPSEEK_BRANCH=main
|
||||
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale-tui
|
||||
cd /tmp/codewhale-tui
|
||||
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale
|
||||
cd /tmp/codewhale
|
||||
sudo DEEPSEEK_REPO_URL="$DEEPSEEK_REPO_URL" \
|
||||
DEEPSEEK_REPO_BRANCH="$DEEPSEEK_BRANCH" \
|
||||
bash scripts/tencent-lighthouse/bootstrap-ubuntu.sh
|
||||
@@ -85,7 +85,7 @@ The intended deploy button should:
|
||||
|
||||
1. Run bridge validation/tests and lightweight release-version checks.
|
||||
2. SSH to Lighthouse with a deploy key stored as a CNB secret.
|
||||
3. Update `/opt/whalebro/codewhale-tui`.
|
||||
3. Update `/opt/whalebro/codewhale`.
|
||||
4. Rebuild/install both binaries.
|
||||
5. Reinstall/restart systemd services.
|
||||
6. Run `scripts/tencent-lighthouse/doctor.sh`.
|
||||
|
||||
@@ -11,14 +11,14 @@ is the implementation runbook for the Lighthouse host itself.
|
||||
|
||||
```text
|
||||
CNB mirror or GitHub branch
|
||||
-> /opt/whalebro/codewhale-tui
|
||||
-> /opt/whalebro/codewhale
|
||||
|
||||
Feishu/Lark mobile app
|
||||
-> Feishu/Lark long-connection bot
|
||||
-> codewhale-feishu-bridge systemd service
|
||||
-> http://127.0.0.1:7878 codewhale serve --http
|
||||
-> /opt/whalebro
|
||||
-> codewhale-tui/
|
||||
-> codewhale/
|
||||
|
||||
Optional public edge:
|
||||
EdgeOne -> Caddy/Nginx public site on Lighthouse
|
||||
@@ -31,11 +31,11 @@ HTTP service, not the runtime API.
|
||||
## Remote Whalebro Workspace
|
||||
|
||||
Use `/opt/whalebro` as the VPS workspace root. The first-class checkout is
|
||||
`/opt/whalebro/codewhale-tui`.
|
||||
`/opt/whalebro/codewhale`.
|
||||
|
||||
Create these paths first:
|
||||
|
||||
- `/opt/whalebro/codewhale-tui`
|
||||
- `/opt/whalebro/codewhale`
|
||||
- `/opt/whalebro/worktrees`
|
||||
|
||||
Linux is enough for Rust, Node, and service work. Mac-only release work such
|
||||
@@ -87,9 +87,9 @@ SSH into the Lighthouse instance and run:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y git
|
||||
export DEEPSEEK_BRANCH=main
|
||||
export DEEPSEEK_REPO_URL=https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git
|
||||
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale-tui
|
||||
cd /tmp/codewhale-tui
|
||||
export DEEPSEEK_REPO_URL=https://cnb.cool/codewhale.net/codewhale.git
|
||||
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale
|
||||
cd /tmp/codewhale
|
||||
sudo DEEPSEEK_REPO_URL="$DEEPSEEK_REPO_URL" \
|
||||
DEEPSEEK_REPO_BRANCH="$DEEPSEEK_BRANCH" \
|
||||
bash scripts/tencent-lighthouse/bootstrap-ubuntu.sh
|
||||
@@ -106,7 +106,7 @@ For stable release docs, confirm the CNB mirror has the branch or tag before
|
||||
using it:
|
||||
|
||||
```bash
|
||||
export DEEPSEEK_REPO_URL=https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git
|
||||
export DEEPSEEK_REPO_URL=https://cnb.cool/codewhale.net/codewhale.git
|
||||
git ls-remote "$DEEPSEEK_REPO_URL" \
|
||||
refs/heads/main \
|
||||
refs/tags/v0.8.37
|
||||
@@ -129,7 +129,7 @@ sed -n '1,120p' /tmp/rustup-init.sh
|
||||
sh /tmp/rustup-init.sh -y --profile minimal
|
||||
. "$HOME/.cargo/env"
|
||||
rustup default stable
|
||||
cd /opt/whalebro/codewhale-tui
|
||||
cd /opt/whalebro/codewhale
|
||||
cargo install --path crates/cli --locked --force
|
||||
cargo install --path crates/tui --locked --force
|
||||
exit
|
||||
@@ -138,14 +138,14 @@ exit
|
||||
Copy and install the bridge/service files:
|
||||
|
||||
```bash
|
||||
cd /opt/whalebro/codewhale-tui
|
||||
cd /opt/whalebro/codewhale
|
||||
sudo bash scripts/tencent-lighthouse/install-services.sh
|
||||
```
|
||||
|
||||
After editing both env files, validate the bridge/runtime pairing:
|
||||
|
||||
```bash
|
||||
sudo -u codewhale node /opt/deepseek/bridge/scripts/validate-config.mjs \
|
||||
sudo -u codewhale node /opt/codewhale/bridge/scripts/validate-config.mjs \
|
||||
--env /etc/deepseek/feishu-bridge.env \
|
||||
--runtime-env /etc/deepseek/runtime.env \
|
||||
--workspace-root /opt/whalebro \
|
||||
@@ -196,7 +196,7 @@ sudo journalctl -u codewhale-feishu-bridge -f
|
||||
Run the Lighthouse doctor after both services are configured:
|
||||
|
||||
```bash
|
||||
cd /opt/whalebro/codewhale-tui
|
||||
cd /opt/whalebro/codewhale
|
||||
sudo bash scripts/tencent-lighthouse/doctor.sh
|
||||
```
|
||||
|
||||
@@ -289,5 +289,5 @@ From a phone DM to the bot:
|
||||
- Keep the Lighthouse firewall focused on SSH for this setup.
|
||||
- Use SSH key auth.
|
||||
- Use `tmux` for emergency terminal work from Blink/Termius.
|
||||
- Keep `/opt/whalebro/codewhale-tui` on a personal branch while working from the
|
||||
- Keep `/opt/whalebro/codewhale` on a personal branch while working from the
|
||||
phone.
|
||||
|
||||
@@ -39,15 +39,20 @@
|
||||
{
|
||||
packages = forEachSystem (
|
||||
{ pkgs, system }:
|
||||
{
|
||||
default = self.packages.${system}.deepseek-tui;
|
||||
deepseek-tui = pkgs.callPackage ./nix/package.nix {
|
||||
let
|
||||
codewhale = pkgs.callPackage ./nix/package.nix {
|
||||
inherit rev;
|
||||
rustPlatform = pkgs.makeRustPlatform {
|
||||
cargo = pkgs.rustToolchain;
|
||||
rustc = pkgs.rustToolchain;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
default = codewhale;
|
||||
codewhale = codewhale;
|
||||
# Compatibility alias for existing Nix users during the rename.
|
||||
deepseek-tui = codewhale;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ DEEPSEEK_AUTO_APPROVE=false
|
||||
DEEPSEEK_CHAT_ALLOWLIST=
|
||||
DEEPSEEK_ALLOW_UNLISTED=false
|
||||
|
||||
FEISHU_THREAD_MAP_PATH=/var/lib/deepseek-feishu-bridge/thread-map.json
|
||||
FEISHU_THREAD_MAP_PATH=/var/lib/codewhale-feishu-bridge/thread-map.json
|
||||
FEISHU_ALLOW_GROUPS=false
|
||||
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
||||
FEISHU_GROUP_PREFIX=/ds
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Feishu / Lark Bridge
|
||||
|
||||
This bridge lets a Feishu or Lark chat control a local `deepseek serve --http`
|
||||
This bridge lets a Feishu or Lark chat control a local `codewhale serve --http`
|
||||
runtime from a phone. It uses the official Lark/Feishu Node SDK long-connection
|
||||
mode, so the first version does not need a public webhook URL.
|
||||
|
||||
Security model:
|
||||
|
||||
- `deepseek serve --http` stays bound to `127.0.0.1`.
|
||||
- `codewhale serve --http` stays bound to `127.0.0.1`.
|
||||
- `/v1/*` runtime calls use `DEEPSEEK_RUNTIME_TOKEN`.
|
||||
- Feishu/Lark chats must be allowlisted unless `DEEPSEEK_ALLOW_UNLISTED=true`
|
||||
is set for first pairing.
|
||||
@@ -17,7 +17,7 @@ Security model:
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
cd /opt/deepseek/bridge
|
||||
cd /opt/codewhale/bridge
|
||||
npm install --omit=dev
|
||||
cp .env.example /etc/deepseek/feishu-bridge.env
|
||||
sudoedit /etc/deepseek/feishu-bridge.env
|
||||
@@ -37,8 +37,8 @@ npm run validate:config -- \
|
||||
For a Tencent Lighthouse deployment, use:
|
||||
|
||||
```bash
|
||||
sudo systemctl enable --now deepseek-runtime deepseek-feishu-bridge
|
||||
sudo journalctl -u deepseek-feishu-bridge -f
|
||||
sudo systemctl enable --now codewhale-runtime codewhale-feishu-bridge
|
||||
sudo journalctl -u codewhale-feishu-bridge -f
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "@deepseek-tui/feishu-bridge",
|
||||
"name": "@codewhale/feishu-bridge",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@deepseek-tui/feishu-bridge",
|
||||
"name": "@codewhale/feishu-bridge",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@larksuiteoapi/node-sdk": "^1.52.0"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "@deepseek-tui/feishu-bridge",
|
||||
"name": "@codewhale/feishu-bridge",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "Feishu/Lark mobile bridge for a local deepseek serve --http runtime.",
|
||||
"description": "Feishu/Lark mobile bridge for a local codewhale serve --http runtime.",
|
||||
"main": "src/index.mjs",
|
||||
"scripts": {
|
||||
"start": "node src/index.mjs",
|
||||
|
||||
@@ -99,7 +99,7 @@ const config = {
|
||||
allowUnlisted: parseBool(process.env.DEEPSEEK_ALLOW_UNLISTED, false),
|
||||
threadMapPath:
|
||||
process.env.FEISHU_THREAD_MAP_PATH ||
|
||||
"/var/lib/deepseek-feishu-bridge/thread-map.json",
|
||||
"/var/lib/codewhale-feishu-bridge/thread-map.json",
|
||||
allowGroups: parseBool(process.env.FEISHU_ALLOW_GROUPS, false),
|
||||
requirePrefixInGroup: parseBool(process.env.FEISHU_REQUIRE_PREFIX_IN_GROUP, true),
|
||||
groupPrefix: process.env.FEISHU_GROUP_PREFIX || "/ds",
|
||||
|
||||
@@ -160,7 +160,7 @@ test("validateBridgeConfig accepts locked-down whalebro DM config", () => {
|
||||
DEEPSEEK_WORKSPACE: "/opt/whalebro",
|
||||
DEEPSEEK_CHAT_ALLOWLIST: "oc_allowed",
|
||||
DEEPSEEK_ALLOW_UNLISTED: "false",
|
||||
FEISHU_THREAD_MAP_PATH: "/var/lib/deepseek-feishu-bridge/thread-map.json",
|
||||
FEISHU_THREAD_MAP_PATH: "/var/lib/codewhale-feishu-bridge/thread-map.json",
|
||||
FEISHU_ALLOW_GROUPS: "false",
|
||||
FEISHU_REQUIRE_PREFIX_IN_GROUP: "true"
|
||||
},
|
||||
@@ -187,7 +187,7 @@ test("validateBridgeConfig rejects unsafe group pairing and token mismatch", ()
|
||||
DEEPSEEK_RUNTIME_TOKEN: "bridge-token",
|
||||
DEEPSEEK_WORKSPACE: "/opt/whalebro",
|
||||
DEEPSEEK_ALLOW_UNLISTED: "true",
|
||||
FEISHU_THREAD_MAP_PATH: "/var/lib/deepseek-feishu-bridge/thread-map.json",
|
||||
FEISHU_THREAD_MAP_PATH: "/var/lib/codewhale-feishu-bridge/thread-map.json",
|
||||
FEISHU_ALLOW_GROUPS: "true",
|
||||
FEISHU_REQUIRE_PREFIX_IN_GROUP: "false"
|
||||
},
|
||||
|
||||
+5
-5
@@ -15,7 +15,7 @@
|
||||
rev ? "dirty",
|
||||
}:
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "deepseek-tui";
|
||||
pname = "codewhale";
|
||||
version = "git-${rev}";
|
||||
|
||||
src = ../.;
|
||||
@@ -46,9 +46,9 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
|
||||
cargoBuildFlags = [
|
||||
"--package"
|
||||
"deepseek-tui-cli"
|
||||
"codewhale-cli"
|
||||
"--package"
|
||||
"deepseek-tui"
|
||||
"codewhale-tui"
|
||||
];
|
||||
cargoTestFlags = finalAttrs.cargoBuildFlags ++ [
|
||||
"--lib"
|
||||
@@ -60,9 +60,9 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Coding agent for DeepSeek models that runs in your terminal";
|
||||
description = "Terminal coding agent for DeepSeek";
|
||||
homepage = "https://github.com/Hmbown/DeepSeek-TUI";
|
||||
license = lib.licenses.mit;
|
||||
mainProgram = "deepseek";
|
||||
mainProgram = "codewhale";
|
||||
};
|
||||
})
|
||||
|
||||
@@ -6,8 +6,8 @@ if [[ "${EUID}" -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEEPSEEK_USER="${DEEPSEEK_USER:-deepseek}"
|
||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/deepseek}"
|
||||
DEEPSEEK_USER="${DEEPSEEK_USER:-codewhale}"
|
||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/codewhale}"
|
||||
WHALEBRO_ROOT="${WHALEBRO_ROOT:-/opt/whalebro}"
|
||||
REPO_URL="${DEEPSEEK_REPO_URL:-https://github.com/Hmbown/DeepSeek-TUI.git}"
|
||||
WHALEBRO_EXTRA_REPOS="${WHALEBRO_EXTRA_REPOS:-}"
|
||||
@@ -47,10 +47,10 @@ install -d -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" "${DEEPSEEK_ROOT}/bridge"
|
||||
install -d -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" "${WHALEBRO_ROOT}"
|
||||
install -d -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" "${WHALEBRO_ROOT}/worktrees"
|
||||
install -d -m 0750 -o root -g "${DEEPSEEK_USER}" /etc/deepseek
|
||||
install -d -m 0700 -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" /var/lib/deepseek-feishu-bridge
|
||||
install -d -m 0700 -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" /var/lib/codewhale-feishu-bridge
|
||||
|
||||
if [[ ! -d "${WHALEBRO_ROOT}/deepseek-tui/.git" ]]; then
|
||||
sudo -u "${DEEPSEEK_USER}" git clone --branch "${REPO_BRANCH}" "${REPO_URL}" "${WHALEBRO_ROOT}/deepseek-tui"
|
||||
if [[ ! -d "${WHALEBRO_ROOT}/codewhale/.git" ]]; then
|
||||
sudo -u "${DEEPSEEK_USER}" git clone --branch "${REPO_BRANCH}" "${REPO_URL}" "${WHALEBRO_ROOT}/codewhale"
|
||||
fi
|
||||
|
||||
for repo_spec in ${WHALEBRO_EXTRA_REPOS}; do
|
||||
@@ -94,7 +94,7 @@ DEEPSEEK_TRUST_MODE=false
|
||||
DEEPSEEK_AUTO_APPROVE=false
|
||||
DEEPSEEK_CHAT_ALLOWLIST=
|
||||
DEEPSEEK_ALLOW_UNLISTED=false
|
||||
FEISHU_THREAD_MAP_PATH=/var/lib/deepseek-feishu-bridge/thread-map.json
|
||||
FEISHU_THREAD_MAP_PATH=/var/lib/codewhale-feishu-bridge/thread-map.json
|
||||
FEISHU_ALLOW_GROUPS=false
|
||||
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
||||
FEISHU_GROUP_PREFIX=/ds
|
||||
@@ -116,7 +116,7 @@ Next:
|
||||
1. Install Rust 1.88+ for ${DEEPSEEK_USER}; rustup is the usual path.
|
||||
2. Build/install both binaries:
|
||||
sudo -iu ${DEEPSEEK_USER}
|
||||
cd ${WHALEBRO_ROOT}/deepseek-tui
|
||||
cd ${WHALEBRO_ROOT}/codewhale
|
||||
cargo install --path crates/cli --locked --force
|
||||
cargo install --path crates/tui --locked --force
|
||||
3. Copy integrations/feishu-bridge to ${DEEPSEEK_ROOT}/bridge and run npm install.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
DEEPSEEK_USER="${DEEPSEEK_USER:-deepseek}"
|
||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/deepseek}"
|
||||
DEEPSEEK_USER="${DEEPSEEK_USER:-codewhale}"
|
||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/codewhale}"
|
||||
WHALEBRO_ROOT="${WHALEBRO_ROOT:-/opt/whalebro}"
|
||||
RUNTIME_ENV="${RUNTIME_ENV:-/etc/deepseek/runtime.env}"
|
||||
BRIDGE_ENV="${BRIDGE_ENV:-/etc/deepseek/feishu-bridge.env}"
|
||||
BRIDGE_DIR="${BRIDGE_DIR:-${DEEPSEEK_ROOT}/bridge}"
|
||||
REPO_ROOT="${REPO_ROOT:-${WHALEBRO_ROOT}/deepseek-tui}"
|
||||
REPO_ROOT="${REPO_ROOT:-${WHALEBRO_ROOT}/codewhale}"
|
||||
|
||||
failures=0
|
||||
warnings=0
|
||||
@@ -97,15 +97,15 @@ check_workspace() {
|
||||
}
|
||||
|
||||
check_binaries() {
|
||||
section "DeepSeek binaries"
|
||||
section "Codewhale binaries"
|
||||
local cargo_bin="/home/${DEEPSEEK_USER}/.cargo/bin"
|
||||
local deepseek="${cargo_bin}/deepseek"
|
||||
local tui="${cargo_bin}/deepseek-tui"
|
||||
if [[ -x "${deepseek}" ]]; then
|
||||
pass "${deepseek} is executable"
|
||||
"${deepseek}" --version 2>/dev/null | sed 's/^/[info] deepseek version: /' || warn "deepseek --version failed"
|
||||
local codewhale="${cargo_bin}/codewhale"
|
||||
local tui="${cargo_bin}/codewhale-tui"
|
||||
if [[ -x "${codewhale}" ]]; then
|
||||
pass "${codewhale} is executable"
|
||||
"${codewhale}" --version 2>/dev/null | sed 's/^/[info] codewhale version: /' || warn "codewhale --version failed"
|
||||
else
|
||||
fail "${deepseek} is missing or not executable"
|
||||
fail "${codewhale} is missing or not executable"
|
||||
fi
|
||||
if [[ -x "${tui}" ]]; then
|
||||
pass "${tui} is executable"
|
||||
@@ -205,7 +205,7 @@ check_systemd() {
|
||||
warn "systemd is not available in this environment"
|
||||
return
|
||||
fi
|
||||
for unit in deepseek-runtime deepseek-feishu-bridge; do
|
||||
for unit in codewhale-runtime codewhale-feishu-bridge; do
|
||||
[[ -f "/etc/systemd/system/${unit}.service" ]] \
|
||||
&& pass "${unit}.service is installed" \
|
||||
|| fail "${unit}.service is missing"
|
||||
|
||||
@@ -7,8 +7,8 @@ if [[ "${EUID}" -ne 0 ]]; then
|
||||
fi
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
DEEPSEEK_USER="${DEEPSEEK_USER:-deepseek}"
|
||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/deepseek}"
|
||||
DEEPSEEK_USER="${DEEPSEEK_USER:-codewhale}"
|
||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/codewhale}"
|
||||
|
||||
install -d -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" "${DEEPSEEK_ROOT}/bridge"
|
||||
rsync -a --delete \
|
||||
@@ -23,11 +23,11 @@ else
|
||||
sudo -u "${DEEPSEEK_USER}" npm --prefix "${DEEPSEEK_ROOT}/bridge" install --omit=dev
|
||||
fi
|
||||
|
||||
install -m 0644 "${REPO_ROOT}/deploy/tencent-lighthouse/systemd/deepseek-runtime.service" /etc/systemd/system/deepseek-runtime.service
|
||||
install -m 0644 "${REPO_ROOT}/deploy/tencent-lighthouse/systemd/deepseek-feishu-bridge.service" /etc/systemd/system/deepseek-feishu-bridge.service
|
||||
install -m 0644 "${REPO_ROOT}/deploy/tencent-lighthouse/systemd/codewhale-runtime.service" /etc/systemd/system/codewhale-runtime.service
|
||||
install -m 0644 "${REPO_ROOT}/deploy/tencent-lighthouse/systemd/codewhale-feishu-bridge.service" /etc/systemd/system/codewhale-feishu-bridge.service
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable deepseek-runtime deepseek-feishu-bridge
|
||||
systemctl enable codewhale-runtime codewhale-feishu-bridge
|
||||
|
||||
cat <<'EOF'
|
||||
Services installed but not started.
|
||||
@@ -35,11 +35,11 @@ Services installed but not started.
|
||||
Before starting, verify:
|
||||
/etc/deepseek/runtime.env
|
||||
/etc/deepseek/feishu-bridge.env
|
||||
sudo -u deepseek node /opt/deepseek/bridge/scripts/validate-config.mjs --env /etc/deepseek/feishu-bridge.env --runtime-env /etc/deepseek/runtime.env --workspace-root /opt/whalebro --check-filesystem
|
||||
sudo -u codewhale node /opt/codewhale/bridge/scripts/validate-config.mjs --env /etc/deepseek/feishu-bridge.env --runtime-env /etc/deepseek/runtime.env --workspace-root /opt/whalebro --check-filesystem
|
||||
|
||||
Then run:
|
||||
sudo systemctl start deepseek-runtime
|
||||
sudo systemctl start deepseek-feishu-bridge
|
||||
sudo bash /opt/whalebro/deepseek-tui/scripts/tencent-lighthouse/doctor.sh
|
||||
sudo journalctl -u deepseek-feishu-bridge -f
|
||||
sudo systemctl start codewhale-runtime
|
||||
sudo systemctl start codewhale-feishu-bridge
|
||||
sudo bash /opt/whalebro/codewhale/scripts/tencent-lighthouse/doctor.sh
|
||||
sudo journalctl -u codewhale-feishu-bridge -f
|
||||
EOF
|
||||
|
||||
Reference in New Issue
Block a user