initial: team agent workstation for 6-repo matrix

- Dockerfile (Node/Python/Go/Bun + claude-code + gh cli)
- docker-compose.yml (flexible REPOS_DIR, 7 mounts, 6 cache volumes)
- CLAUDE.md (team conventions + red lines + per-repo build/test cmds)
- .claude/settings.json (allow/deny permissions)
- Makefile + scripts/{enter,bootstrap,run-task}.sh
- README.md (onboarding guide)
This commit is contained in:
gongzhiyong
2026-04-23 23:11:16 +08:00
commit 3112ca1d7c
11 changed files with 567 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(git status*)",
"Bash(git diff*)",
"Bash(git log*)",
"Bash(git branch*)",
"Bash(git checkout*)",
"Bash(git switch*)",
"Bash(git add*)",
"Bash(git commit*)",
"Bash(git pull*)",
"Bash(git fetch*)",
"Bash(git stash*)",
"Bash(git push origin*)",
"Bash(gh pr*)",
"Bash(gh issue*)",
"Bash(gh run*)",
"Bash(gh workflow*)",
"Bash(gh auth status*)",
"Bash(npm install*)",
"Bash(npm test*)",
"Bash(npm run*)",
"Bash(npm audit*)",
"Bash(npm outdated*)",
"Bash(pnpm install*)",
"Bash(pnpm run*)",
"Bash(pnpm test*)",
"Bash(bun install*)",
"Bash(bun test*)",
"Bash(bun run*)",
"Bash(pip install*)",
"Bash(pip list*)",
"Bash(uv pip*)",
"Bash(uv run*)",
"Bash(pytest*)",
"Bash(ruff*)",
"Bash(black*)",
"Bash(mypy*)",
"Bash(alembic*)",
"Bash(go build*)",
"Bash(go test*)",
"Bash(go vet*)",
"Bash(go fmt*)",
"Bash(go mod*)",
"Bash(go list*)",
"Bash(make*)",
"Bash(prisma*)",
"Bash(npx prisma*)",
"Bash(docker compose build*)",
"Bash(docker compose config*)",
"Bash(docker compose ps*)",
"Bash(docker compose logs*)",
"Bash(rg*)",
"Bash(fd*)",
"Bash(jq*)",
"Bash(ls*)",
"Bash(cat*)",
"Bash(head*)",
"Bash(tail*)",
"Bash(wc*)"
],
"deny": [
"Bash(git push --force*)",
"Bash(git push -f*)",
"Bash(git push origin main*)",
"Bash(git push origin master*)",
"Bash(git reset --hard*)",
"Bash(git clean -fd*)",
"Bash(git commit --amend*)",
"Bash(rm -rf /*)",
"Bash(rm -rf ~*)",
"Bash(sudo*)",
"Bash(docker system prune*)",
"Bash(docker volume rm*)",
"Bash(terraform destroy*)",
"Bash(terraform apply*)",
"Bash(kubectl delete*)",
"Bash(kubectl apply*)",
"Bash(az containerapp update*)",
"Bash(az containerapp delete*)",
"Bash(alembic downgrade*)",
"Bash(dropdb*)",
"Bash(psql*production*)",
"Read(./**/.env)",
"Read(./**/.env.*)",
"Read(./**/secrets/**)",
"Read(./**/*.pem)",
"Read(./**/*.key)",
"Read(./casdoor-internal/conf/app.conf)",
"Write(./**/.env)",
"Write(./**/.env.*)",
"Write(./**/secrets/**)"
]
},
"env": {
"DISABLE_TELEMETRY": "0",
"CLAUDE_CODE_MAX_OUTPUT_TOKENS": "32000"
}
}
+40
View File
@@ -0,0 +1,40 @@
# =================================================================
# 登录方式(订阅模式无需填任何 KEY)
# =================================================================
#
# 方式 A(推荐):Claude Max/Pro 订阅 OAuth
# —— 本文件任何 KEY 都不用填。启动容器后运行 `/login` 即可。
# 凭证会写入 docker named volume `claude-home`,下次启动自动复用。
#
# 方式 B:Anthropic API Key(按量计费,适合 CI 无人值守)
# ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# =================================================================
# 仓库根目录(如果你的 6 个仓库不在 ai-ops 的父目录)
# =================================================================
# 默认:REPOS_DIR 不设 → 使用 ai-ops/../ (即 ai-ops 的同级)
# 自定义示例:
# REPOS_DIR=/Users/alice/dev/work
# REPOS_DIR=${HOME}/projects
# 注意:6 个仓库必须都在 REPOS_DIR 下,名字与 GitHub 一致:
# chat-gw / xiaoshou / gongdan / casdoor-internal / CloudCostbrank / lobechat-enterprise
# REPOS_DIR=${HOME}/work
# =================================================================
# Git / GitHub(Agent 提 PR 时需要)
# =================================================================
# GH_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
GIT_AUTHOR_NAME=Your Name
GIT_AUTHOR_EMAIL=you@example.com
# =================================================================
# 企业合规:走 AWS Bedrock(代替 Anthropic API)
# =================================================================
# CLAUDE_CODE_USE_BEDROCK=1
# AWS_REGION=us-west-2
# AWS_PROFILE=default
# =================================================================
# 模型覆盖(默认 Opus 4.7,1M 上下文)
# =================================================================
# ANTHROPIC_MODEL=claude-sonnet-4-6
+10
View File
@@ -0,0 +1,10 @@
.env
.env.local
.claude/state/
.claude/logs/
.claude/sessions/
.claude/projects/
.claude/todos/
.omc/
*.log
.DS_Store
+70
View File
@@ -0,0 +1,70 @@
# 6-Repo Enterprise Matrix — Agent Operating Guide
你是这个企业级 SaaS 矩阵的维护者。工作目录 `/workspace` 挂载了 6 个协同工作的仓库。
## 仓库清单与职责
| 目录 | 角色 | 栈 | 端口 | 测试/构建 |
|---|---|---|---|---|
| `chat-gw/` | MCP 工具网关(权限 + 审计 + 路由) | Python 3.12 / FastAPI / asyncpg / Redis | 8000 | `pytest`;`docker compose up --build -d` |
| `xiaoshou/` | B2B 销售管理(客户 / 订单 / 账单) | FastAPI + React 18 / AntD 5 / Vite 5 | 后端 8000 / 前端 5173 | `pytest` + `npm run build`;`alembic upgrade head` |
| `gongdan/` | 工单系统 + KB 聊天 | NestJS + React + Python FastAPI | 后端 3000 / KB 8001 / 前端 5173 | `npm test`;`prisma migrate dev`;`pytest kb-chat-python` |
| `casdoor-internal/` | IAM(Casdoor fork) | Go 1.25 / Beego / xorm / PostgreSQL | 8000 | `make ut`;`make fmt vet`;`make run` |
| `CloudCostbrank/` | 多云成本聚合 | Python FastAPI + Celery + SQLAlchemy 2.0 | 8000 | `pytest`;`alembic upgrade head`;`docker compose up` |
| `lobechat-enterprise/` | 企业版聊天前端 | Next.js 16 + pgvector + Drizzle | 3010 | `bun test`;`docker compose build`;pnpm monorepo |
## 系统拓扑
```
┌──── 用户浏览器 ────┐
│ │
▼ ▼
[lobechat-enterprise] [xiaoshou / gongdan 前端]
│ │
│ ◄── JWT via Casdoor ──►
▼ ▼
[chat-gw MCP] ◄──► [xiaoshou API] [gongdan API] [CloudCostbrank API]
│ ▲
└── 统一身份 ────► [casdoor-internal]
```
## 工作原则
1. **改动前先读当前仓库的 README / Makefile / package.json**,遵循本仓库既有的命名、lint、测试约定;各仓库风格不统一,不要跨仓库硬套。
2. **跨仓库改动要成套提 PR**:例如改 Casdoor 的 role claim 字段,必须同步更新 chat-gw、xiaoshou、gongdan、lobechat 的 JWT 解析代码,并在 PR 描述里互相链接。
3. **验证闭环前不得声称完成**:改了 Python → `pytest`;改了 Go → `make ut`;改了前端 → `npm run build`;改了 SQL 模型 → 跑 `alembic revision --autogenerate` 确认 diff。
4. **提 PR 而非直推 main**:使用 `gh pr create`,描述必须含 "What / Why / Test"。
5. **数据库迁移**:xiaoshou 当前有"pending migrations"遗留问题,任何 model 改动都要显式 `alembic revision` 并检查生成的文件。
## 硬红线(禁止)
- ❌ 修改 `.env` / `secrets/**` / `conf/app.conf`(casdoor-internal 已 `skip-worktree`)
- ❌ 直接 push 到 main / master,force push 任何分支
- ❌ 跑 `docker system prune`、`rm -rf /`、`terraform destroy`、`kubectl delete`
- ❌ 读取或打印任何包含 `TOKEN` / `SECRET` / `PASSWORD` / `AZURE_STORAGE_CONNECTION_STRING` 的值
- ❌ 触碰 lobechat-enterprise 的 242 个 i18n 文件里的 "Enterprise AI Workspace" 品牌字符串(这是 de-brand 改动,升级上游时必须保留)
- ❌ 对 casdoor-internal 的 upstream merge 留下未标注的冲突决策
## CI/CD 现状(每个仓库自带 workflow)
- `chat-gw/.github/workflows/main_gaw-chat-tools.yml` — Azure 部署
- `xiaoshou/.github/workflows/{ci,deploy,frontend-deploy}.yml` — CI + 前后端部署
- `gongdan/.github/workflows/{backend-deploy,post-deploy-smoke,azure-static-web-apps-*}.yml`
- `casdoor-internal/.github/workflows/{build,build-and-deploy,sync}.yml` — 含上游同步
- `CloudCostbrank/` — **缺 CI,需补齐(优先级 P1)**
- `lobechat-enterprise/.github/workflows/deploy-aca.yml` — 仅部署,**缺 CI(优先级 P1)**
任何会改变 lint / test 行为的 PR,都要先本地跑一遍对应 workflow 的核心命令。
## 常用任务入口
- 跨仓库搜索:`rg -t py '<pattern>' chat-gw xiaoshou CloudCostbrank`
- 依赖审计:`cd <repo> && npm audit` / `pip list --outdated` / `go list -u -m all`
- 启动真实环境验证:`cd <repo> && docker compose up -d`,完事 `docker compose down -v`
- 提交前自我审查:调用 `code-reviewer` 子 agent,不要自评自批
## 失败处理
- CI 红:读 `gh run view <id> --log-failed`,定位到文件再动手,不要猜
- Casdoor upstream merge 冲突:先 `git log --oneline origin/upstream-main ^HEAD` 看上游新增,按 `sync.yml` 的策略逐个 hunk 决策
- 测试 flake:不要直接 `@pytest.mark.skip`,先 rerun 3 次确认是否真 flake
+52
View File
@@ -0,0 +1,52 @@
FROM node:22-bookworm
ARG TARGETARCH
ARG GO_VERSION=1.25.0
ENV DEBIAN_FRONTEND=noninteractive \
PATH=/usr/local/go/bin:/root/go/bin:/root/.bun/bin:/root/.local/bin:$PATH \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on
# 换成清华 Debian 镜像(国内网络更稳)+ apt 重试策略
RUN sed -i 's|http://deb.debian.org|https://mirrors.tuna.tsinghua.edu.cn|g; s|http://security.debian.org|https://mirrors.tuna.tsinghua.edu.cn/debian-security|g' /etc/apt/sources.list.d/debian.sources \
&& echo 'Acquire::Retries "8";' > /etc/apt/apt.conf.d/80-retries \
&& echo 'Acquire::http::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries \
&& echo 'Acquire::https::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries
RUN apt-get update && apt-get install -y --no-install-recommends --fix-missing \
git curl ca-certificates gnupg lsb-release \
make build-essential \
python3 python3-pip python3-venv python3-dev \
postgresql-client redis-tools \
jq ripgrep fd-find less vim-tiny tini \
&& ln -s /usr/bin/fdfind /usr/local/bin/fd \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz" \
| tar -C /usr/local -xz
RUN curl -fsSL https://bun.sh/install | bash
RUN npm install -g pnpm@latest @anthropic-ai/claude-code
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
> /etc/apt/sources.list.d/github-cli.list \
&& apt-get update && apt-get install -y --no-install-recommends gh \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --break-system-packages --no-cache-dir \
uv ruff black pytest pytest-asyncio httpx
RUN git config --system --add safe.directory '*' \
&& git config --system pull.rebase false \
&& git config --system init.defaultBranch main
WORKDIR /workspace
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["claude"]
+31
View File
@@ -0,0 +1,31 @@
.PHONY: help bootstrap build up enter task clean logout
help:
@echo "Targets:"
@echo " bootstrap 一键初始化:clone 6 仓库 + 构建镜像"
@echo " build (重)构建镜像"
@echo " enter 进入容器(交互式)"
@echo " task CMD=.. 非交互执行单任务,例: make task CMD='审计 6 仓库的过时依赖'"
@echo " logout 清掉容器内的登录状态"
@echo " clean 删除镜像和所有卷(慎用)"
bootstrap:
./scripts/bootstrap.sh
build:
docker compose build
up enter:
./scripts/enter.sh
task:
@[ -n "$(CMD)" ] || (echo "用法: make task CMD='<任务描述>'" && exit 1)
./scripts/run-task.sh "$(CMD)"
logout:
docker volume rm ai-ops_claude-home 2>/dev/null || true
@echo "已清除登录状态,下次 enter 需要重新 /login"
clean:
docker compose down -v --rmi local
@echo "镜像和卷已清除"
+106
View File
@@ -0,0 +1,106 @@
# ai-ops —— 六仓库企业矩阵的 Agent 工作站
给 `chat-gw / xiaoshou / gongdan / casdoor-internal / CloudCostbrank / lobechat-enterprise`
这六个仓库提供一个开箱即用的 Claude Code 容器化工作环境。
每个团队成员**在自己的机器上**跑自己的容器,用自己的 Claude Max/Pro 订阅登录。
共享的只是这份仓库里的 Dockerfile / CLAUDE.md / settings.json。
## 前置条件
- **macOS / Linux**,装好 Docker Desktop(>= 4.30)并能拉公网镜像
- 有 **Claude Max 或 Pro 订阅**(或 Anthropic API Key)
- 能访问 6 个业务仓库的 GitHub 权限(已配好 ssh-key 或 gh auth login)
## 快速上手(3 分钟)
```bash
# 1. clone 本仓库(ai-ops)到你想放的地方,例如 ~/work
cd ~/work
git clone git@github.com:your-org/ai-ops.git
cd ai-ops
# 2. 一键初始化:clone 6 个业务仓库 + 构建镜像
make bootstrap
# 3. 进容器并登录
make enter
# 容器内:
/login # 浏览器完成 Claude Max/Pro 授权
/status # 确认登录成功
```
完成后,容器里 `/workspace` 下能看到 7 个目录(6 个业务仓库 + `ai-ops` 本身)。
## 目录约定
默认布局(`REPOS_DIR` 不设时):
```
~/work/ ← 任意名字
├── ai-ops/ ← 本仓库
├── chat-gw/
├── xiaoshou/
├── gongdan/
├── casdoor-internal/
├── CloudCostbrank/
└── lobechat-enterprise/
```
如果你 6 个仓库放在别处,编辑 `.env`:
```bash
REPOS_DIR=/Users/alice/projects
```
然后 `make build && make enter` 即可。
## 常用命令
```bash
make enter # 交互进入 Agent
make task CMD="扫描 6 仓库的 CVE 并提 PR" # 非交互单任务
make logout # 清除登录状态
make build # 重新构建镜像(改了 Dockerfile 后)
```
## 权限模型
- 容器内的 Agent 按 `.claude/settings.json` 的 allow/deny 列表行事:
- ✅ 允许:git 操作、`pytest` / `npm test` / `make` / `gh pr`
- ❌ 拒绝:`git push --force`、`rm -rf /`、读 `.env`、`alembic downgrade`、生产数据库操作
- 你宿主机的 `~/.ssh` 和 `~/.gitconfig` 只读挂载到容器内,git push 能用,但 Agent 改不了你本机配置
- 登录凭证存在 docker volume `claude-home`,**不要把这个 volume 导出给队友**——每人各自 `/login` 自己的订阅
## 改团队规范(CLAUDE.md / settings.json)
这两个文件是**全队共享的 Agent 行为约束**:
- `CLAUDE.md` —— 告诉 Agent 每个仓库是做什么的、该怎么测、红线在哪
- `.claude/settings.json` —— allow/deny 权限清单
改动流程:**提 PR 到本仓库(ai-ops),团队 review 合并**。每人下次 `make build && make enter` 就同步到本地。
## 出问题排查
**Docker pull 失败 / TLS 证书错误**
—— 检查是否有 VPN / 代理在做 HTTPS 拦截(例如 Astrill 的 OpenWeb 模式)。换成 WireGuard / StealthVPN,或关闭 VPN 后再拉镜像。
**apt 装包失败**
—— Dockerfile 已配清华镜像 + 重试 8 次。如果仍失败,检查网络对 `mirrors.tuna.tsinghua.edu.cn` 的访问。
**`/login` 后仍提示未登录**
—— 确认你的 Claude 订阅类型是 Max 或 Pro。Free 账号没有 Claude Code 权限。
**想切到 API Key 模式**
—— 编辑 `.env`,填 `ANTHROPIC_API_KEY=sk-ant-...`。API Key 优先级高于订阅。
## 不做什么
- **不是**一个跑在云上的服务,不支持 SSH 远程访问
- **不是**给 CI/CD 用的(CI 场景另用 `.github/workflows/claude-review.yml` + API Key)
- **不**共享登录凭证 —— 每人用自己的订阅,违反 Claude TOS 会被踢
## 许可 / 归属
内部工具,仅限团队使用。六个业务仓库的许可证以各自仓库为准。
+59
View File
@@ -0,0 +1,59 @@
name: ai-ops
services:
claude-agent:
build:
context: .
dockerfile: Dockerfile
image: claude-agent-6repos:latest
container_name: claude-agent
hostname: claude-agent
stdin_open: true
tty: true
working_dir: /workspace
environment:
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
ANTHROPIC_MODEL: ${ANTHROPIC_MODEL:-claude-opus-4-7}
CLAUDE_CODE_USE_BEDROCK: ${CLAUDE_CODE_USE_BEDROCK:-}
AWS_REGION: ${AWS_REGION:-}
AWS_PROFILE: ${AWS_PROFILE:-}
GH_TOKEN: ${GH_TOKEN:-}
GITHUB_TOKEN: ${GH_TOKEN:-}
GIT_AUTHOR_NAME: ${GIT_AUTHOR_NAME:-Claude Agent}
GIT_AUTHOR_EMAIL: ${GIT_AUTHOR_EMAIL:-claude-agent@local}
GIT_COMMITTER_NAME: ${GIT_AUTHOR_NAME:-Claude Agent}
GIT_COMMITTER_EMAIL: ${GIT_AUTHOR_EMAIL:-claude-agent@local}
TERM: xterm-256color
volumes:
# REPOS_DIR 默认指向 ai-ops 的父目录;队友可在 .env 里改成自己的工作目录
- ${REPOS_DIR:-..}/chat-gw:/workspace/chat-gw
- ${REPOS_DIR:-..}/xiaoshou:/workspace/xiaoshou
- ${REPOS_DIR:-..}/gongdan:/workspace/gongdan
- ${REPOS_DIR:-..}/casdoor-internal:/workspace/casdoor-internal
- ${REPOS_DIR:-..}/CloudCostbrank:/workspace/CloudCostbrank
- ${REPOS_DIR:-..}/lobechat-enterprise:/workspace/lobechat-enterprise
- ./CLAUDE.md:/workspace/CLAUDE.md:ro
- ./.claude:/workspace/.claude
- claude-home:/root/.claude
- pip-cache:/root/.cache/pip
- go-cache:/root/go/pkg
- npm-cache:/root/.npm
- pnpm-store:/root/.local/share/pnpm/store
- bun-cache:/root/.bun/install/cache
- ${HOME}/.ssh:/root/.ssh:ro
# 注意:不要挂载 ~/.gitconfig —— 若宿主机没这个文件,Docker 会
# 把它自动创建为「空目录」,导致 git 报错。用上面 GIT_AUTHOR_*
# 环境变量就足够了。
healthcheck:
test: ["CMD", "claude", "--version"]
interval: 30s
timeout: 10s
retries: 3
volumes:
claude-home:
pip-cache:
go-cache:
npm-cache:
pnpm-store:
bun-cache:
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# 新成员一键初始化:
# 1. 克隆 6 个业务仓库到 REPOS_DIR(默认为 ai-ops 的父目录)
# 2. 创建 .env(如果还没有)
# 3. 构建 Docker 镜像
set -euo pipefail
cd "$(dirname "$0")/.."
AI_OPS_DIR="$(pwd)"
# 读取 .env 里的 REPOS_DIR(如果存在)
if [[ -f .env ]]; then
# shellcheck disable=SC1091
source <(grep -E '^REPOS_DIR=' .env || true)
fi
REPOS_DIR="${REPOS_DIR:-$(cd .. && pwd)}"
echo ">>> 仓库将克隆到: $REPOS_DIR"
mkdir -p "$REPOS_DIR"
declare -A REPOS=(
[chat-gw]="https://github.com/Fasthei/chat-gw.git"
[xiaoshou]="https://github.com/Fasthei/xiaoshou.git"
[gongdan]="https://github.com/Fasthei/gongdan.git"
[casdoor-internal]="https://github.com/zsbgnw12/casdoor-internal.git"
[CloudCostbrank]="https://github.com/zsbgnw12/CloudCostbrank.git"
[lobechat-enterprise]="https://github.com/zsbgnw12/lobechat-enterprise.git"
)
for name in "${!REPOS[@]}"; do
target="$REPOS_DIR/$name"
if [[ -d "$target/.git" ]]; then
echo " [skip] $name 已存在"
else
echo " [clone] $name"
git clone "${REPOS[$name]}" "$target"
fi
done
cd "$AI_OPS_DIR"
if [[ ! -f .env ]]; then
cp .env.example .env
echo ">>> 已创建 .env(订阅模式无需改动;用 API Key 的话填上 ANTHROPIC_API_KEY)"
fi
echo ">>> 构建镜像(首次约 5 分钟)"
docker compose build
echo ""
echo ">>> 完成。下一步:"
echo " ./scripts/enter.sh # 进入容器"
echo " 容器内运行 /login # 用你自己的 Claude Max/Pro 订阅登录"
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
# .env 可选(订阅模式下完全无需 key)
if [[ ! -f .env ]]; then
cp .env.example .env
echo "已创建 .env(订阅模式无需填 key,直接继续)"
fi
# 首次构建提示
if ! docker image inspect claude-agent-6repos:latest >/dev/null 2>&1; then
echo ">>> 首次构建镜像(约 5 分钟,下载 Node/Python/Go/Bun 工具链)"
docker compose build
fi
# 检查容器内是否已登录(claude-home 卷里有 .credentials.json)
LOGGED_IN=$(docker volume inspect ai-ops_claude-home >/dev/null 2>&1 \
&& docker run --rm -v ai-ops_claude-home:/h alpine \
sh -c 'test -f /h/.credentials.json && echo yes || echo no' 2>/dev/null || echo no)
if [[ "$LOGGED_IN" != "yes" && -z "${ANTHROPIC_API_KEY:-$(grep -E '^ANTHROPIC_API_KEY=sk-' .env 2>/dev/null || true)}" ]]; then
cat <<'EOF'
>>> 首次登录提示:
进入容器后执行 /login,用浏览器完成 Claude Max 订阅 OAuth。
凭证会持久化到 docker volume,下次直接复用。
EOF
fi
exec docker compose run --rm claude-agent "$@"
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# 非交互跑单任务:./scripts/run-task.sh "审计 6 个仓库的过时依赖并提 PR"
set -euo pipefail
cd "$(dirname "$0")/.."
if [[ $# -lt 1 ]]; then
echo "用法: $0 '<任务描述>'"
exit 1
fi
docker compose run --rm claude-agent \
claude -p "$1" --permission-mode acceptEdits