From 677d41074b2bb3e17c54874486e928bd9e92b9d1 Mon Sep 17 00:00:00 2001 From: Gahow Wang Date: Fri, 15 May 2026 11:14:27 +0800 Subject: [PATCH] docs: add project README and deployment guide Document how to start, configure, and deploy the local Kanban app including auth, GPU hosts, Gitea integration, quota checking, and agent session management. --- README.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f09c9ee --- /dev/null +++ b/README.md @@ -0,0 +1,141 @@ +# Local Kanban + +本地 Web 看板,用来汇总 SSH 可访问开发机的 GPU 使用情况、IPADS API 额度、本地 Gitea 项目,并从选定 project/branch 准备 workspace 后启动 agent。 + +## 启动 + +```bash +npm start +``` + +默认地址是 `http://127.0.0.1:5180`,生产访问通常走 `https://gahow-pc.ipads-lab.se.sjtu.edu.cn:8443/` 的本地 Nginx 反代。 + +首次启动会生成访问 token,并保存到 `~/.config/local-kanban/state.json`。登录页需要输入这个 token: + +```bash +jq -r .authToken ~/.config/local-kanban/state.json +``` + +也可以用固定环境变量覆盖: + +```bash +KANBAN_AUTH_TOKEN='long-random-token' npm start +``` + +如果通过 HTTPS 反代访问,可设置 `KANBAN_AUTH_SECURE_COOKIE=1` 让浏览器只在 HTTPS 连接发送 cookie。纯 HTTP 暴露在局域网时,token 登录能阻止未授权用户直接访问服务,但链路本身不能抵御同网段抓包;需要“强隔离”时应配合 HTTPS、VPN 或 SSH tunnel。 + +HTTPS 反代推荐让 Node 只监听本机: + +```bash +KANBAN_HOST=127.0.0.1 \ +KANBAN_PORT=5180 \ +KANBAN_AUTH_SECURE_COOKIE=1 \ +KANBAN_REQUIRE_HTTPS=1 \ +npm start +``` + +Nginx 示例在 `deploy/nginx.local-kanban.conf`。当前设计是: + +- `https://gahow-pc.ipads-lab.se.sjtu.edu.cn/` 是入口首页 +- 每个服务仍然保留自己的端口,例如 Kanban 是 `https://gahow-pc.ipads-lab.se.sjtu.edu.cn:8443/` +- 入口首页展示 Gitea、Kanban、Stock Agent 三个常用服务 +- 后端 API 链接默认折叠,需要时展开 + +系统 Nginx 负责: + +- TLS 终止 +- 在 443 提供静态入口首页 +- 在 3443 反代 Gitea 的 3300 +- 在 5443 反代 Stock Agent 前端的 5174,并把 `/api` 转发到 8787 +- 在 8788 直接反代 Stock Agent API 的 8787 +- 默认不监听 80,避免和现有本地服务冲突 + +没有 sudo 时,可以使用当前仓库里的用户级 Nginx 配置监听 8443,详见 `deploy/README.md`。 + +如果需要持久运行 Node app 和用户级 Nginx,可以安装用户级 systemd 服务: + +```bash +./scripts/install-user-systemd.sh +``` + +## 配置 + +可以用环境变量快速配置: + +```bash +KANBAN_GPU_HOSTS=dash0,dash1 \ +KANBAN_GITEA_BASE_URL="http://gahow-pc.ipads-lab.se.sjtu.edu.cn:3300" \ +npm start +``` + +也可以创建 `~/.config/local-kanban/config.json`: + +```json +{ + "gpuHosts": ["dash0", "dash1"], + "gitea": { + "baseUrl": "http://gahow-pc.ipads-lab.se.sjtu.edu.cn:3300", + "tokenEnv": "GITEA_TOKEN" + }, + "workspaceRoot": "/home/gahow/.local/share/local-kanban/workspaces", + "authSecureCookie": true, + "requireHttps": true, + "quotaSources": [ + { + "id": "ipads", + "label": "IPADS API", + "type": "command", + "command": "bash", + "args": ["-lc", "curl -sS -H \"Authorization: Bearer $IPADS_API_KEY\" http://tianx.ipads-lab.se.sjtu.edu.cn:8319/v1/usage | jq '{remaining, usage}'"], + "timeoutMs": 15000 + } + ], + "agentProfiles": [ + { + "id": "codex-full", + "label": "Codex Full Permission", + "command": "codex", + "args": [ + "--dangerously-bypass-approvals-and-sandbox", + "exec", + "--sandbox", + "danger-full-access", + "--cd", + "{workspace_path}" + ] + } + ] +} +``` + +GPU 机器列表可以在 Web 页面里编辑保存,保存位置是 `~/.config/local-kanban/state.json`。默认只读取当前项目目录的 `/home/gahow/projects/kanban/.env`。需要的 key 可以参考 `.env.example`: + +```bash +GITEA_TOKEN=replace-with-your-gitea-token +IPADS_API_KEY=replace-with-your-ipads-api-key +``` + +也可以用逗号分隔的 `KANBAN_ENV_FILE` 指向其他 env 文件。 + +## API + +- `GET /api/gpus`: 查询 `ssh nvidia-smi --query-gpu=index,name,memory.used,memory.total,utilization.gpu --format=csv,noheader,nounits` +- `PUT /api/settings/gpu-hosts`: 保存需要监控的 GPU 机器列表 +- `POST /api/auth/login`: 使用本地 token 登录并设置 HttpOnly cookie +- `POST /api/auth/logout`: 清除登录 cookie +- `GET /api/quotas`: 执行默认的 IPADS API 额度命令 +- `GET /api/repos`: 从 Gitea `/user/repos` 读取仓库 +- `GET /api/branches?repo=owner/name`: 从 Gitea 读取 branch list +- `GET /api/agent-profiles`: 返回可选 AI 配置 +- `POST /api/tasks`: 准备选定 project/branch 的 workspace 后启动 agent 命令 +- `GET /api/dashboard`: 聚合以上数据,供 Web 和后续 iOS 复用 + +## Agent Session 历史 + +任务历史会保存到 `~/.config/local-kanban/state.json`。每次 Codex 启动后,服务会从输出中提取 `session id` 并记录到对应的 project/branch。之后在同一个 project/branch 下,可以在 Web UI 的 “历史 Session” 下拉框里选择之前的任务,点击 “继续 Session” 发送新指令。 + +继续会话使用: + +```bash +codex --dangerously-bypass-approvals-and-sandbox exec --sandbox danger-full-access --cd resume +```