sq.kashic.cn

开发者指南

把版本推到 kashic 分发服务,或从契约里读取最新版。本文同时是人类说明书与 AI 代理执行规格。

下载 MD(给 AI 用) 看一个真实契约 MD 内含可直接执行的命令、客户端拉更新协议与校验步骤,交给 AI 代理即可自主发布

1 · 模型

三层结构,一切分发都落在这三层的组合上:

项目 project(slug)  →  版本 release(version, channel)  →  资产 asset(文件名, size, sha256)

2 · 公开接口(读,无需鉴权)

用途请求
作品列表(含最新版本与下载地址)GET /works.json
某项目最新版契约GET /<slug>/latest.json
下载资产(支持子路径)GET /<slug>/files/<文件名>

契约与 GitHub releases 同形,客户端逐项校验:

{
  "tag_name": "v1.14.85",
  "body": "更新说明",
  "draft": false,
  "prerelease": false,
  "assets": [
    {
      "name": "loli_v1.14.85.amr",
      "size": 5524002,
      "digest": "sha256:8fa34b07…(64 位十六进制)",
      "browser_download_url": "https://sq.kashic.cn/loliapp/files/loli_v1.14.85.amr"
    }
  ]
}
digest 缺失即拒绝该资产;size 必填;契约响应 no-store,可放心轮询。

3 · 客户端拉更新(读端协议)

客户端只需一个 slug,就能自行完成「查版本 → 选资产 → 下载 → 校验」全流程。按下面顺序做即可:

① 拉取时机与地址

GET https://sq.kashic.cn/<slug>/latest.json        # 稳定版
got https://sq.kashic.cn/<slug>/latest.json?channel=prerelease   # 预发布通道

建议时机:启动时拉一次 + 用户手动「检查更新」,或每 24 小时一次。契约带 no-store,不会拿到陈旧数据,高频拉取也不会踩缓存。

② 版本比较(拿 tag_name 比本地版本)

③ 选资产

④ 下载 + 必校验(顺序不能反)

  1. 下到临时文件(不要直接覆盖正在运行的副本)
  2. 字节数 == size?不符丢弃重试
  3. sha256 == digest 后半段(不区分大小写)?不符丢弃重试
  4. 都通过后再替换旧文件;若替换会失败,可保留一份旧版回滚

⑤ 最小可用示例(Python,直接能跑)

import json, re, hashlib, urllib.request, pathlib

BASE, SLUG, ASSET = "https://sq.kashic.cn", "dshl", "DSHL-update.zip"
LOCAL = "0.1.1.5"                            # 本地当前版本

def ver(v):
    p = [int(x) if str(x).isdigit() else 0 for x in str(v).lstrip("vV").split(".")]
    return tuple((p + [0, 0, 0, 0])[:4])

rel = json.load(urllib.request.urlopen(f"{BASE}/{SLUG}/latest.json", timeout=20))
if rel.get("draft") or rel.get("prerelease"):
    raise SystemExit("跳过非稳定版")
if ver(rel["tag_name"]) <= ver(LOCAL):
    raise SystemExit("已是最新")

asset = next((a for a in rel["assets"] if a["name"] == ASSET), None)
assert asset, f"新版本缺少资产 {ASSET}"
assert re.fullmatch(r"sha256:[a-fA-F0-9]{64}", asset["digest"]), "digest 格式非法"

data = urllib.request.urlopen(asset["browser_download_url"], timeout=600).read()
assert len(data) == asset["size"], "字节数不符"
assert hashlib.sha256(data).hexdigest() == asset["digest"].split(":")[1].lower(), "哈希不符"

pathlib.Path("/tmp/" + ASSET).write_bytes(data)   # 校验通过后才落盘/替换
print("已下载", ASSET, len(data), "B")
多分量客户端把「版号比较 + 下载校验」循环套到每个分量上即可;每个分量的最新版本号可以从资产文件名 <分量>_v<版本> 里解出,或让服务方提供一个分量清单接口。

4 · Key 与权限

5 · CLI

脚本:/usr/local/bin/kashic-push(纯标准库 python3,拷走即用)。

# 配置 key(二选一)
export KASHIC_HUB_KEY=kh_xxxxxxxx
# 或:mkdir -p ~/.config/kashic-hub && echo kh_xxxxxxxx > ~/.config/kashic-hub/key

kashic-push whoami                  # 校验 key,打印身份与绑定项目
kashic-push projects                # 可见项目
kashic-push latest <slug>           # 打印公网契约
kashic-push release <slug> <文件> \
  --version 1.2.3 --notes "本次更新…" --channel stable

环境变量 KASHIC_HUB_SERVER 可覆盖服务地址(默认 https://sq.kashic.cn/api)。

6 · HTTP API(脚本 / CI 直调)

# 发布一个完整版本(单资产)
curl -X POST https://sq.kashic.cn/api/projects/<slug>/releases \
  -H "Authorization: Bearer $KASHIC_HUB_KEY" \
  -F "version=0.3.0" -F "notes=本次更新…" -F "channel=stable" \
  -F "file=@./DSHL-update.zip"

# 推送/更新一个分量(多资产项目)
curl -X POST https://sq.kashic.cn/api/projects/<slug>/components \
  -H "Authorization: Bearer $KASHIC_HUB_KEY" \
  -F "name=cvi" -F "version=1.14.86" -F "file=@./cvi_v1.14.86.amr"

管理接口需 cookie(auth.kashic.cn 登录且 power==1)或请求头 X-Admin-Token。

7 · 错误码

码含义处理
401未带凭据 / key 无效或已撤销检查 Bearer 与 key 状态;不要重试
403key 绑定的是别的项目换该项目专用 key
404项目不存在或未发布过先让管理员建项目 / 发布一次
413超过上传上限(4 GB)拆分或压缩
502/504大文件上传超时可安全重试

8 · 给 AI 代理的要点

  1. 只需要一把分发 key;不要向用户索要管理员口令。
  2. 发布 = 一次 multipart POST + 回读契约验证 digest,一致才算成功。
  3. 路径固定为 /api/projects/<slug>/releases 与 /<slug>/latest.json(整站就是分发服务,直接拼域名根路径即可)。
  4. 永远不要打印或写日志 key 内容,从环境变量读取。
  5. 401/403 不要重试,直接报给用户。