chore: make Lite edition support and related configurations hidden

This commit is contained in:
wizardchen
2026-03-02 18:23:02 +08:00
committed by lyingbug
parent 4222b9dc21
commit 88d5b303b8
11 changed files with 3 additions and 1003 deletions

View File

@@ -1,45 +0,0 @@
# WeKnora Lite 配置模板
# 复制此文件为 .env.lite 并按需修改
# cp .env.lite.example .env.lite
GIN_MODE=release
# === 数据库 ===
DB_DRIVER=sqlite
DB_PATH=./data/weknora.db
# === 检索引擎FTS5 + sqlite-vec===
RETRIEVE_DRIVER=sqlite
# === 文件存储 ===
STORAGE_TYPE=local
LOCAL_STORAGE_BASE_DIR=./data/files
# === 流管理(内存,无 Redis===
STREAM_MANAGER_TYPE=memory
# === LLM 服务 ===
# Ollama 本地服务(默认地址,按需修改)
OLLAMA_BASE_URL=http://127.0.0.1:11434
# 如使用其他 OpenAI 兼容服务,取消注释:
# OPENAI_API_KEY=sk-xxx
# OPENAI_BASE_URL=https://api.openai.com/v1
# === 安全配置(生产环境请务必修改!)===
TENANT_AES_KEY=CHANGE-ME-32-char-secret-key!!!!
JWT_SECRET=CHANGE-ME-jwt-secret
# === 功能开关 ===
NEO4J_ENABLE=false
WEKNORA_SANDBOX_MODE=disabled
ENABLE_GRAPH_RAG=false
DISABLE_REGISTRATION=false
# === 性能 ===
CONCURRENCY_POOL_SIZE=3
# Docreader 地址
DOCREADER_ADDR=127.0.0.1:50051
# Docreader 传输方式
DOCREADER_TRANSPORT=grpc

View File

@@ -1,246 +0,0 @@
name: Release Lite Binaries
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g. v0.2.0)"
required: true
concurrency:
group: release-lite-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: write
env:
GO_VERSION: "1.24"
NODE_VERSION: "22"
jobs:
# ── 1. Build frontend once, share as artifact ──
build-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Build frontend
working-directory: frontend
run: |
npm ci
npm run build
- uses: actions/upload-artifact@v4
with:
name: frontend-dist
path: frontend/dist/
retention-days: 1
# ── 2. Build Go binary per platform (native CGO) ──
build-binary:
needs: build-frontend
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
- os: ubuntu-24.04-arm
goos: linux
goarch: arm64
- os: macos-13
goos: darwin
goarch: amd64
- os: macos-14
goos: darwin
goarch: arm64
runs-on: ${{ matrix.os }}
env:
CGO_ENABLED: 1
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- uses: actions/download-artifact@v4
with:
name: frontend-dist
path: web/
- name: Resolve version
id: ver
run: |
if [ -n "${{ inputs.tag }}" ]; then
VERSION="${{ inputs.tag }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Building ${VERSION} for ${{ matrix.goos }}/${{ matrix.goarch }}"
- name: Build
run: |
export EDITION=lite
eval "$(./scripts/get_version.sh env)"
LDFLAGS="-w -s $(./scripts/get_version.sh ldflags)"
export CGO_CFLAGS="-Wno-deprecated-declarations"
if [ "${{ matrix.goos }}" = "darwin" ]; then
export CGO_LDFLAGS="-Wl,-no_warn_duplicate_libraries"
fi
go build -tags "sqlite_fts5" -ldflags="${LDFLAGS}" \
-o WeKnora-lite ./cmd/server
- name: Package tarball
run: |
ARCHIVE="WeKnora-lite_${{ steps.ver.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}"
mkdir -p "${ARCHIVE}/web"
cp WeKnora-lite "${ARCHIVE}/"
cp -r web/* "${ARCHIVE}/web/"
cp .env.lite.example "${ARCHIVE}/"
cp docs/LITE.md "${ARCHIVE}/README.md"
if [ -d config ]; then
cp -r config "${ARCHIVE}/config"
fi
if [ -d migrations/sqlite ]; then
mkdir -p "${ARCHIVE}/migrations/sqlite"
cp -r migrations/sqlite/* "${ARCHIVE}/migrations/sqlite/"
fi
if [ -f deploy/weknora-lite.service ]; then
cp deploy/weknora-lite.service "${ARCHIVE}/"
fi
tar czf "${ARCHIVE}.tar.gz" "${ARCHIVE}"
shasum -a 256 "${ARCHIVE}.tar.gz" > "${ARCHIVE}.tar.gz.sha256"
- uses: actions/upload-artifact@v4
with:
name: release-${{ matrix.goos }}-${{ matrix.goarch }}
path: |
WeKnora-lite_*.tar.gz
WeKnora-lite_*.tar.gz.sha256
retention-days: 3
# ── 3. Create GitHub Release ──
release:
needs: build-binary
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
pattern: release-*
merge-multiple: true
- name: Resolve version
id: ver
run: |
if [ -n "${{ inputs.tag }}" ]; then
VERSION="${{ inputs.tag }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Generate release notes
id: notes
run: |
cat > notes.md << 'NOTES'
## WeKnora Lite ${{ steps.ver.outputs.version }}
单二进制部署,零外部依赖(无需 Docker / PostgreSQL / Redis
### 快速开始
```bash
# 1. 解压
tar xzf WeKnora-lite_${{ steps.ver.outputs.version }}_<os>_<arch>.tar.gz
cd WeKnora-lite_${{ steps.ver.outputs.version }}_<os>_<arch>
# 2. 配置
cp .env.lite.example .env.lite
# 编辑 .env.lite至少确认 OLLAMA_BASE_URL 正确
# 3. 启动 Ollama如尚未运行
ollama serve &
ollama pull qwen2.5:7b
ollama pull nomic-embed-text
# 4. 运行
set -a && source .env.lite && set +a
./WeKnora-lite
# 访问 http://localhost:8080
```
### 平台支持
| 文件 | 平台 |
|------|------|
| `WeKnora-lite_*_linux_amd64.tar.gz` | Linux x86_64 |
| `WeKnora-lite_*_linux_arm64.tar.gz` | Linux ARM64 |
| `WeKnora-lite_*_darwin_amd64.tar.gz` | macOS Intel |
| `WeKnora-lite_*_darwin_arm64.tar.gz` | macOS Apple Silicon |
详细文档见 [LITE.md](docs/LITE.md)。
NOTES
- name: Create release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${{ steps.ver.outputs.version }}" \
--title "WeKnora Lite ${{ steps.ver.outputs.version }}" \
--notes-file notes.md \
WeKnora-lite_*.tar.gz \
WeKnora-lite_*.tar.gz.sha256
# ── 4. Update Homebrew Formula ──
update-homebrew:
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: main
token: ${{ secrets.GITHUB_TOKEN }}
- name: Resolve version
id: ver
run: |
if [ -n "${{ inputs.tag }}" ]; then
VERSION="${{ inputs.tag }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Wait for release assets to be available
run: sleep 15
- name: Update Formula
run: ./scripts/update-homebrew-formula.sh "${{ steps.ver.outputs.version }}"
- name: Commit and push
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/weknora-lite.rb
if git diff --cached --quiet; then
echo "No changes to Formula"
else
git commit -m "formula: update weknora-lite to ${{ steps.ver.outputs.version }}"
git push origin main
fi

View File

@@ -1,118 +0,0 @@
class WeknoraLite < Formula
desc "Knowledge base management system — single-binary Lite edition"
homepage "https://github.com/Tencent/WeKnora"
version "0.0.0"
license "Apache-2.0"
on_macos do
on_arm do
url "https://github.com/Tencent/WeKnora/releases/download/v#{version}/WeKnora-lite_v#{version}_darwin_arm64.tar.gz"
sha256 "PLACEHOLDER"
end
on_intel do
url "https://github.com/Tencent/WeKnora/releases/download/v#{version}/WeKnora-lite_v#{version}_darwin_amd64.tar.gz"
sha256 "PLACEHOLDER"
end
end
on_linux do
on_arm do
url "https://github.com/Tencent/WeKnora/releases/download/v#{version}/WeKnora-lite_v#{version}_linux_arm64.tar.gz"
sha256 "PLACEHOLDER"
end
on_intel do
url "https://github.com/Tencent/WeKnora/releases/download/v#{version}/WeKnora-lite_v#{version}_linux_amd64.tar.gz"
sha256 "PLACEHOLDER"
end
end
def install
libexec.install "WeKnora-lite"
pkgshare.install "web" if File.directory?("web")
pkgshare.install "config" if File.directory?("config")
pkgshare.install ".env.lite.example"
doc.install "README.md"
pkgshare.install "migrations" if File.directory?("migrations")
(bin/"weknora-lite").write <<~SH
#!/bin/bash
CONFIG_DIR="${WEKNORA_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/weknora}"
DATA_DIR="${WEKNORA_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/weknora}"
mkdir -p "$DATA_DIR/files" "$CONFIG_DIR/config" 2>/dev/null
if [ ! -f "$CONFIG_DIR/config/config.yaml" ]; then
cp -r "#{pkgshare}/config/" "$CONFIG_DIR/config/"
fi
if [ ! -d "$CONFIG_DIR/migrations" ] && [ -d "#{pkgshare}/migrations" ]; then
ln -sf "#{pkgshare}/migrations" "$CONFIG_DIR/migrations"
fi
if [ ! -f "$CONFIG_DIR/.env.lite" ]; then
cp "#{pkgshare}/.env.lite.example" "$CONFIG_DIR/.env.lite"
sed -i '' "s|DB_PATH=.*|DB_PATH=$DATA_DIR/weknora.db|" "$CONFIG_DIR/.env.lite"
sed -i '' "s|LOCAL_STORAGE_BASE_DIR=.*|LOCAL_STORAGE_BASE_DIR=$DATA_DIR/files|" "$CONFIG_DIR/.env.lite"
rm -f "$CONFIG_DIR/.env.lite-e"
echo ""
echo "已创建配置文件: $CONFIG_DIR/.env.lite"
echo "请根据需要编辑(如修改 LLM 地址、安全密钥等)。"
echo ""
fi
set -a
source "$CONFIG_DIR/.env.lite"
set +a
export DB_PATH="${DB_PATH:-$DATA_DIR/weknora.db}"
export LOCAL_STORAGE_BASE_DIR="${LOCAL_STORAGE_BASE_DIR:-$DATA_DIR/files}"
export WEKNORA_WEB_DIR="${WEKNORA_WEB_DIR:-#{pkgshare}/web}"
cd "$CONFIG_DIR"
exec "#{libexec}/WeKnora-lite" "$@"
SH
end
def post_install
(var/"weknora").mkpath
(var/"log").mkpath
end
service do
run [bin/"weknora-lite"]
keep_alive true
working_dir var/"weknora"
log_path var/"log/weknora-lite.log"
error_log_path var/"log/weknora-lite.log"
end
def caveats
<<~EOS
:
weknora-lite
:
brew services start weknora-lite # 启动并开机自启
brew services stop weknora-lite # 停止
brew services restart weknora-lite # 重启
brew services info weknora-lite # 查看状态
:
#{var}/log/weknora-lite.log
:
~/.config/weknora/.env.lite
:
~/.local/share/weknora/
LLM :
$EDITOR ~/.config/weknora/.env.lite
brew services restart weknora-lite
EOS
end
test do
assert_predicate bin/"weknora-lite", :executable?
end
end

View File

@@ -1,4 +1,4 @@
.PHONY: help build run test clean docker-build-app docker-build-docreader docker-build-frontend docker-build-all docker-run migrate-up migrate-down docker-restart docker-stop start-all stop-all start-ollama stop-ollama build-images build-images-app build-images-docreader build-images-frontend clean-images check-env list-containers pull-images show-platform dev-start dev-stop dev-restart dev-logs dev-status dev-app dev-frontend docs install-swagger build-lite run-lite package-lite
.PHONY: help build run test clean docker-build-app docker-build-docreader docker-build-frontend docker-build-all docker-run migrate-up migrate-down docker-restart docker-stop start-all stop-all start-ollama stop-ollama build-images build-images-app build-images-docreader build-images-frontend clean-images check-env list-containers pull-images show-platform dev-start dev-stop dev-restart dev-logs dev-status dev-app dev-frontend docs install-swagger
# Show help
help:
@@ -56,11 +56,6 @@ help:
@echo " dev-status 查看开发环境状态"
@echo " dev-app 启动后端应用(本地运行,需先运行 dev-start"
@echo " dev-frontend 启动前端(本地运行,需先运行 dev-start"
@echo ""
@echo "Lite 模式(零外部依赖):"
@echo " build-lite 构建 Lite 版本(先构建前端到 web/,再构建 GoSKIP_FRONTEND=1 跳过前端)"
@echo " run-lite 构建并启动 Lite 版本"
@echo " package-lite 构建并打包 Lite 发行包tarball"
# Go related variables
BINARY_NAME=WeKnora
@@ -236,35 +231,6 @@ build-prod:
LDFLAGS="-X 'github.com/Tencent/WeKnora/internal/handler.Version=$$VERSION' -X 'github.com/Tencent/WeKnora/internal/handler.Edition=standard' -X 'github.com/Tencent/WeKnora/internal/handler.CommitID=$$COMMIT_ID' -X 'github.com/Tencent/WeKnora/internal/handler.BuildTime=$$BUILD_TIME' -X 'github.com/Tencent/WeKnora/internal/handler.GoVersion=$$GO_VERSION' -X 'google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn'"; \
go build -ldflags="-w -s $$LDFLAGS" -o $(BINARY_NAME) $(MAIN_PATH)
# Build Lite version (single binary, SQLite + in-memory queue)
# 会先构建前端到 web/,再构建 Go 二进制SKIP_FRONTEND=1 可跳过前端
build-lite:
@if [ -f frontend/package.json ] && [ "$${SKIP_FRONTEND:-}" != "1" ]; then \
echo ">> Building frontend for Lite..."; \
(cd frontend && npm ci --prefer-offline && npm run build) && \
rm -rf web && cp -r frontend/dist web; \
elif [ "$${SKIP_FRONTEND:-}" = "1" ]; then \
echo ">> Skipping frontend (SKIP_FRONTEND=1)"; \
else \
echo ">> No frontend/package.json, skipping frontend"; \
fi
export EDITION=lite; \
eval "$$(./scripts/get_version.sh env)"; \
LDFLAGS="$$(./scripts/get_version.sh ldflags)"; \
CGO_ENABLED=1 \
CGO_CFLAGS="-Wno-deprecated-declarations" \
CGO_LDFLAGS="-Wl,-no_warn_duplicate_libraries" \
go build -tags "sqlite_fts5" -ldflags="-w -s $$LDFLAGS" -o $(BINARY_NAME)-lite $(MAIN_PATH)
# Run Lite version with .env.lite defaults
run-lite: build-lite
@if [ ! -f .env.lite ]; then echo "Error: .env.lite not found"; exit 1; fi
@set -a && . ./.env.lite && set +a && ./$(BINARY_NAME)-lite
# Package Lite version into distributable tarball
package-lite:
./scripts/package-lite.sh
download_spatial:
go run cmd/download/duckdb/duckdb.go

View File

@@ -1,23 +0,0 @@
[Unit]
Description=WeKnora Lite - Knowledge Base Management System
After=network.target
[Service]
Type=simple
User=weknora
Group=weknora
WorkingDirectory=/opt/weknora
EnvironmentFile=/opt/weknora/.env.lite
ExecStart=/opt/weknora/WeKnora-lite
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/weknora/data
[Install]
WantedBy=multi-user.target

View File

@@ -1,165 +0,0 @@
# WeKnora Lite
零外部依赖的单二进制部署模式。无需 Docker、PostgreSQL、Redis适合快速体验和小规模私有部署。
## 架构
| 组件 | 标准版 | Lite 版 |
|------|--------|---------|
| 数据库 | PostgreSQL | SQLite (WAL) |
| 向量检索 | pgvector / Qdrant / ES | sqlite-vec (vec0) |
| 关键词检索 | ParadeDB BM25 / ES | SQLite FTS5 |
| 消息队列 | Redis + Asynq | 内存 SyncTaskExecutor |
| 会话存储 | Redis | 内存 |
| 流管理 | Redis / 内存 | 内存 |
| 文件存储 | MinIO / COS / 本地 | 本地 |
| 文档解析 | DocReader (gRPC) | 不可用(文本/段落导入可用)|
| 前端 | Nginx 容器 | Go 内置静态文件服务 |
## 快速开始
### 方式一Homebrew 安装macOS / Linux推荐
```bash
brew tap Tencent/weknora https://github.com/Tencent/WeKnora
brew install weknora-lite
```
安装完成后,推荐使用 **brew services** 以后台服务方式运行:
```bash
brew services start weknora-lite # 启动服务(开机自动启动)
brew services info weknora-lite # 查看运行状态
# 首次启动自动创建配置文件 ~/.config/weknora/.env.lite
# 数据存储在 ~/.local/share/weknora/
# 访问 http://localhost:8080
```
常用服务管理命令:
```bash
brew services stop weknora-lite # 停止服务
brew services restart weknora-lite # 重启服务(修改配置后需重启)
brew services info weknora-lite # 查看状态
```
日志位于 `$(brew --prefix)/var/log/weknora-lite.log`
也可以前台直接运行:
```bash
weknora-lite
```
如需修改配置LLM 服务地址、安全密钥等):
```bash
$EDITOR ~/.config/weknora/.env.lite
brew services restart weknora-lite # 修改配置后重启生效
```
> **LLM 服务**WeKnora Lite 需要一个 OpenAI 兼容的 LLM 服务来提供对话和 Embedding 能力。
> 可以使用 [Ollama](https://ollama.com/)本地、通义千问、OpenAI 等任何兼容服务,
> 在配置文件中设置对应的地址和 API Key 即可。
### 方式二:下载预编译包
从 [GitHub Releases](https://github.com/Tencent/WeKnora/releases) 下载对应平台的 tarball
| 文件 | 平台 |
|------|------|
| `WeKnora-lite_*_linux_amd64.tar.gz` | Linux x86_64 |
| `WeKnora-lite_*_linux_arm64.tar.gz` | Linux ARM64 |
| `WeKnora-lite_*_darwin_amd64.tar.gz` | macOS Intel |
| `WeKnora-lite_*_darwin_arm64.tar.gz` | macOS Apple Silicon |
```bash
# 1. 解压
tar xzf WeKnora-lite_v0.2.0_darwin_arm64.tar.gz
cd WeKnora-lite_v0.2.0_darwin_arm64
# 2. 配置
cp .env.lite.example .env.lite
# 编辑 .env.lite配置 LLM 服务地址和安全密钥
# 3. 运行
set -a && source .env.lite && set +a
./WeKnora-lite
# 访问 http://localhost:8080
```
### 方式三:从源码构建
前置条件Go 1.22+(需要 CGO、C 编译器 (gcc/clang)、Node.js 22+(前端构建)。
```bash
make run-lite
```
## 配置
Lite 模式通过 `.env.lite` 文件配置(模板见 `.env.lite.example`)。关键环境变量:
```bash
DB_DRIVER=sqlite # 使用 SQLite
DB_PATH=./data/weknora.db # 数据库文件路径
RETRIEVE_DRIVER=sqlite # SQLite 检索引擎 (FTS5 + sqlite-vec)
STORAGE_TYPE=local # 本地文件存储
LOCAL_STORAGE_BASE_DIR=./data/files
STREAM_MANAGER_TYPE=memory # 内存流管理
# REDIS_ADDR= # 留空 = 不使用 Redis
OLLAMA_BASE_URL=http://127.0.0.1:11434
```
完整配置参见 [.env.lite.example](../.env.lite.example)。
## 后台运行
### Homebrew 用户macOS / Linux
Homebrew 安装后直接使用 `brew services` 管理,详见上方「快速开始 → 方式一」。
### Linux systemdtarball 安装)
tarball 中附带 `weknora-lite.service` 模板,按需修改路径后安装:
```bash
# 创建用户和目录
sudo useradd -r -s /sbin/nologin weknora
sudo mkdir -p /opt/weknora/data
sudo cp WeKnora-lite web/ .env.lite /opt/weknora/
sudo chown -R weknora:weknora /opt/weknora
# 安装并启动服务
sudo cp weknora-lite.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now weknora-lite
# 管理
sudo systemctl status weknora-lite # 查看状态
sudo journalctl -u weknora-lite -f # 查看日志
```
## 功能限制
与标准版相比Lite 版有以下限制:
- **文档解析**:不支持文件上传和 URL 导入的自动解析PDF/Word/Excel 等)。可使用文本和段落方式手动导入。
- **向量检索**sqlite-vec 使用精确 KNN非近似适合 10 万条以下的小规模数据集。
- **并发**SQLite 单写者模型,高并发写入场景下性能不如 PostgreSQL。
- **任务队列**:无持久化队列,进程重启后未完成的异步任务会丢失。
- **知识图谱**:默认禁用 (`NEO4J_ENABLE=false`)。
- **Agent Skills 沙箱**:默认禁用 (`WEKNORA_SANDBOX_MODE=disabled`)。
## 数据目录
默认所有数据存储在 `./data/` 目录下:
```
data/
├── weknora.db # SQLite 数据库
├── weknora.db-wal # WAL 日志
└── files/ # 上传文件
```
备份只需复制整个 `data/` 目录。

View File

@@ -2,7 +2,6 @@
<div class="aside_box">
<div class="logo_box" @click="router.push('/platform/knowledge-bases')" style="cursor: pointer;">
<img class="logo" src="@/assets/img/weknora.png" alt="">
<span v-if="isLiteEdition" class="lite-badge">Lite</span>
</div>
<!-- 租户选择器仅在用户可切换租户时显示 -->
@@ -108,7 +107,6 @@ import { MessagePlugin, DialogPlugin } from "tdesign-vue-next";
import UserMenu from '@/components/UserMenu.vue';
import TenantSelector from '@/components/TenantSelector.vue';
import { useI18n } from 'vue-i18n';
import { getSystemInfo } from '@/api/system';
const { t } = useI18n();
const usemenuStore = useMenuStore();
@@ -129,7 +127,6 @@ const hasMore = computed(() => currentPage.value < totalPages.value);
type MenuItem = { title: string; icon: string; path: string; childrenPath?: string; children?: any[] };
const { menuArr } = storeToRefs(usemenuStore);
let activeSubmenu = ref<string>('');
const isLiteEdition = ref(false);
// 批量管理状态
const batchMode = ref(false)
@@ -465,10 +462,6 @@ onMounted(async () => {
currentSecondpath.value = `chat/${route.params.chatid}`;
}
getSystemInfo().then(res => {
isLiteEdition.value = res.data?.edition === 'lite'
}).catch(() => {})
// 初始化知识库信息
const kbId = (route.params as any)?.kbId as string
if (kbId && isInKnowledgeBase.value) {
@@ -687,19 +680,6 @@ const mouseleaveMenu = (path: string) => {
height: auto;
margin-left: 24px;
}
.lite-badge {
margin-left: 4px;
padding: 1px 6px;
font-size: 11px;
font-weight: 600;
line-height: 18px;
color: #07c05f;
background: #07c05f1a;
border: 1px solid #07c05f40;
border-radius: 4px;
letter-spacing: 0.5px;
user-select: none;
}
}
.logo_img {

View File

@@ -33,11 +33,11 @@
{{ systemInfo?.version || $t('system.unknown') }}
<t-tag
v-if="systemInfo?.edition"
:theme="systemInfo.edition === 'lite' ? 'primary' : 'default'"
theme="default"
variant="light"
size="small"
style="margin-left: 8px;"
>{{ systemInfo.edition === 'lite' ? 'Lite' : 'Standard' }}</t-tag>
>{{ systemInfo.edition || 'Standard' }}</t-tag>
<span v-if="systemInfo?.commit_id" class="commit-info">
({{ systemInfo.commit_id }})
</span>

View File

@@ -1,97 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
#
# 本地构建 + 打包 WeKnora Lite 发行包
#
# 用法:
# ./scripts/package-lite.sh # 自动检测版本
# ./scripts/package-lite.sh v0.2.0 # 指定版本号
# SKIP_FRONTEND=1 ./scripts/package-lite.sh # 跳过前端构建(使用已有 web/
#
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
cd "${ROOT_DIR}"
# Resolve version
if [ -n "${1:-}" ]; then
VERSION="$1"
elif command -v git >/dev/null 2>&1; then
VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "dev")
else
VERSION="dev"
fi
GOOS=$(go env GOOS)
GOARCH=$(go env GOARCH)
ARCHIVE="WeKnora-lite_${VERSION}_${GOOS}_${GOARCH}"
DIST_DIR="dist/${ARCHIVE}"
echo "=== WeKnora Lite Packager ==="
echo " Version : ${VERSION}"
echo " Platform: ${GOOS}/${GOARCH}"
echo " Output : dist/${ARCHIVE}.tar.gz"
echo ""
# ── Step 1: Build frontend (if not skipped) ──
if [ "${SKIP_FRONTEND:-}" != "1" ]; then
if [ -f frontend/package.json ]; then
echo ">> Building frontend..."
(cd frontend && npm ci --prefer-offline && npm run build)
rm -rf web
cp -r frontend/dist web
else
echo ">> No frontend/package.json found, skipping frontend build"
fi
fi
if [ ! -f web/index.html ]; then
echo "WARNING: web/index.html not found — package will not include frontend"
fi
# ── Step 2: Build Go binary ──
echo ">> Building WeKnora-lite binary..."
export EDITION=lite
eval "$(./scripts/get_version.sh env)"
LDFLAGS="-w -s $(./scripts/get_version.sh ldflags)"
export CGO_CFLAGS="-Wno-deprecated-declarations"
if [ "$(uname)" = "Darwin" ]; then
export CGO_LDFLAGS="-Wl,-no_warn_duplicate_libraries"
fi
CGO_ENABLED=1 go build -tags "sqlite_fts5" -ldflags="${LDFLAGS}" \
-o WeKnora-lite ./cmd/server
# ── Step 3: Assemble package ──
echo ">> Assembling package..."
rm -rf "${DIST_DIR}"
mkdir -p "${DIST_DIR}/web"
cp WeKnora-lite "${DIST_DIR}/"
if [ -d web ] && [ -f web/index.html ]; then
cp -r web/* "${DIST_DIR}/web/"
fi
cp .env.lite.example "${DIST_DIR}/"
cp docs/LITE.md "${DIST_DIR}/README.md"
if [ -d config ]; then
cp -r config "${DIST_DIR}/config"
fi
if [ -d migrations/sqlite ]; then
mkdir -p "${DIST_DIR}/migrations/sqlite"
cp -r migrations/sqlite/* "${DIST_DIR}/migrations/sqlite/"
fi
if [ -f deploy/weknora-lite.service ]; then
cp deploy/weknora-lite.service "${DIST_DIR}/"
fi
# ── Step 4: Create tarball ──
echo ">> Creating tarball..."
(cd dist && tar czf "${ARCHIVE}.tar.gz" "${ARCHIVE}")
(cd dist && shasum -a 256 "${ARCHIVE}.tar.gz" > "${ARCHIVE}.tar.gz.sha256")
echo ""
echo "=== Done ==="
echo " dist/${ARCHIVE}.tar.gz"
echo " dist/${ARCHIVE}.tar.gz.sha256"
SIZE=$(du -h "dist/${ARCHIVE}.tar.gz" | cut -f1)
echo " Size: ${SIZE}"

View File

@@ -1,178 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
#
# 本地测试 Homebrew Formula
#
# 流程:打包 → 创建本地 tap → 写入 Formula → brew install → 验证
#
# 用法:
# ./scripts/test-homebrew.sh # 完整测试(含前端构建)
# SKIP_FRONTEND=1 ./scripts/test-homebrew.sh # 跳过前端构建
# SKIP_BUILD=1 ./scripts/test-homebrew.sh # 跳过构建(使用已有 tarball
#
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
cd "${ROOT_DIR}"
TAP_NAME="weknora/test"
FORMULA_NAME="weknora-lite-test"
VERSION="test"
GOOS=$(go env GOOS)
GOARCH=$(go env GOARCH)
ARCHIVE="WeKnora-lite_${VERSION}_${GOOS}_${GOARCH}"
TARBALL="${ROOT_DIR}/dist/${ARCHIVE}.tar.gz"
# ── Step 1: Build package ──
if [ "${SKIP_BUILD:-}" != "1" ]; then
echo "=== Step 1: Build local package ==="
SKIP_FRONTEND="${SKIP_FRONTEND:-0}" ./scripts/package-lite.sh "${VERSION}"
else
echo "=== Step 1: Skipped (SKIP_BUILD=1) ==="
fi
if [ ! -f "${TARBALL}" ]; then
echo "Error: tarball not found at ${TARBALL}"
exit 1
fi
SHA=$(shasum -a 256 "${TARBALL}" | awk '{print $1}')
echo ""
echo " Tarball: ${TARBALL}"
echo " SHA256: ${SHA}"
# ── Step 2: Create local tap ──
echo ""
echo "=== Step 2: Set up local tap ==="
# Create tap if it doesn't exist
TAP_DIR="$(brew --repository)/Library/Taps/weknora/homebrew-test"
if [ ! -d "${TAP_DIR}" ]; then
mkdir -p "${TAP_DIR}/Formula"
(cd "${TAP_DIR}" && git init -q && git commit --allow-empty -m "init" -q)
echo " Created tap: ${TAP_NAME}"
else
echo " Tap already exists: ${TAP_NAME}"
fi
# ── Step 3: Write Formula into tap ──
echo ""
echo "=== Step 3: Generate Formula ==="
cat > "${TAP_DIR}/Formula/${FORMULA_NAME}.rb" << RUBY
class WeknoraLiteTest < Formula
desc "WeKnora Lite (local test)"
homepage "https://github.com/Tencent/WeKnora"
version "${VERSION}"
license "Apache-2.0"
url "file://${TARBALL}"
sha256 "${SHA}"
def install
libexec.install "WeKnora-lite"
pkgshare.install "web" if File.directory?("web")
pkgshare.install "config" if File.directory?("config")
pkgshare.install ".env.lite.example"
if File.directory?("migrations")
pkgshare.install "migrations"
end
(bin/"weknora-lite-test").write <<~SH
#!/bin/bash
CONFIG_DIR="\\\${WEKNORA_CONFIG_DIR:-\\\${XDG_CONFIG_HOME:-\\\$HOME/.config}/weknora-test}"
DATA_DIR="\\\${WEKNORA_DATA_DIR:-\\\${XDG_DATA_HOME:-\\\$HOME/.local/share}/weknora-test}"
mkdir -p "\\\$DATA_DIR/files" "\\\$CONFIG_DIR/config" 2>/dev/null
if [ ! -f "\\\$CONFIG_DIR/config/config.yaml" ]; then
cp -r "#{pkgshare}/config/" "\\\$CONFIG_DIR/config/"
fi
if [ ! -d "\\\$CONFIG_DIR/migrations" ] && [ -d "#{pkgshare}/migrations" ]; then
ln -sf "#{pkgshare}/migrations" "\\\$CONFIG_DIR/migrations"
fi
if [ ! -f "\\\$CONFIG_DIR/.env.lite" ]; then
cp "#{pkgshare}/.env.lite.example" "\\\$CONFIG_DIR/.env.lite"
sed -i'' -e "s|DB_PATH=.*|DB_PATH=\\\$DATA_DIR/weknora.db|" "\\\$CONFIG_DIR/.env.lite"
sed -i'' -e "s|LOCAL_STORAGE_BASE_DIR=.*|LOCAL_STORAGE_BASE_DIR=\\\$DATA_DIR/files|" "\\\$CONFIG_DIR/.env.lite"
echo ""
echo "已创建配置文件: \\\$CONFIG_DIR/.env.lite"
echo ""
fi
set -a
source "\\\$CONFIG_DIR/.env.lite"
set +a
export DB_PATH="\\\${DB_PATH:-\\\$DATA_DIR/weknora.db}"
export LOCAL_STORAGE_BASE_DIR="\\\${LOCAL_STORAGE_BASE_DIR:-\\\$DATA_DIR/files}"
export WEKNORA_WEB_DIR="\\\${WEKNORA_WEB_DIR:-#{pkgshare}/web}"
cd "\\\$CONFIG_DIR"
exec "#{libexec}/WeKnora-lite" "\\\$@"
SH
end
def post_install
(var/"weknora-test").mkpath
(var/"log").mkpath
end
service do
run [bin/"weknora-lite-test"]
keep_alive true
working_dir var/"weknora-test"
log_path var/"log/weknora-lite-test.log"
error_log_path var/"log/weknora-lite-test.log"
end
test do
assert_predicate bin/"weknora-lite-test", :executable?
end
end
RUBY
(cd "${TAP_DIR}" && git add -A && git commit -m "update formula" -q --allow-empty)
echo " Formula written to: ${TAP_DIR}/Formula/${FORMULA_NAME}.rb"
# ── Step 4: Install ──
echo ""
echo "=== Step 4: Install ==="
brew reinstall "${TAP_NAME}/${FORMULA_NAME}" 2>&1 || brew install "${TAP_NAME}/${FORMULA_NAME}"
# ── Step 5: Verify ──
echo ""
echo "=== Step 5: Verify ==="
echo ""
echo " which:"
which weknora-lite-test || true
echo ""
echo " Installed files:"
brew list "${TAP_NAME}/${FORMULA_NAME}"
echo ""
echo " Test paths (isolated from production):"
echo " Config: ~/.config/weknora-test/.env.lite"
echo " Data: ~/.local/share/weknora-test/"
echo ""
echo "=== Done ==="
echo ""
echo "前台运行:"
echo " weknora-lite-test"
echo ""
echo "后台服务:"
echo " brew services start ${TAP_NAME}/${FORMULA_NAME}"
echo " brew services info ${TAP_NAME}/${FORMULA_NAME}"
echo " brew services stop ${TAP_NAME}/${FORMULA_NAME}"
echo ""
echo "日志:"
echo " $(brew --prefix)/var/log/weknora-lite-test.log"
echo ""
echo "卸载测试:"
echo " brew services stop ${FORMULA_NAME} 2>/dev/null"
echo " brew uninstall ${FORMULA_NAME}"
echo " brew untap ${TAP_NAME}"
echo " rm -rf ~/.config/weknora-test ~/.local/share/weknora-test"

View File

@@ -1,74 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
#
# 更新 Homebrew Formula 中的版本号和 sha256
#
# 用法:
# ./scripts/update-homebrew-formula.sh v0.2.0
#
# 会自动从 GitHub Releases 下载 .sha256 文件来填充 Formula。
# 在 CI 中被 release-lite workflow 调用。
#
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
VERSION="${1:?Usage: $0 <version> (e.g. v0.2.0)}"
VERSION_BARE="${VERSION#v}"
FORMULA="${ROOT_DIR}/Formula/weknora-lite.rb"
REPO="Tencent/WeKnora"
BASE_URL="https://github.com/${REPO}/releases/download/${VERSION}"
if [ ! -f "${FORMULA}" ]; then
echo "Error: Formula not found at ${FORMULA}"
exit 1
fi
echo "Updating Formula to version ${VERSION_BARE}..."
fetch_sha256() {
local file="$1"
local url="${BASE_URL}/${file}.sha256"
local sha
sha=$(curl -sSL "${url}" | awk '{print $1}')
if [ -z "${sha}" ] || [ "${#sha}" -ne 64 ]; then
echo "Error: Failed to fetch sha256 from ${url}" >&2
exit 1
fi
echo "${sha}"
}
SHA_DARWIN_ARM64=$(fetch_sha256 "WeKnora-lite_${VERSION}_darwin_arm64.tar.gz")
SHA_DARWIN_AMD64=$(fetch_sha256 "WeKnora-lite_${VERSION}_darwin_amd64.tar.gz")
SHA_LINUX_ARM64=$(fetch_sha256 "WeKnora-lite_${VERSION}_linux_arm64.tar.gz")
SHA_LINUX_AMD64=$(fetch_sha256 "WeKnora-lite_${VERSION}_linux_amd64.tar.gz")
echo " darwin_arm64 : ${SHA_DARWIN_ARM64}"
echo " darwin_amd64 : ${SHA_DARWIN_AMD64}"
echo " linux_arm64 : ${SHA_LINUX_ARM64}"
echo " linux_amd64 : ${SHA_LINUX_AMD64}"
# Use a temp file for portable sed
TMP=$(mktemp)
cp "${FORMULA}" "${TMP}"
# Update version
sed -i.bak "s/^ version \".*\"/ version \"${VERSION_BARE}\"/" "${TMP}"
# Update sha256 values in order of appearance.
# The formula has sha256 lines in this order:
# 1. darwin arm64
# 2. darwin amd64
# 3. linux arm64
# 4. linux amd64
awk -v s1="${SHA_DARWIN_ARM64}" \
-v s2="${SHA_DARWIN_AMD64}" \
-v s3="${SHA_LINUX_ARM64}" \
-v s4="${SHA_LINUX_AMD64}" \
'BEGIN{n=0} /sha256 "/{n++; if(n==1) sub(/"[^"]*"$/,"\"" s1 "\""); else if(n==2) sub(/"[^"]*"$/,"\"" s2 "\""); else if(n==3) sub(/"[^"]*"$/,"\"" s3 "\""); else if(n==4) sub(/"[^"]*"$/,"\"" s4 "\"")} {print}' \
"${TMP}" > "${FORMULA}"
rm -f "${TMP}" "${TMP}.bak"
echo "Formula updated: ${FORMULA}"