No description
  • JavaScript 95%
  • Shell 5%
Find a file
2026-10-15 06:18:37 +00:00
harmony/xyzide-hm 提交 2 处改动(2026-10-15 14:18) · Code · xyzide 2026-10-15 06:18:37 +00:00
xyzide 提交 4 处改动(2026-10-15 13:45) 2026-10-15 05:45:10 +00:00
xyzide-node 提交 4 处改动(2026-10-15 13:45) 2026-10-15 05:45:10 +00:00
.gitignore init 2026-10-14 12:40:12 +08:00
README.md init 2026-10-14 12:40:12 +08:00

xyzide

装在你自己的机器上的 AI 开发环境。数据全在你机器上 —— 文件、代码、git、编译都在本地, 云上那份只管"谁能用、从哪个门进",而且看不到你的内容(它只搬加密字节)。

xyzide/         服务中心(云上)—— 账号、授权码、子域名与端口分配、SNI 分流、发布
xyzide-node/    节点(客户自己的 Linux)—— 文件 / 索引 / 搜索 / git / 编译 / 反编译 / 收藏
harmony/        鸿蒙客户端
win/            Windows 客户端(还没放进来)
dist/           打包产物(zip + sha256)

线上现状(2026-10-12)

服务中心 https://ide.xyztang.xyz(云 39.105.10.233;systemd xyzide,只监听 127.0.0.1:2011)
客户入口 https://<子域名>.ide.xyztang.xyz —— 443 按 SNI 直达客户机,TLS 在客户机终结;http:// 同域名仍可用
装机 / 升级 curl -fsSL https://ide.xyztang.xyz/xyzide.sh | sudo bash(已经装过 = 原地升级)
节点上升级 sudo xyzide update(还有 --check / --dry-run / --file)
节点看证书 xyzide cert status(issue / renew / selfsign;证书由节点自己用内置 ACME 签,装完自动签)
发布新版本 cd xyzide-node && ./pack/release.sh --via-http --notes "改了什么"
已接入节点 1 台(desktop-1hf4nts,本机 WSL 自测);记录在云上 xyzide.subdomains 表

职责划分

一句话:服务中心管"谁能用、从哪个门进",节点管"东西在哪、怎么改"。 数据在节点,权限在服务中心;凭据过桥,客户流量的字节不过云的应用层。

xyzide(服务中心 · 云) xyzide-node(节点 · 客户机器)
定位 控制面 数据面
账号 邮箱验证码登录 / 注册、试用、停用、续期 没有账号概念
数据库 MySQL + Redis 一行数据库代码都没有
授权码(唯一凭据) 账号的属性:签发 / 换码 / 吊销,UUID,明文入库 只存哈希,请求时比对"对不对";不判过期、不连云
子域名 / 隧道 唯一分配权威(subdomains 表,含归属 user_id) 用分配来的
文件 / 索引 / git / 编译 从不碰内容 全在这儿
TLS 只搬加密字节(L3/L4),解不了客户流量 客户流量的 TLS 在这台机器终结(2443;证书本机 ACME 自签,私钥不出机器)
发布 GET /release + POST /release/publish(存 /opt/xyzide/releases/) xyzide update 拉最新版
收藏夹 — 本机 JSON(data/favs.json)

四条硬约定

  1. 全产品只有一个凭据概念 = 授权码(UUID):客户端 Authorization: Bearer <授权码> 直接访问节点; 没有"安装码"、没有"用户 token"
  2. 权限在云上判,生效在客户端:节点只比哈希(不判过期、不连云);过期由客户端问云 POST /key/check,过期就锁界面。代价:码没过期前谁拿着都能用,要立刻停人只能换码
  3. 云不解密客户流量:443 上按 SNI 分流(nginx stream + ssl_preread),客户的加密字节 经隧道直达客户机 —— 云上没有客户证书、没有私钥。反过来说:绝不把客户域名的证书私钥放云上
  4. "账号 → 根目录"写在凭据/授权里:一个账号可以有多台节点(subdomains 一行一台,1:N)

一次请求怎么走

客户端 ── HTTPS/http ──> <子域名>.ide.xyztang.xyz:443/80
                          │
                云 nginx(按 SNI / Host 分流,不解密)
                          │
        ┌─────────────────┴──────────────────┐
        │ tunnel.*  → 127.0.0.1:18099         │ ← 节点主动连上来的那条隧道(TLS+SNI)
        │ <客户子域名> → /run/xyzide/<子域名>-tls.sock(或 -http.sock)
        └─────────────────┬──────────────────┘
                          │  隧道接入器(多路复用,一条长连接带多条流)
                          ▼
                   客户机 xyzide-node:  2010(http)/ 2443(https:TLS 在这台机器终结,明文原样接给 2010)

客户端另外还会问云两个接口:POST /key/check(我的码过期没)、GET /key/mine(换客户端时把码取回来)。

证书怎么来的:节点自己跑 ACME(HTTP-01),挑战经云 80 转到本机 (http://<子域名>/.well-known/acme-challenge/<token> → 云 80 → 隧道 → 本机 2010 应答), 私钥从头到尾只在节点。签不下来时先用自签顶着,隧道一恢复就自动换成真证书(xyzide cert status 看)。

几个口径(容易忘)

  • 续费不换码:只改 users.expires_at;换码只用在"泄漏/停用",换完在那台机器上跑 xyzide set-license
  • 节点默认不打印任何云侧信息(隧道域名/SNI/云上端口/服务中心地址),要排查加 --verbose
  • 云上不占额外端口:每台节点的投递点是 unix socket(/run/xyzide/<子域名>-{tls,http}.sock), 不是 TCP 端口;对外的服务端口只有 80/443(另有运维用的 SSH 10022,跟业务无关)
  • 云上的"端口段 19000-19999"是历史遗留(subdomains.tunnel_port 现在只当节点编号用,不再监听)

还没做

  • https:节点侧签自己的证书 + 开 2443 TLS 前端(2026-10-12 落地:内置 ACME + 自签兜底 + 自动续期, 客户入口已是 https://;下一条"客户端改造"做完才算产品上切干净)
  • 客户端改造:填授权码 + 问 /key/check + 过期锁界面 + pin 证书指纹(入口地址要换成 https)
  • 把本机别的服务挂到外网(2026-10-14:xyzide expose add git|dsh → https://<子域名>/git、/dsh; 云侧零改动;只作用于 HTTPS 入口,http:// 那条还没分流)
  • 证书到期前的提醒(自动续已经有了,缺"要出事了报警"这条通道);泛域名/多域名(要 dns-01)
  • "云上批量看谁还是旧版"(subdomains.version 已经有了)
  • 多租户托管的 scope 硬围栏(代码在,默认关;单租户用不上)