chore(rebrand): finish codewhale release surfaces
This commit is contained in:
@@ -323,7 +323,7 @@ jobs:
|
|||||||
files: artifacts/*/*
|
files: artifacts/*/*
|
||||||
prerelease: false
|
prerelease: false
|
||||||
body: |
|
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
|
> `deepseek` and `deepseek-tui` binaries continue to ship as
|
||||||
> deprecation shims for one release cycle; they print a one-line
|
> deprecation shims for one release cycle; they print a one-line
|
||||||
> warning and forward to `codewhale` / `codewhale-tui`. They will
|
> warning and forward to `codewhale` / `codewhale-tui`. They will
|
||||||
@@ -345,8 +345,8 @@ jobs:
|
|||||||
```bash
|
```bash
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v ~/.deepseek:/home/deepseek/.deepseek \
|
-v ~/.deepseek:/home/codewhale/.deepseek \
|
||||||
ghcr.io/hmbown/deepseek-tui:${{ needs.resolve.outputs.tag }}
|
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.
|
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
|
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
|
# so users behind GitHub-blocking networks can fetch the source and tagged
|
||||||
# releases from the Tencent-hosted mirror.
|
# releases from the Tencent-hosted mirror.
|
||||||
#
|
#
|
||||||
@@ -69,7 +69,7 @@ jobs:
|
|||||||
# special characters. CNB tokens are typically alphanumeric so
|
# special characters. CNB tokens are typically alphanumeric so
|
||||||
# this is belt-and-suspenders.
|
# 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=""))')"
|
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.
|
# Use a masked alias so the token never appears in log lines.
|
||||||
git remote add cnb "${REMOTE_URL}"
|
git remote add cnb "${REMOTE_URL}"
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ This file provides context for AI assistants working on this project.
|
|||||||
## Project Type: Rust
|
## Project Type: Rust
|
||||||
|
|
||||||
### Commands
|
### 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`
|
- Test: `cargo test --workspace --all-features`
|
||||||
- Lint: `cargo clippy --workspace --all-targets --all-features`
|
- Lint: `cargo clippy --workspace --all-targets --all-features`
|
||||||
- Format: `cargo fmt --all`
|
- 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 (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 deepseek` (or `cargo run -p deepseek-tui-cli`).
|
- Run from source: `cargo run --bin codewhale` (or `cargo run -p codewhale-cli`).
|
||||||
- Local dev shorthand: after `cargo build --release`, run `./target/release/deepseek`.
|
- Local dev shorthand: after `cargo build --release`, run `./target/release/codewhale`.
|
||||||
- **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:
|
- **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
|
```bash
|
||||||
cargo install --path crates/cli --locked --force
|
cargo install --path crates/cli --locked --force
|
||||||
cargo install --path crates/tui --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
|
### Build Dependencies
|
||||||
- **Rust** 1.88+ (the workspace declares `rust-version = "1.88"` because we
|
- **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)
|
## 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:**
|
**To survive a multi-hour sprint:**
|
||||||
|
|
||||||
|
|||||||
+23
-19
@@ -1,17 +1,16 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# 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 .
|
# Build: docker buildx build --platform linux/amd64,linux/arm64 -t codewhale:latest .
|
||||||
# Run: docker run --rm -it -e DEEPSEEK_API_KEY -v deepseek-tui-home:/home/deepseek/.deepseek deepseek-tui
|
# 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)
|
# The image ships the canonical binaries (`codewhale`, `codewhale-tui`) plus
|
||||||
# in a minimal runtime layer. No MCP servers or heavy toolchains are included
|
# the legacy `deepseek` / `deepseek-tui` shims in a minimal runtime layer.
|
||||||
# — keep it slim.
|
|
||||||
#
|
#
|
||||||
# API keys MUST be passed at runtime (never baked into the image):
|
# 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:
|
# 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
|
ARG RUST_VERSION=1.88
|
||||||
|
|
||||||
@@ -56,11 +55,14 @@ COPY . .
|
|||||||
|
|
||||||
# Build both binaries for the target platform. --locked ensures
|
# Build both binaries for the target platform. --locked ensures
|
||||||
# reproducible builds from the committed lockfile.
|
# reproducible builds from the committed lockfile.
|
||||||
RUN --mount=type=cache,id=deepseek-tui-target-${TARGETARCH},target=/build/target,sharing=locked \
|
RUN --mount=type=cache,id=codewhale-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=codewhale-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 \
|
--mount=type=cache,id=codewhale-cargo-git-${TARGETARCH},target=/usr/local/cargo/git,sharing=locked \
|
||||||
cargo build --release --locked --target "$(cat /rust-target)" \
|
cargo build --release --locked --target "$(cat /rust-target)" \
|
||||||
|
-p codewhale-cli -p codewhale-tui \
|
||||||
&& mkdir -p /out \
|
&& 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 /out/ \
|
||||||
&& cp target/$(cat /rust-target)/release/deepseek-tui /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/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Non-root user with explicit UID/GID for filesystem ownership clarity.
|
# Non-root user with explicit UID/GID for filesystem ownership clarity.
|
||||||
RUN groupadd --gid 1000 deepseek \
|
RUN groupadd --gid 1000 codewhale \
|
||||||
&& useradd --create-home --shell /bin/bash --uid 1000 --gid 1000 deepseek \
|
&& useradd --create-home --shell /bin/bash --uid 1000 --gid 1000 codewhale \
|
||||||
&& install -d -m 0700 -o deepseek -g deepseek /home/deepseek/.deepseek
|
&& install -d -m 0700 -o codewhale -g codewhale /home/codewhale/.deepseek
|
||||||
USER deepseek
|
USER codewhale
|
||||||
WORKDIR /home/deepseek
|
WORKDIR /home/codewhale
|
||||||
|
|
||||||
COPY --from=builder --chown=deepseek:deepseek /out/deepseek /usr/local/bin/deepseek
|
COPY --from=builder --chown=codewhale:codewhale /out/codewhale /usr/local/bin/codewhale
|
||||||
COPY --from=builder --chown=deepseek:deepseek /out/deepseek-tui /usr/local/bin/deepseek-tui
|
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.
|
# The dispatcher expects to find its companion binary next to it.
|
||||||
# Both are in /usr/local/bin — no further path setup needed.
|
# Both are in /usr/local/bin — no further path setup needed.
|
||||||
|
|
||||||
ENTRYPOINT ["deepseek"]
|
ENTRYPOINT ["codewhale"]
|
||||||
CMD []
|
CMD []
|
||||||
|
|||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
# 🐳 codewhale
|
# 🐳 Codewhale
|
||||||
|
|
||||||
> **このターミナルネイティブのコーディングエージェントは、DeepSeek V4 の 100 万トークンのコンテキストウィンドウとプレフィックスキャッシュ機能を中心に構築されています。単一のバイナリとして配布され、Node.js や Python のランタイムは不要です。MCP クライアント、サンドボックス、永続的なタスクキューも標準で同梱されています。**
|
> **このターミナルネイティブのコーディングエージェントは、DeepSeek V4 の 100 万トークンのコンテキストウィンドウとプレフィックスキャッシュ機能を中心に構築されています。単一のバイナリとして配布され、Node.js や Python のランタイムは不要です。MCP クライアント、サンドボックス、永続的なタスクキューも標準で同梱されています。**
|
||||||
|
|
||||||
@@ -28,13 +28,13 @@ brew install deepseek-tui
|
|||||||
# Linux x64/ARM64、macOS x64/ARM64、Windows x64 向けのビルド済みバイナリがあります。
|
# Linux x64/ARM64、macOS x64/ARM64、Windows x64 向けのビルド済みバイナリがあります。
|
||||||
|
|
||||||
# 5. Docker — ビルド済みリリースイメージ。
|
# 5. Docker — ビルド済みリリースイメージ。
|
||||||
docker volume create codewhale-tui-home
|
docker volume create codewhale-home
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
ghcr.io/hmbown/deepseek-tui:latest
|
ghcr.io/hmbown/codewhale:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
> 中国本土では、`--registry=https://registry.npmmirror.com` を指定して npm 経由のダウンロードを高速化するか、下記の[Cargo ミラー](#中国--ミラーフレンドリーなインストール)を利用してください。
|
> 中国本土では、`--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.
|
> 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.
|
# Prebuilt for Linux x64/ARM64, macOS x64/ARM64, Windows x64.
|
||||||
|
|
||||||
# 5. Docker — prebuilt release image.
|
# 5. Docker — prebuilt release image.
|
||||||
docker volume create codewhale-tui-home
|
docker volume create codewhale-home
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
ghcr.io/hmbown/deepseek-tui:latest
|
ghcr.io/hmbown/codewhale:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
> In mainland China, speed up the npm path with
|
> In mainland China, speed up the npm path with
|
||||||
@@ -72,7 +72,7 @@ cargo install codewhale-tui --locked --force
|
|||||||
|
|
||||||
## What Is It?
|
## 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.
|
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
|
### 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.
|
- **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.
|
- **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)
|
### 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
|
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
|
GitHub/npm/Cargo release. Run `scoop update` first, then verify the installed
|
||||||
version with `codewhale --version`:
|
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:
|
Docker images are published to GHCR for release builds:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker volume create codewhale-tui-home
|
docker volume create codewhale-home
|
||||||
|
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /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,
|
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 客户端、沙箱和持久化任务队列。**
|
> **面向 [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
|
# 覆盖 Linux x64/ARM64、macOS x64/ARM64、Windows x64
|
||||||
|
|
||||||
# 5. Docker —— 预构建发布镜像。
|
# 5. Docker —— 预构建发布镜像。
|
||||||
docker volume create codewhale-tui-home
|
docker volume create codewhale-home
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
ghcr.io/hmbown/deepseek-tui:latest
|
ghcr.io/hmbown/codewhale:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
> 中国大陆访问较慢时,npm 可加 `--registry=https://registry.npmmirror.com`,
|
> 中国大陆访问较慢时,npm 可加 `--registry=https://registry.npmmirror.com`,
|
||||||
@@ -316,14 +316,14 @@ codewhale update # 检查并应用二进制更新
|
|||||||
Docker 镜像发布在 GHCR 上:
|
Docker 镜像发布在 GHCR 上:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker volume create codewhale-tui-home
|
docker volume create codewhale-home
|
||||||
|
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
ghcr.io/hmbown/deepseek-tui:latest
|
ghcr.io/hmbown/codewhale:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
固定 tag、本地构建、volume 权限和非交互管道用法见 [docs/DOCKER.md](docs/DOCKER.md)。
|
固定 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.).
|
# 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
|
# max_workspace_gb = 2 # Snapshots self-disable on first init when the
|
||||||
# # non-excluded workspace exceeds this size in GB
|
# # non-excluded workspace exceeds this size in GB
|
||||||
# # (v0.8.32). Default 2 GB protects against running
|
# # (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
|
# # of datasets / model weights / docker dumps where
|
||||||
# # `git add -A` would hang the TUI for hours. Set
|
# # `git add -A` would hang the TUI for hours. Set
|
||||||
# # to 0 to disable the cap (v0.8.31 behaviour);
|
# # to 0 to disable the cap (v0.8.31 behaviour);
|
||||||
@@ -530,7 +530,7 @@ default_text_model = "deepseek-ai/deepseek-v4-pro"
|
|||||||
#
|
#
|
||||||
# [[hooks.hooks]]
|
# [[hooks.hooks]]
|
||||||
# event = "session_start"
|
# event = "session_start"
|
||||||
# command = "echo 'DeepSeek TUI session started'"
|
# command = "echo 'Codewhale session started'"
|
||||||
#
|
#
|
||||||
# # Inject ephemeral creds into every shell call. Output one
|
# # Inject ephemeral creds into every shell call. Output one
|
||||||
# # KEY=VALUE per line on stdout (export prefix optional).
|
# # KEY=VALUE per line on stdout (export prefix optional).
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ struct Cli {
|
|||||||
enum Commands {
|
enum Commands {
|
||||||
/// Run interactive/non-interactive flows via the TUI binary.
|
/// Run interactive/non-interactive flows via the TUI binary.
|
||||||
Run(RunArgs),
|
Run(RunArgs),
|
||||||
/// Run DeepSeek TUI diagnostics.
|
/// Run Codewhale diagnostics.
|
||||||
Doctor(TuiPassthroughArgs),
|
Doctor(TuiPassthroughArgs),
|
||||||
/// List live DeepSeek API models via the TUI binary.
|
/// List live DeepSeek API models via the TUI binary.
|
||||||
Models(TuiPassthroughArgs),
|
Models(TuiPassthroughArgs),
|
||||||
@@ -129,7 +129,7 @@ enum Commands {
|
|||||||
Init(TuiPassthroughArgs),
|
Init(TuiPassthroughArgs),
|
||||||
/// Bootstrap MCP config and/or skills directories.
|
/// Bootstrap MCP config and/or skills directories.
|
||||||
Setup(TuiPassthroughArgs),
|
Setup(TuiPassthroughArgs),
|
||||||
/// Run the DeepSeek TUI non-interactive agent command.
|
/// Run the Codewhale non-interactive agent command.
|
||||||
#[command(after_help = "\
|
#[command(after_help = "\
|
||||||
Common forwarded flags:
|
Common forwarded flags:
|
||||||
--auto Enable agentic mode with tool access
|
--auto Enable agentic mode with tool access
|
||||||
@@ -140,7 +140,7 @@ Common forwarded flags:
|
|||||||
--output-format <FORMAT> Output format: text or stream-json
|
--output-format <FORMAT> Output format: text or stream-json
|
||||||
")]
|
")]
|
||||||
Exec(TuiPassthroughArgs),
|
Exec(TuiPassthroughArgs),
|
||||||
/// Run a DeepSeek-powered code review over a git diff.
|
/// Run a Codewhale-powered code review over a git diff.
|
||||||
Review(TuiPassthroughArgs),
|
Review(TuiPassthroughArgs),
|
||||||
/// Apply a patch file or stdin to the working tree.
|
/// Apply a patch file or stdin to the working tree.
|
||||||
Apply(TuiPassthroughArgs),
|
Apply(TuiPassthroughArgs),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use std::io::Write;
|
|||||||
|
|
||||||
const CHECKSUM_MANIFEST_ASSET: &str = "codewhale-artifacts-sha256.txt";
|
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 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 RELEASE_BASE_URL_ENV: &str = "DEEPSEEK_TUI_RELEASE_BASE_URL";
|
||||||
const LEGACY_RELEASE_BASE_URL_ENV: &str = "DEEPSEEK_RELEASE_BASE_URL";
|
const LEGACY_RELEASE_BASE_URL_ENV: &str = "DEEPSEEK_RELEASE_BASE_URL";
|
||||||
const UPDATE_VERSION_ENV: &str = "DEEPSEEK_TUI_VERSION";
|
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() {
|
match std::env::var("CARGO_CFG_TARGET_ENV").as_deref() {
|
||||||
Ok("msvc") => println!("cargo:rustc-link-arg-bin=deepseek-tui=/STACK:8388608"),
|
Ok("msvc") => {
|
||||||
Ok("gnu") => println!("cargo:rustc-link-arg-bin=deepseek-tui=-Wl,--stack,8388608"),
|
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 mut out = String::new();
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
out,
|
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);
|
||||||
let _ = writeln!(out, "Write or update `.deepseek/handoff.md`.");
|
let _ = writeln!(out, "Write or update `.deepseek/handoff.md`.");
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ impl PrefixChange {
|
|||||||
/// Monitors and manages prefix-cache stability across turns.
|
/// Monitors and manages prefix-cache stability across turns.
|
||||||
///
|
///
|
||||||
/// This is the core abstraction, mirroring Reasonix's `ImmutablePrefix`
|
/// 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.
|
/// system prompt is rebuilt each turn and tools are registered at startup.
|
||||||
///
|
///
|
||||||
/// Usage:
|
/// 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
|
//! This module handles loading project-specific context files that provide
|
||||||
//! instructions and context to the AI agent. These include:
|
//! instructions and context to the AI agent. These include:
|
||||||
@@ -529,7 +529,7 @@ fn auto_generate_context(workspace: &Path) -> Option<String> {
|
|||||||
|
|
||||||
let content = format!(
|
let content = format!(
|
||||||
"# Project Structure (Auto-generated)\n\n\
|
"# 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\
|
> You can edit or delete it at any time.\n\n\
|
||||||
**Summary:** {summary}\n\n\
|
**Summary:** {summary}\n\n\
|
||||||
**Tree:**\n```\n{tree}\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
|
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
|
## File Location
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//! Sandbox module for secure command execution.
|
//! Sandbox module for secure command execution.
|
||||||
//!
|
//!
|
||||||
//! This module provides sandboxing capabilities for shell commands executed by
|
//! 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.
|
//! preventing accidental or malicious damage to the system.
|
||||||
//!
|
//!
|
||||||
//! # Platform Support
|
//! # Platform Support
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pub enum SandboxPolicy {
|
|||||||
|
|
||||||
/// Indicates the process is already running in an external sandbox.
|
/// 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
|
/// VM, or other sandboxed environment. This avoids double-sandboxing
|
||||||
/// which can cause issues.
|
/// which can cause issues.
|
||||||
#[serde(rename = "external-sandbox")]
|
#[serde(rename = "external-sandbox")]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Windows sandbox helper contract.
|
//! 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
|
//! sandbox. Future Windows support must run commands through a dedicated
|
||||||
//! helper that provides process-tree containment with a Job Object and
|
//! helper that provides process-tree containment with a Job Object and
|
||||||
//! `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`.
|
//! `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`.
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ const SIZE_WALK_SKIP_DIRS: &[&str] = &[
|
|||||||
];
|
];
|
||||||
|
|
||||||
const BUILTIN_EXCLUDES: &str = "\
|
const BUILTIN_EXCLUDES: &str = "\
|
||||||
# DeepSeek TUI built-in snapshot exclusions
|
# Codewhale built-in snapshot exclusions
|
||||||
node_modules/
|
node_modules/
|
||||||
target/
|
target/
|
||||||
dist/
|
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:
|
//! This module defines the core abstractions for tools:
|
||||||
//! - `ToolSpec`: The main trait that all tools must implement
|
//! - `ToolSpec`: The main trait that all tools must implement
|
||||||
|
|||||||
@@ -510,7 +510,7 @@ mod tests {
|
|||||||
app.system_prompt = Some(SystemPrompt::Blocks(vec![
|
app.system_prompt = Some(SystemPrompt::Blocks(vec![
|
||||||
SystemBlock {
|
SystemBlock {
|
||||||
block_type: "text".to_string(),
|
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,
|
cache_control: None,
|
||||||
},
|
},
|
||||||
SystemBlock {
|
SystemBlock {
|
||||||
@@ -570,7 +570,7 @@ mod tests {
|
|||||||
fn inspector_text_prompt_shows_layer_map() {
|
fn inspector_text_prompt_shows_layer_map() {
|
||||||
let mut app = test_app();
|
let mut app = test_app();
|
||||||
app.system_prompt = Some(SystemPrompt::Text(
|
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);
|
let text = build_context_inspector_text(&app);
|
||||||
@@ -590,7 +590,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn inspector_text_prompt_without_markers_shows_single_blob() {
|
fn inspector_text_prompt_without_markers_shows_single_blob() {
|
||||||
let mut app = test_app();
|
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);
|
let text = build_context_inspector_text(&app);
|
||||||
assert!(text.contains("Single text blob"));
|
assert!(text.contains("Single text blob"));
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
|||||||
if !lines.is_empty() {
|
if !lines.is_empty() {
|
||||||
let mut panel = Block::default()
|
let mut panel = Block::default()
|
||||||
.title(Line::from(Span::styled(
|
.title(Line::from(Span::styled(
|
||||||
" DeepSeek TUI ",
|
" Codewhale ",
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(palette::DEEPSEEK_BLUE)
|
.fg(palette::DEEPSEEK_BLUE)
|
||||||
.add_modifier(Modifier::BOLD),
|
.add_modifier(Modifier::BOLD),
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ impl ModalView for ModePickerView {
|
|||||||
|
|
||||||
let mut lines = Vec::with_capacity(MODE_ROWS.len() + 1);
|
let mut lines = Vec::with_capacity(MODE_ROWS.len() + 1);
|
||||||
lines.push(Line::from(Span::styled(
|
lines.push(Line::from(Span::styled(
|
||||||
"Choose how DeepSeek TUI should operate:",
|
"Choose how Codewhale should operate:",
|
||||||
Style::default().fg(palette::TEXT_MUTED),
|
Style::default().fg(palette::TEXT_MUTED),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Threat model: this is a deliberate user opt-in to a path the workspace
|
//! 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
|
//! 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
|
//! it does not loosen the OS sandbox profile (Seatbelt/Landlock) used for
|
||||||
//! shell commands. Sandbox-profile expansion is tracked separately so a
|
//! shell commands. Sandbox-profile expansion is tracked separately so a
|
||||||
//! shell tool can opt into the same paths in a future release.
|
//! 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`;
|
- runs Feishu bridge and version-drift checks when CNB receives `main`;
|
||||||
- builds Linux x64 release assets from `v*` tags, creates the CNB release, and
|
- 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`.
|
`deepseek-artifacts-sha256.txt`.
|
||||||
|
|
||||||
The files in this directory are retained as deploy-button templates for Tencent
|
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
|
- `DEEPSEEK_REPO_URL`: defaults to the CNB mirror URL
|
||||||
- `LIGHTHOUSE_SSH_PORT`: defaults to `22`
|
- `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
|
`/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
|
## Safety Notes
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ main:
|
|||||||
|
|
||||||
LIGHTHOUSE_SSH_PORT="${LIGHTHOUSE_SSH_PORT:-22}"
|
LIGHTHOUSE_SSH_PORT="${LIGHTHOUSE_SSH_PORT:-22}"
|
||||||
DEEPSEEK_REPO_BRANCH="${DEEPSEEK_REPO_BRANCH:-main}"
|
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
|
install -m 700 -d ~/.ssh
|
||||||
printf '%s\n' "$LIGHTHOUSE_SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
|
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'
|
"DEEPSEEK_REPO_BRANCH='$DEEPSEEK_REPO_BRANCH' DEEPSEEK_REPO_URL='$DEEPSEEK_REPO_URL' bash -s" <<'REMOTE'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
if [ ! -d /opt/whalebro/deepseek-tui/.git ]; then
|
if [ ! -d /opt/whalebro/codewhale/.git ]; then
|
||||||
sudo -u deepseek git clone --branch "$DEEPSEEK_REPO_BRANCH" "$DEEPSEEK_REPO_URL" /opt/whalebro/deepseek-tui
|
sudo -u codewhale git clone --branch "$DEEPSEEK_REPO_BRANCH" "$DEEPSEEK_REPO_URL" /opt/whalebro/codewhale
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd /opt/whalebro/deepseek-tui
|
cd /opt/whalebro/codewhale
|
||||||
if [ -n "$(sudo -u deepseek git status --porcelain)" ]; then
|
if [ -n "$(sudo -u codewhale git status --porcelain)" ]; then
|
||||||
echo "Refusing to deploy over a dirty /opt/whalebro/deepseek-tui checkout." >&2
|
echo "Refusing to deploy over a dirty /opt/whalebro/codewhale checkout." >&2
|
||||||
sudo -u deepseek git status --short
|
sudo -u codewhale git status --short
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo -u deepseek git fetch --all --tags
|
sudo -u codewhale git fetch --all --tags
|
||||||
if sudo -u deepseek git rev-parse --verify --quiet "refs/remotes/origin/$DEEPSEEK_REPO_BRANCH" >/dev/null; then
|
if sudo -u codewhale 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"
|
sudo -u codewhale 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
|
elif sudo -u codewhale 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 checkout --detach "$DEEPSEEK_REPO_BRANCH"
|
||||||
else
|
else
|
||||||
sudo -u deepseek git checkout "$DEEPSEEK_REPO_BRANCH"
|
sudo -u codewhale git checkout "$DEEPSEEK_REPO_BRANCH"
|
||||||
sudo -u deepseek git pull --ff-only
|
sudo -u codewhale git pull --ff-only
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo -iu deepseek bash -lc '
|
sudo -iu codewhale bash -lc '
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
. "$HOME/.cargo/env"
|
. "$HOME/.cargo/env"
|
||||||
cd /opt/whalebro/deepseek-tui
|
cd /opt/whalebro/codewhale
|
||||||
cargo install --path crates/cli --locked --force
|
cargo install --path crates/cli --locked --force
|
||||||
cargo install --path crates/tui --locked --force
|
cargo install --path crates/tui --locked --force
|
||||||
'
|
'
|
||||||
|
|
||||||
sudo bash scripts/tencent-lighthouse/install-services.sh
|
sudo bash scripts/tencent-lighthouse/install-services.sh
|
||||||
sudo systemctl restart deepseek-runtime
|
sudo systemctl restart codewhale-runtime
|
||||||
sudo systemctl restart deepseek-feishu-bridge
|
sudo systemctl restart codewhale-feishu-bridge
|
||||||
sudo bash scripts/tencent-lighthouse/doctor.sh
|
sudo bash scripts/tencent-lighthouse/doctor.sh
|
||||||
REMOTE
|
REMOTE
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
environments:
|
environments:
|
||||||
- name: lighthouse-hk
|
- name: lighthouse-hk
|
||||||
description: Deploy DeepSeek TUI to Tencent Lighthouse Hong Kong.
|
description: Deploy Codewhale to Tencent Lighthouse Hong Kong.
|
||||||
env:
|
env:
|
||||||
name: lighthouse-hk
|
name: lighthouse-hk
|
||||||
button:
|
button:
|
||||||
- name: Deploy Lighthouse
|
- 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
|
event: web_trigger_lighthouse
|
||||||
isDefault: true
|
isDefault: true
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ DEEPSEEK_AUTO_APPROVE=false
|
|||||||
DEEPSEEK_CHAT_ALLOWLIST=
|
DEEPSEEK_CHAT_ALLOWLIST=
|
||||||
DEEPSEEK_ALLOW_UNLISTED=false
|
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_ALLOW_GROUPS=false
|
||||||
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
||||||
FEISHU_GROUP_PREFIX=/ds
|
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 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
|
GitHub repository for users on networks where GitHub is slow or blocked
|
||||||
(primarily mainland China). The mirror receives every push to `main`, every
|
(primarily mainland China). The mirror receives every push to `main`, every
|
||||||
`fix/*`, `rebrand/*`, and `work/v*` branch used for first-party release work,
|
`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
|
```bash
|
||||||
# Quick check: does the new tag exist on CNB?
|
# 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
|
refs/tags/vX.Y.Z
|
||||||
|
|
||||||
# Quick check: is CNB's main at the same commit as origin/main?
|
# 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}')
|
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"
|
test "$gh_main" = "$cnb_main" && echo "in sync" || echo "DIVERGED: gh=$gh_main cnb=$cnb_main"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -103,10 +103,10 @@ password manager.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Add the CNB remote alongside origin.
|
# 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:
|
# 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}
|
# (you'll be prompted for username `cnb` and password ${CNB_TOKEN}
|
||||||
# on the first push; subsequent pushes use the credential helper.)
|
# 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:
|
- **`cargo install`** from the CNB mirror:
|
||||||
```bash
|
```bash
|
||||||
cargo install --git https://cnb.cool/deepseek-tui.com/DeepSeek-TUI --tag vX.Y.Z codewhale-cli
|
cargo install --git https://cnb.cool/codewhale.net/codewhale --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-tui
|
||||||
```
|
```
|
||||||
(Both binaries are required — the dispatcher and the TUI ship
|
(Both binaries are required — the dispatcher and the TUI ship
|
||||||
separately; see `AGENTS.md` for the two-binary install rationale.)
|
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:
|
automation lane. For a stable install, clone `main` or a release tag from:
|
||||||
|
|
||||||
```bash
|
```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
|
The mirror receives `main`, release tags, and the Tencent setup branch patterns
|
||||||
|
|||||||
+17
-17
@@ -1,10 +1,10 @@
|
|||||||
# Docker
|
# 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.
|
for each release.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker pull ghcr.io/hmbown/deepseek-tui:latest
|
docker pull ghcr.io/hmbown/codewhale:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
@@ -12,14 +12,14 @@ docker pull ghcr.io/hmbown/deepseek-tui:latest
|
|||||||
Run the published image with a Docker-managed data volume:
|
Run the published image with a Docker-managed data volume:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker volume create codewhale-tui-home
|
docker volume create codewhale-home
|
||||||
|
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
ghcr.io/hmbown/deepseek-tui:latest
|
ghcr.io/hmbown/codewhale:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Use a pinned release tag for reproducible installs:
|
Use a pinned release tag for reproducible installs:
|
||||||
@@ -27,10 +27,10 @@ Use a pinned release tag for reproducible installs:
|
|||||||
```bash
|
```bash
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /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
|
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:
|
Build the image locally from a checkout:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t codewhale-tui .
|
docker build -t codewhale .
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run it with the same Docker-managed data volume:
|
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
|
```bash
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek \
|
-v codewhale-home:/home/codewhale/.deepseek \
|
||||||
-v "$PWD:/workspace" \
|
-v "$PWD:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
codewhale-tui
|
codewhale
|
||||||
```
|
```
|
||||||
|
|
||||||
Docker Hub publishing is not configured; GHCR is the supported prebuilt image
|
Docker Hub publishing is not configured; GHCR is the supported prebuilt image
|
||||||
@@ -68,13 +68,13 @@ registry.
|
|||||||
|
|
||||||
## Volumes
|
## 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
|
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
|
is the safest default because Docker creates it with ownership the container can
|
||||||
write:
|
write:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
-v codewhale-tui-home:/home/deepseek/.deepseek
|
-v codewhale-home:/home/codewhale/.deepseek
|
||||||
```
|
```
|
||||||
|
|
||||||
Without this mount the container starts fresh each time.
|
Without this mount the container starts fresh each time.
|
||||||
@@ -91,8 +91,8 @@ sudo chown -R 1000:1000 ~/.deepseek
|
|||||||
|
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
-e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
|
||||||
-v ~/.deepseek:/home/deepseek/.deepseek \
|
-v ~/.deepseek:/home/codewhale/.deepseek \
|
||||||
ghcr.io/hmbown/deepseek-tui:latest
|
ghcr.io/hmbown/codewhale:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
That `chown` changes ownership of the host `~/.deepseek` directory. Skip it if
|
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
|
```bash
|
||||||
echo "Explain the Cargo.toml in structured English." | \
|
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
|
## Building locally
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Single platform (your host architecture)
|
# Single platform (your host architecture)
|
||||||
docker build -t codewhale-tui .
|
docker build -t codewhale .
|
||||||
|
|
||||||
# Multi-platform (requires a builder with emulation)
|
# Multi-platform (requires a builder with emulation)
|
||||||
docker buildx create --use
|
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
|
## Devcontainer
|
||||||
|
|||||||
+5
-5
@@ -1,4 +1,4 @@
|
|||||||
# Installing codewhale
|
# Installing Codewhale
|
||||||
|
|
||||||
This page covers every supported install path and the most common
|
This page covers every supported install path and the most common
|
||||||
"it didn't install" failures, including **Linux ARM64** and other less
|
"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
|
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:
|
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
|
- Tencent Lighthouse HK: `/opt/whalebro` remote workspace
|
||||||
- Feishu/Lark: long-connection phone bridge
|
- Feishu/Lark: long-connection phone bridge
|
||||||
- EdgeOne: optional public HTTPS edge for docs/status/webhook surfaces
|
- EdgeOne: optional public HTTPS edge for docs/status/webhook surfaces
|
||||||
@@ -278,7 +278,7 @@ curl -L -o /tmp/codewhale-artifacts-sha256.txt \
|
|||||||
|
|
||||||
### Windows Scoop
|
### Windows Scoop
|
||||||
|
|
||||||
codewhale is listed in Scoop's main bucket:
|
The `codewhale` package is listed in Scoop's main bucket:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
scoop update
|
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:
|
mirror instead and install both binaries from the release tag:
|
||||||
|
|
||||||
```bash
|
```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/codewhale.net/codewhale --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-tui --locked --force
|
||||||
```
|
```
|
||||||
|
|
||||||
If you operate a binary asset mirror, `codewhale update` can use it directly:
|
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`.
|
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
|
- **Homebrew tap and formula** (`Hmbown/homebrew-deepseek-tui`): still
|
||||||
installs by the legacy name during the transition. The tap's formula
|
installs by the legacy name during the transition. The tap's formula
|
||||||
will be flipped to the new names in a follow-up.
|
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)
|
## Deprecation shims (one release cycle)
|
||||||
|
|
||||||
@@ -119,11 +119,10 @@ still verifies.
|
|||||||
|
|
||||||
## Why the name change
|
## Why the name change
|
||||||
|
|
||||||
`codewhale` is a shorter, terminal-friendlier handle that doesn't suggest
|
Codewhale is a shorter, terminal-friendlier handle for the same terminal
|
||||||
the project is tied to a single provider. The dispatcher already supports
|
coding agent. In v0.8.41 it remains centered on DeepSeek V4 while the project
|
||||||
DeepSeek, NVIDIA NIM, OpenAI-compatible endpoints, AtlasCloud, Wanjie Ark,
|
name, command names, package names, release assets, Docker image, and CNB
|
||||||
OpenRouter, Novita, Fireworks, SGLang, vLLM, and Ollama, with more on the
|
mirror move to Codewhale.
|
||||||
roadmap. The new name reflects that.
|
|
||||||
|
|
||||||
## Reporting issues with the rename
|
## Reporting issues with the rename
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ Run, in order, from the repo root:
|
|||||||
reports the new version on the npm registry.
|
reports the new version on the npm registry.
|
||||||
- [ ] `crates.io` has the new version (or the `publish-crates.sh` job has
|
- [ ] `crates.io` has the new version (or the `publish-crates.sh` job has
|
||||||
pushed it).
|
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
|
## 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,
|
This runbook is the source of truth for shipping Rust crates, GitHub release assets,
|
||||||
and the `codewhale` npm wrapper.
|
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
|
## CNB Cool mirror
|
||||||
|
|
||||||
Every push to `main`, `fix/*`, `rebrand/*`, `work/v*`, and every `v*` tag is mirrored to
|
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
|
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
|
run the heavy Linux CI lane. After a release tag, **verify the mirror caught
|
||||||
it** before declaring the release shipped:
|
it** before declaring the release shipped:
|
||||||
|
|
||||||
```bash
|
```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
|
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.
|
that works well from mainland China.
|
||||||
|
|
||||||
It complements the local install path. If you only want to use `codewhale` on a
|
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.
|
workbench I can control from my phone", start here.
|
||||||
|
|
||||||
## Default Stack
|
## Default Stack
|
||||||
|
|
||||||
```text
|
```text
|
||||||
GitHub main/tags
|
GitHub main/tags
|
||||||
-> CNB mirror: cnb.cool/deepseek-tui.com/DeepSeek-TUI
|
-> CNB mirror: cnb.cool/codewhale.net/codewhale
|
||||||
-> optional CNB build/deploy pipeline
|
-> optional CNB build/deploy pipeline
|
||||||
-> Tencent Lighthouse HK
|
-> Tencent Lighthouse HK
|
||||||
/opt/whalebro/codewhale-tui
|
/opt/whalebro/codewhale
|
||||||
/opt/whalebro/worktrees
|
/opt/whalebro/worktrees
|
||||||
codewhale-runtime.service on 127.0.0.1:7878
|
codewhale-runtime.service on 127.0.0.1:7878
|
||||||
codewhale-feishu-bridge.service
|
codewhale-feishu-bridge.service
|
||||||
@@ -45,7 +45,7 @@ EdgeOne is optional:
|
|||||||
2. Clone from CNB by default when the branch or tag exists there:
|
2. Clone from CNB by default when the branch or tag exists there:
|
||||||
|
|
||||||
```bash
|
```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
|
git ls-remote "$DEEPSEEK_REPO_URL" refs/heads/main
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -57,8 +57,8 @@ EdgeOne is optional:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
export DEEPSEEK_BRANCH=main
|
export DEEPSEEK_BRANCH=main
|
||||||
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale-tui
|
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale
|
||||||
cd /tmp/codewhale-tui
|
cd /tmp/codewhale
|
||||||
sudo DEEPSEEK_REPO_URL="$DEEPSEEK_REPO_URL" \
|
sudo DEEPSEEK_REPO_URL="$DEEPSEEK_REPO_URL" \
|
||||||
DEEPSEEK_REPO_BRANCH="$DEEPSEEK_BRANCH" \
|
DEEPSEEK_REPO_BRANCH="$DEEPSEEK_BRANCH" \
|
||||||
bash scripts/tencent-lighthouse/bootstrap-ubuntu.sh
|
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.
|
1. Run bridge validation/tests and lightweight release-version checks.
|
||||||
2. SSH to Lighthouse with a deploy key stored as a CNB secret.
|
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.
|
4. Rebuild/install both binaries.
|
||||||
5. Reinstall/restart systemd services.
|
5. Reinstall/restart systemd services.
|
||||||
6. Run `scripts/tencent-lighthouse/doctor.sh`.
|
6. Run `scripts/tencent-lighthouse/doctor.sh`.
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ is the implementation runbook for the Lighthouse host itself.
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
CNB mirror or GitHub branch
|
CNB mirror or GitHub branch
|
||||||
-> /opt/whalebro/codewhale-tui
|
-> /opt/whalebro/codewhale
|
||||||
|
|
||||||
Feishu/Lark mobile app
|
Feishu/Lark mobile app
|
||||||
-> Feishu/Lark long-connection bot
|
-> Feishu/Lark long-connection bot
|
||||||
-> codewhale-feishu-bridge systemd service
|
-> codewhale-feishu-bridge systemd service
|
||||||
-> http://127.0.0.1:7878 codewhale serve --http
|
-> http://127.0.0.1:7878 codewhale serve --http
|
||||||
-> /opt/whalebro
|
-> /opt/whalebro
|
||||||
-> codewhale-tui/
|
-> codewhale/
|
||||||
|
|
||||||
Optional public edge:
|
Optional public edge:
|
||||||
EdgeOne -> Caddy/Nginx public site on Lighthouse
|
EdgeOne -> Caddy/Nginx public site on Lighthouse
|
||||||
@@ -31,11 +31,11 @@ HTTP service, not the runtime API.
|
|||||||
## Remote Whalebro Workspace
|
## Remote Whalebro Workspace
|
||||||
|
|
||||||
Use `/opt/whalebro` as the VPS workspace root. The first-class checkout is
|
Use `/opt/whalebro` as the VPS workspace root. The first-class checkout is
|
||||||
`/opt/whalebro/codewhale-tui`.
|
`/opt/whalebro/codewhale`.
|
||||||
|
|
||||||
Create these paths first:
|
Create these paths first:
|
||||||
|
|
||||||
- `/opt/whalebro/codewhale-tui`
|
- `/opt/whalebro/codewhale`
|
||||||
- `/opt/whalebro/worktrees`
|
- `/opt/whalebro/worktrees`
|
||||||
|
|
||||||
Linux is enough for Rust, Node, and service work. Mac-only release work such
|
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 update
|
||||||
sudo apt-get install -y git
|
sudo apt-get install -y git
|
||||||
export DEEPSEEK_BRANCH=main
|
export DEEPSEEK_BRANCH=main
|
||||||
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 clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale-tui
|
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale
|
||||||
cd /tmp/codewhale-tui
|
cd /tmp/codewhale
|
||||||
sudo DEEPSEEK_REPO_URL="$DEEPSEEK_REPO_URL" \
|
sudo DEEPSEEK_REPO_URL="$DEEPSEEK_REPO_URL" \
|
||||||
DEEPSEEK_REPO_BRANCH="$DEEPSEEK_BRANCH" \
|
DEEPSEEK_REPO_BRANCH="$DEEPSEEK_BRANCH" \
|
||||||
bash scripts/tencent-lighthouse/bootstrap-ubuntu.sh
|
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:
|
using it:
|
||||||
|
|
||||||
```bash
|
```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" \
|
git ls-remote "$DEEPSEEK_REPO_URL" \
|
||||||
refs/heads/main \
|
refs/heads/main \
|
||||||
refs/tags/v0.8.37
|
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
|
sh /tmp/rustup-init.sh -y --profile minimal
|
||||||
. "$HOME/.cargo/env"
|
. "$HOME/.cargo/env"
|
||||||
rustup default stable
|
rustup default stable
|
||||||
cd /opt/whalebro/codewhale-tui
|
cd /opt/whalebro/codewhale
|
||||||
cargo install --path crates/cli --locked --force
|
cargo install --path crates/cli --locked --force
|
||||||
cargo install --path crates/tui --locked --force
|
cargo install --path crates/tui --locked --force
|
||||||
exit
|
exit
|
||||||
@@ -138,14 +138,14 @@ exit
|
|||||||
Copy and install the bridge/service files:
|
Copy and install the bridge/service files:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/whalebro/codewhale-tui
|
cd /opt/whalebro/codewhale
|
||||||
sudo bash scripts/tencent-lighthouse/install-services.sh
|
sudo bash scripts/tencent-lighthouse/install-services.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
After editing both env files, validate the bridge/runtime pairing:
|
After editing both env files, validate the bridge/runtime pairing:
|
||||||
|
|
||||||
```bash
|
```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 \
|
--env /etc/deepseek/feishu-bridge.env \
|
||||||
--runtime-env /etc/deepseek/runtime.env \
|
--runtime-env /etc/deepseek/runtime.env \
|
||||||
--workspace-root /opt/whalebro \
|
--workspace-root /opt/whalebro \
|
||||||
@@ -196,7 +196,7 @@ sudo journalctl -u codewhale-feishu-bridge -f
|
|||||||
Run the Lighthouse doctor after both services are configured:
|
Run the Lighthouse doctor after both services are configured:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/whalebro/codewhale-tui
|
cd /opt/whalebro/codewhale
|
||||||
sudo bash scripts/tencent-lighthouse/doctor.sh
|
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.
|
- Keep the Lighthouse firewall focused on SSH for this setup.
|
||||||
- Use SSH key auth.
|
- Use SSH key auth.
|
||||||
- Use `tmux` for emergency terminal work from Blink/Termius.
|
- 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.
|
phone.
|
||||||
|
|||||||
@@ -39,15 +39,20 @@
|
|||||||
{
|
{
|
||||||
packages = forEachSystem (
|
packages = forEachSystem (
|
||||||
{ pkgs, system }:
|
{ pkgs, system }:
|
||||||
{
|
let
|
||||||
default = self.packages.${system}.deepseek-tui;
|
codewhale = pkgs.callPackage ./nix/package.nix {
|
||||||
deepseek-tui = pkgs.callPackage ./nix/package.nix {
|
|
||||||
inherit rev;
|
inherit rev;
|
||||||
rustPlatform = pkgs.makeRustPlatform {
|
rustPlatform = pkgs.makeRustPlatform {
|
||||||
cargo = pkgs.rustToolchain;
|
cargo = pkgs.rustToolchain;
|
||||||
rustc = 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_CHAT_ALLOWLIST=
|
||||||
DEEPSEEK_ALLOW_UNLISTED=false
|
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_ALLOW_GROUPS=false
|
||||||
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
||||||
FEISHU_GROUP_PREFIX=/ds
|
FEISHU_GROUP_PREFIX=/ds
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# Feishu / Lark Bridge
|
# 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
|
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.
|
mode, so the first version does not need a public webhook URL.
|
||||||
|
|
||||||
Security model:
|
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`.
|
- `/v1/*` runtime calls use `DEEPSEEK_RUNTIME_TOKEN`.
|
||||||
- Feishu/Lark chats must be allowlisted unless `DEEPSEEK_ALLOW_UNLISTED=true`
|
- Feishu/Lark chats must be allowlisted unless `DEEPSEEK_ALLOW_UNLISTED=true`
|
||||||
is set for first pairing.
|
is set for first pairing.
|
||||||
@@ -17,7 +17,7 @@ Security model:
|
|||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/deepseek/bridge
|
cd /opt/codewhale/bridge
|
||||||
npm install --omit=dev
|
npm install --omit=dev
|
||||||
cp .env.example /etc/deepseek/feishu-bridge.env
|
cp .env.example /etc/deepseek/feishu-bridge.env
|
||||||
sudoedit /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:
|
For a Tencent Lighthouse deployment, use:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo systemctl enable --now deepseek-runtime deepseek-feishu-bridge
|
sudo systemctl enable --now codewhale-runtime codewhale-feishu-bridge
|
||||||
sudo journalctl -u deepseek-feishu-bridge -f
|
sudo journalctl -u codewhale-feishu-bridge -f
|
||||||
```
|
```
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@deepseek-tui/feishu-bridge",
|
"name": "@codewhale/feishu-bridge",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@deepseek-tui/feishu-bridge",
|
"name": "@codewhale/feishu-bridge",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@larksuiteoapi/node-sdk": "^1.52.0"
|
"@larksuiteoapi/node-sdk": "^1.52.0"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "@deepseek-tui/feishu-bridge",
|
"name": "@codewhale/feishu-bridge",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"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",
|
"main": "src/index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node src/index.mjs",
|
"start": "node src/index.mjs",
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ const config = {
|
|||||||
allowUnlisted: parseBool(process.env.DEEPSEEK_ALLOW_UNLISTED, false),
|
allowUnlisted: parseBool(process.env.DEEPSEEK_ALLOW_UNLISTED, false),
|
||||||
threadMapPath:
|
threadMapPath:
|
||||||
process.env.FEISHU_THREAD_MAP_PATH ||
|
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),
|
allowGroups: parseBool(process.env.FEISHU_ALLOW_GROUPS, false),
|
||||||
requirePrefixInGroup: parseBool(process.env.FEISHU_REQUIRE_PREFIX_IN_GROUP, true),
|
requirePrefixInGroup: parseBool(process.env.FEISHU_REQUIRE_PREFIX_IN_GROUP, true),
|
||||||
groupPrefix: process.env.FEISHU_GROUP_PREFIX || "/ds",
|
groupPrefix: process.env.FEISHU_GROUP_PREFIX || "/ds",
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ test("validateBridgeConfig accepts locked-down whalebro DM config", () => {
|
|||||||
DEEPSEEK_WORKSPACE: "/opt/whalebro",
|
DEEPSEEK_WORKSPACE: "/opt/whalebro",
|
||||||
DEEPSEEK_CHAT_ALLOWLIST: "oc_allowed",
|
DEEPSEEK_CHAT_ALLOWLIST: "oc_allowed",
|
||||||
DEEPSEEK_ALLOW_UNLISTED: "false",
|
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_ALLOW_GROUPS: "false",
|
||||||
FEISHU_REQUIRE_PREFIX_IN_GROUP: "true"
|
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_RUNTIME_TOKEN: "bridge-token",
|
||||||
DEEPSEEK_WORKSPACE: "/opt/whalebro",
|
DEEPSEEK_WORKSPACE: "/opt/whalebro",
|
||||||
DEEPSEEK_ALLOW_UNLISTED: "true",
|
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_ALLOW_GROUPS: "true",
|
||||||
FEISHU_REQUIRE_PREFIX_IN_GROUP: "false"
|
FEISHU_REQUIRE_PREFIX_IN_GROUP: "false"
|
||||||
},
|
},
|
||||||
|
|||||||
+5
-5
@@ -15,7 +15,7 @@
|
|||||||
rev ? "dirty",
|
rev ? "dirty",
|
||||||
}:
|
}:
|
||||||
rustPlatform.buildRustPackage (finalAttrs: {
|
rustPlatform.buildRustPackage (finalAttrs: {
|
||||||
pname = "deepseek-tui";
|
pname = "codewhale";
|
||||||
version = "git-${rev}";
|
version = "git-${rev}";
|
||||||
|
|
||||||
src = ../.;
|
src = ../.;
|
||||||
@@ -46,9 +46,9 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
|||||||
|
|
||||||
cargoBuildFlags = [
|
cargoBuildFlags = [
|
||||||
"--package"
|
"--package"
|
||||||
"deepseek-tui-cli"
|
"codewhale-cli"
|
||||||
"--package"
|
"--package"
|
||||||
"deepseek-tui"
|
"codewhale-tui"
|
||||||
];
|
];
|
||||||
cargoTestFlags = finalAttrs.cargoBuildFlags ++ [
|
cargoTestFlags = finalAttrs.cargoBuildFlags ++ [
|
||||||
"--lib"
|
"--lib"
|
||||||
@@ -60,9 +60,9 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
meta = {
|
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";
|
homepage = "https://github.com/Hmbown/DeepSeek-TUI";
|
||||||
license = lib.licenses.mit;
|
license = lib.licenses.mit;
|
||||||
mainProgram = "deepseek";
|
mainProgram = "codewhale";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ if [[ "${EUID}" -ne 0 ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DEEPSEEK_USER="${DEEPSEEK_USER:-deepseek}"
|
DEEPSEEK_USER="${DEEPSEEK_USER:-codewhale}"
|
||||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/deepseek}"
|
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/codewhale}"
|
||||||
WHALEBRO_ROOT="${WHALEBRO_ROOT:-/opt/whalebro}"
|
WHALEBRO_ROOT="${WHALEBRO_ROOT:-/opt/whalebro}"
|
||||||
REPO_URL="${DEEPSEEK_REPO_URL:-https://github.com/Hmbown/DeepSeek-TUI.git}"
|
REPO_URL="${DEEPSEEK_REPO_URL:-https://github.com/Hmbown/DeepSeek-TUI.git}"
|
||||||
WHALEBRO_EXTRA_REPOS="${WHALEBRO_EXTRA_REPOS:-}"
|
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}"
|
||||||
install -d -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" "${WHALEBRO_ROOT}/worktrees"
|
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 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
|
if [[ ! -d "${WHALEBRO_ROOT}/codewhale/.git" ]]; then
|
||||||
sudo -u "${DEEPSEEK_USER}" git clone --branch "${REPO_BRANCH}" "${REPO_URL}" "${WHALEBRO_ROOT}/deepseek-tui"
|
sudo -u "${DEEPSEEK_USER}" git clone --branch "${REPO_BRANCH}" "${REPO_URL}" "${WHALEBRO_ROOT}/codewhale"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for repo_spec in ${WHALEBRO_EXTRA_REPOS}; do
|
for repo_spec in ${WHALEBRO_EXTRA_REPOS}; do
|
||||||
@@ -94,7 +94,7 @@ DEEPSEEK_TRUST_MODE=false
|
|||||||
DEEPSEEK_AUTO_APPROVE=false
|
DEEPSEEK_AUTO_APPROVE=false
|
||||||
DEEPSEEK_CHAT_ALLOWLIST=
|
DEEPSEEK_CHAT_ALLOWLIST=
|
||||||
DEEPSEEK_ALLOW_UNLISTED=false
|
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_ALLOW_GROUPS=false
|
||||||
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
FEISHU_REQUIRE_PREFIX_IN_GROUP=true
|
||||||
FEISHU_GROUP_PREFIX=/ds
|
FEISHU_GROUP_PREFIX=/ds
|
||||||
@@ -116,7 +116,7 @@ Next:
|
|||||||
1. Install Rust 1.88+ for ${DEEPSEEK_USER}; rustup is the usual path.
|
1. Install Rust 1.88+ for ${DEEPSEEK_USER}; rustup is the usual path.
|
||||||
2. Build/install both binaries:
|
2. Build/install both binaries:
|
||||||
sudo -iu ${DEEPSEEK_USER}
|
sudo -iu ${DEEPSEEK_USER}
|
||||||
cd ${WHALEBRO_ROOT}/deepseek-tui
|
cd ${WHALEBRO_ROOT}/codewhale
|
||||||
cargo install --path crates/cli --locked --force
|
cargo install --path crates/cli --locked --force
|
||||||
cargo install --path crates/tui --locked --force
|
cargo install --path crates/tui --locked --force
|
||||||
3. Copy integrations/feishu-bridge to ${DEEPSEEK_ROOT}/bridge and run npm install.
|
3. Copy integrations/feishu-bridge to ${DEEPSEEK_ROOT}/bridge and run npm install.
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
DEEPSEEK_USER="${DEEPSEEK_USER:-deepseek}"
|
DEEPSEEK_USER="${DEEPSEEK_USER:-codewhale}"
|
||||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/deepseek}"
|
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/codewhale}"
|
||||||
WHALEBRO_ROOT="${WHALEBRO_ROOT:-/opt/whalebro}"
|
WHALEBRO_ROOT="${WHALEBRO_ROOT:-/opt/whalebro}"
|
||||||
RUNTIME_ENV="${RUNTIME_ENV:-/etc/deepseek/runtime.env}"
|
RUNTIME_ENV="${RUNTIME_ENV:-/etc/deepseek/runtime.env}"
|
||||||
BRIDGE_ENV="${BRIDGE_ENV:-/etc/deepseek/feishu-bridge.env}"
|
BRIDGE_ENV="${BRIDGE_ENV:-/etc/deepseek/feishu-bridge.env}"
|
||||||
BRIDGE_DIR="${BRIDGE_DIR:-${DEEPSEEK_ROOT}/bridge}"
|
BRIDGE_DIR="${BRIDGE_DIR:-${DEEPSEEK_ROOT}/bridge}"
|
||||||
REPO_ROOT="${REPO_ROOT:-${WHALEBRO_ROOT}/deepseek-tui}"
|
REPO_ROOT="${REPO_ROOT:-${WHALEBRO_ROOT}/codewhale}"
|
||||||
|
|
||||||
failures=0
|
failures=0
|
||||||
warnings=0
|
warnings=0
|
||||||
@@ -97,15 +97,15 @@ check_workspace() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_binaries() {
|
check_binaries() {
|
||||||
section "DeepSeek binaries"
|
section "Codewhale binaries"
|
||||||
local cargo_bin="/home/${DEEPSEEK_USER}/.cargo/bin"
|
local cargo_bin="/home/${DEEPSEEK_USER}/.cargo/bin"
|
||||||
local deepseek="${cargo_bin}/deepseek"
|
local codewhale="${cargo_bin}/codewhale"
|
||||||
local tui="${cargo_bin}/deepseek-tui"
|
local tui="${cargo_bin}/codewhale-tui"
|
||||||
if [[ -x "${deepseek}" ]]; then
|
if [[ -x "${codewhale}" ]]; then
|
||||||
pass "${deepseek} is executable"
|
pass "${codewhale} is executable"
|
||||||
"${deepseek}" --version 2>/dev/null | sed 's/^/[info] deepseek version: /' || warn "deepseek --version failed"
|
"${codewhale}" --version 2>/dev/null | sed 's/^/[info] codewhale version: /' || warn "codewhale --version failed"
|
||||||
else
|
else
|
||||||
fail "${deepseek} is missing or not executable"
|
fail "${codewhale} is missing or not executable"
|
||||||
fi
|
fi
|
||||||
if [[ -x "${tui}" ]]; then
|
if [[ -x "${tui}" ]]; then
|
||||||
pass "${tui} is executable"
|
pass "${tui} is executable"
|
||||||
@@ -205,7 +205,7 @@ check_systemd() {
|
|||||||
warn "systemd is not available in this environment"
|
warn "systemd is not available in this environment"
|
||||||
return
|
return
|
||||||
fi
|
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" ]] \
|
[[ -f "/etc/systemd/system/${unit}.service" ]] \
|
||||||
&& pass "${unit}.service is installed" \
|
&& pass "${unit}.service is installed" \
|
||||||
|| fail "${unit}.service is missing"
|
|| fail "${unit}.service is missing"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ if [[ "${EUID}" -ne 0 ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
DEEPSEEK_USER="${DEEPSEEK_USER:-deepseek}"
|
DEEPSEEK_USER="${DEEPSEEK_USER:-codewhale}"
|
||||||
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/deepseek}"
|
DEEPSEEK_ROOT="${DEEPSEEK_ROOT:-/opt/codewhale}"
|
||||||
|
|
||||||
install -d -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" "${DEEPSEEK_ROOT}/bridge"
|
install -d -o "${DEEPSEEK_USER}" -g "${DEEPSEEK_USER}" "${DEEPSEEK_ROOT}/bridge"
|
||||||
rsync -a --delete \
|
rsync -a --delete \
|
||||||
@@ -23,11 +23,11 @@ else
|
|||||||
sudo -u "${DEEPSEEK_USER}" npm --prefix "${DEEPSEEK_ROOT}/bridge" install --omit=dev
|
sudo -u "${DEEPSEEK_USER}" npm --prefix "${DEEPSEEK_ROOT}/bridge" install --omit=dev
|
||||||
fi
|
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/codewhale-runtime.service" /etc/systemd/system/codewhale-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-feishu-bridge.service" /etc/systemd/system/codewhale-feishu-bridge.service
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable deepseek-runtime deepseek-feishu-bridge
|
systemctl enable codewhale-runtime codewhale-feishu-bridge
|
||||||
|
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
Services installed but not started.
|
Services installed but not started.
|
||||||
@@ -35,11 +35,11 @@ Services installed but not started.
|
|||||||
Before starting, verify:
|
Before starting, verify:
|
||||||
/etc/deepseek/runtime.env
|
/etc/deepseek/runtime.env
|
||||||
/etc/deepseek/feishu-bridge.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:
|
Then run:
|
||||||
sudo systemctl start deepseek-runtime
|
sudo systemctl start codewhale-runtime
|
||||||
sudo systemctl start deepseek-feishu-bridge
|
sudo systemctl start codewhale-feishu-bridge
|
||||||
sudo bash /opt/whalebro/deepseek-tui/scripts/tencent-lighthouse/doctor.sh
|
sudo bash /opt/whalebro/codewhale/scripts/tencent-lighthouse/doctor.sh
|
||||||
sudo journalctl -u deepseek-feishu-bridge -f
|
sudo journalctl -u codewhale-feishu-bridge -f
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
Reference in New Issue
Block a user