Local Kanban

本地 Web 看板,用来汇总 SSH 可访问开发机的 GPU 使用情况、IPADS API 额度、本地 Gitea 项目,并从选定 project/branch 准备 workspace 后启动 agent。

启动

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

jq -r .authToken ~/.config/local-kanban/state.json

也可以用固定环境变量覆盖:

KANBAN_AUTH_TOKEN='long-random-token' npm start

如果通过 HTTPS 反代访问,可设置 KANBAN_AUTH_SECURE_COOKIE=1 让浏览器只在 HTTPS 连接发送 cookie。纯 HTTP 暴露在局域网时token 登录能阻止未授权用户直接访问服务,但链路本身不能抵御同网段抓包;需要“强隔离”时应配合 HTTPS、VPN 或 SSH tunnel。

HTTPS 反代推荐让 Node 只监听本机:

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 服务:

./scripts/install-user-systemd.sh

配置

可以用环境变量快速配置:

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

{
  "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

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 <host> 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” 发送新指令。

继续会话使用:

codex --dangerously-bypass-approvals-and-sandbox exec --sandbox danger-full-access --cd <workspace> resume <session_id> <prompt>
Description
No description provided
Readme 92 KiB
Languages
JavaScript 59%
CSS 27.2%
HTML 7.8%
Shell 6%