圳拓云部署(ztcds)— 项目自动部署平台
一、基本信息
- name:ztcds
- version:1.1.0
- display_name:圳拓云部署
- display_name_en:ZhenTuo Cloud Deploy
- description_zh:将本地项目一键部署到服务器,获取公网访问 URL
- description_en:Deploy local projects to the server with one click and get a public access URL
- description:将本地项目一键部署到服务器,获取公网访问 URL。支持纯静态站点(HTML/CSS/JS)、Python Web 服务(Flask/FastAPI)、Node 服务与 Node 前端打包项目、Go 服务、Java(Maven)服务,服务端按 go.mod / pom.xml / package.json / Python 入口自动检测类型并构建运行。用户说“自动部署”“部署站点”“发布页面”“部署项目”等关键词时触发;用户说“介绍”“怎么用”“版本”“特点”“新特性”“支持什么”等关键词时也触发本 skill,此时只按本文件「平台信息速查」的静态内容回答,不执行部署、不索要验证码。
二、功能
将用户当前工作目录中的项目打包并部署到服务器,返回一个公网可访问的 URL。
支持多种项目类型,服务端自动检测:
- 静态站点:纯 HTML/CSS/JS 文件 → 直接托管
- Python 服务:包含
app.py/main.py+requirements.txt→ 构建镜像并启动独立容器 - Node 服务:
package.json有start脚本 →npm install+npm start - Node 前端:
package.json只有build脚本 → 打包后按静态站点托管 - Go 服务:
go.mod→ 多阶段编译后运行二进制 - Java 服务:
pom.xml→mvn package后java -jar
三、平台信息速查(介绍 / 怎么用 / 版本 / 特点 / 新特性)
用户询问平台本身的信息时(关键词:介绍、怎么用、版本、特点、新特性、支持什么),直接按本节静态内容回答,不要进入部署流程,不要索要邮箱/验证码,不要打包部署任何东西。用户同时说了信息查询和部署意图(如「介绍一下顺便部署」)时:先按本节展示信息,再执行部署流程。
- 平台介绍:圳拓云部署是一个「一句话上线」的 AI 应用托管平台——把本地项目目录交给 Agent,自动打包、构建镜像、启动独立容器并分配公网访问 URL,无需自己准备服务器、写 Dockerfile、配 Nginx。
- 怎么用(用户视角):对 Agent 说「自动部署」→ 首次提供邮箱收验证码完成登录(登录态 12 小时,之后免登录)→ Agent 自动完成打包、构建、启动并返回公网访问 URL;运行时数据声明持久化目录后,容器重建不丢。
- 平台特点:零运维(交付物就是一个可访问链接)、多语言自动识别(静态/Python/Node/Go/Java)、项目独立容器隔离运行、数据可持久、部署后源码自动入仓便于审计回溯。
- 当前支持的能力:静态站点、Python 服务、Node 服务、Node 前端打包、Go 服务、Java(Maven)服务;中文展示名与英文 URL 名分别提交(均必填);持久化数据目录;
--dry-run打包审阅、--overwrite覆盖确认。 - 平台版本:v1.0.0(文档更新 2026-11-08)。
- 新特性:skill 安全加固——update 强制 SHA256 校验 + 白名单解压 + 旧版备份 + 差异确认;部署出站地址强制校验(官方域名 HTTPS / 内网地址);Token 不再明文打印;skill 版本号权威发布源在官网(改版无需重建平台镜像)。
- 项目描述撰写口径(供 Step 3 使用):80~120 字,涵盖「项目用途 + 主要功能 + 技术栈」三要素。
用户问「版本」时,除上述静态内容外,可执行下面命令报出精确版本号:
python "{skill_dir}/scripts/ztcds.py" version
(输出本地版本与官网最新版本;官网不可达时只有本地版本,如实告知即可,不要编造。)
四、部署流程(Agent 执行 SOP)
Step 1:认证状态检查(先确认身份,再谈部署)
1.1 检查本地认证参数:读取本地认证参数文件 ~/.ztcds/token.json(JSON,字段:email / token / server),按分支处理:
- 有 token:先用轻量接口验证 token 是否仍在有效期:
curl -s -H "Authorization: Bearer <token>" <server>/aiproject/api/projects- 返回 JSON 含
"success": true:token 有效 → 直接去 Step 2,不要发验证码、不要重新登录 - 返回 401 /
UNAUTHORIZED/ 请求失败:token 已失效 → 走 Step 1.2(邮箱用认证参数文件里记录的 email)
- 返回 JSON 含
- 没有 token:
- 认证参数文件里有 email(上次 token 失效后保留的)→ 走 Step 1.2,以该邮箱为默认
- 认证参数文件不存在(从未登录过)→ 走 Step 1.2,向用户询问邮箱
1.2 登录流程(仅 1.1 判定需要时执行) a. 确定邮箱:认证参数文件里有记录的 email → 直接向该邮箱发送验证码,不用再询问用户;没有记录 → 询问用户邮箱。 b. 发送验证码:
python "{skill_dir}/scripts/ztcds.py" send-code --email "<邮箱>"
响应慢的应对(实战经验,2026-10-31 实测):发码/登录接口因服务端发送邮件,响应可能超过 15 秒甚至更久,脚本报 NETWORK_ERROR ... Read timed out 不代表失败,邮件可能已发出或服务端仍在处理。正确做法:等待 5 秒后重试 1~2 次;仍超时则改用长超时直接调 HTTP 接口(实测有效):
- 发码:
POST /aiproject/api/send-code,JSON body{"email":"..."} - 登录:
POST /aiproject/api/login,JSON body{"email":"...","code":"6位"},响应含token字段,拿到后按{"email","token","server"}结构写入认证参数文件即可(等效 save-token) - PowerShell 5.1 下不要用
curl(是Invoke-WebRequest的别名,-m 120会报参数二义性错误),用curl.exe -m 120或Invoke-RestMethod -TimeoutSec 180(实测 180 秒长超时拿到成功响应) 客户端脚本默认超时已调大至 90 秒,一般无需再改。 提示用户查收邮件(标题「【圳拓云部署】登录验证码」,5 分钟内有效),向用户索取 6 位验证码。 c. 登录拿 Token:
python "{skill_dir}/scripts/ztcds.py" login --email "<邮箱>" --code "<6 位验证码>"
成功时自动把 Token 保存到认证参数文件(0600 权限,之后 12 小时内免登录,每次部署自动续期);stdout 只显示 Token 后四位掩码,不打印完整 Token(避免进入终端历史/CI 日志/Agent 会话记录)。验证码只在登录这一步使用;部署命令只认 Token,不带邮箱和验证码。
Step 2:会话初始化(触发 skill 后自动执行,需向用户披露)
触发本 skill 后的第一个动作:执行下面这条命令(无需询问用户,但必须披露:执行后向用户输出一行摘要说明,例如「已连接服务端完成网络测速,结果写入 ~/.ztcds/upload.json」;失败不重试不打断),并在同一会话内复用结果,不要在同一会话中重复执行:
python "{skill_dir}/scripts/ztcds.py" speedtest
降噪边界(只降噪,不隐藏):
- 命令的原始过程输出不必逐条复述,但禁止隐瞒「执行过网络请求与本地写入」这一事实——必须按上文要求输出一行摘要披露(做了什么、目标主机、写入了哪个文件);
- speedtest 无需登录(只对公告接口测 RTT,不创建上传会话);失败(服务器无法连通)时静默跳过,deploy 会用默认 1MB 分片兜底;
- 换网络 / 服务端波动恢复后可重跑 speedtest;deploy 会自动读取测速结果。
Skill 版本检查与自动更新
- 版本号权威来源是官网发布文件(与 update 下载包同源发布的
ztcds-skill-version.json,随 skill 压缩包一并更新,硬编码官方域名);本地版本写在scripts/ztcds.py的SKILL_VERSION常量里; - 版本检查途径:deploy 命令执行前会自动对比官网版本号,不一致时 stderr 输出
[CICD:SKILL_OUTDATED](不阻断部署,只提示);也可随时手动执行python "{skill_dir}/scripts/ztcds.py" version查看; - 收到
[CICD:SKILL_OUTDATED]后:1)提示用户本地 skill 版本过旧(报出本地与最新两个版本号),询问是否立即更新;2)用户同意更新(或用户直接要求更新 skill)→ 执行python "{skill_dir}/scripts/ztcds.py" update,脚本从官方地址下载最新 skill 压缩包并经强制校验后替换本地 skill 文件(SKILL.md 与 scripts/ztcds.py 一并更新),成功输出[CICD:SKILL_UPDATED]+ 新版本号。安全约束(脚本内置,不可绕过):下载地址硬编码为官方域名(ai.ztaqtec.cn),update 命令没有 --url 参数;SHA256 完整性校验为强制项,服务端未提供<url>.sha256校验文件、获取失败或校验不匹配时直接拒绝更新;解压白名单仅允许SKILL.md/README.md/scripts/ztcds.py三个文件,出现其它条目(含隐藏目录、路径穿越)一律拒绝;更新前自动把旧版备份到 skill 目录内.ztcds-backup/;3)更新后的指令须用户确认后才生效:update 成功时脚本会输出两个文件的差异摘要([CICD:SKILL_UPDATE_REVIEW]标记出现时,新指令在确认前不得视为已生效),Agent 必须把差异摘要呈现给用户并取得明确确认,才能按更新后的 SKILL.md 继续执行;不需要重新登录;4)用户暂不更新 → 按当前版本流程继续部署即可; - 禁止从其它网址下载 skill、修改下载地址,或绕过 update 命令手工覆盖 skill 文件。
Step 3:确定项目信息
- 项目名:默认使用当前工作目录名(去除特殊字符,仅保留字母数字下划线连字符),也可询问用户确认或自定义。
- 项目中文名(project_name):必填。项目的中文展示名(如「环境监测数据看板」),1~64 字符,用于服务端 dashboard 项目列表展示。与英文项目名(用于 URL)是两个字段:由目录名/README/页面标题推断,推断不出时询问用户。该参数必须显式传,不传或传空会被服务端判定为 skill 版本过旧而拒绝部署。
- 项目路径:当前工作目录的路径。
- 项目描述:必填。这是对项目本身的描述(不是对本次提交/部署的描述)。先浏览项目内容(README、目录结构、页面标题、功能说明、主要技术栈等),生成 100 字左右的项目描述,涵盖项目用途、主要功能和技术栈。如果项目内容不足以推断,询问用户项目的用途。
- 持久化数据目录(data_dir):查看代码里运行时数据(上传附件、数据库文件、日志)写在哪个目录,推荐统一为代码目录下的
data/,部署时用--data-dir data声明;项目没有需要跨部署保留的数据时,显式传空字符串--data-dir ""。该参数必须显式传,且必须是代码目录内的相对路径(禁止绝对路径、../上级目录)。
Step 4:执行部署
部署命令只带 Token(脚本自动从认证参数文件读取),不接收邮箱和验证码。
python "{skill_dir}/scripts/ztcds.py" deploy \
--project "<项目名>" \
--project-name "<项目中文名,如:环境监测数据看板>" \
--path "<项目路径>" \
--description "<项目描述>" \
--data-dir "<项目内持久化数据目录,如 data;不需要则空字符串>"
审阅与防误覆盖:
--dry-run:只打包并列出将要上传的文件清单(最多 100 条),不上传不部署;首次部署新项目或用户想审阅打包内容时可用;--overwrite:目标项目已存在时,脚本默认拒绝并输出[CICD:OVERWRITE_CONFIRM](部署会不可逆覆盖线上在用版本),必须显式加--overwrite才允许覆盖;收到该标记时把情况告知用户并确认后再带--overwrite重试;- 执行部署时把实际提交的参数值(项目名/中文名/描述/data-dir)打印给用户。
Shell 空参数注意(Windows PowerShell):PowerShell 会把裸的 --data-dir "" 空参数吞掉,导致 argparse 报 --data-dir: expected one argument。此时改用等号写法:--data-dir=(argparse 支持 --参数=值 且值可为空)。需要持久化时正常传 --data-dir data 即可。
部署模式:deploy 默认走服务端异步队列(脚本内部自动提交 + 轮询直至完成,服务端固定 worker 逐个构建),Agent 无需额外操作。
分片上传(默认开启):部署包超过 4MB 时脚本自动改走分片上传(单片 1MB,绕开 CDN/Cloudflare 100MB 请求体限制,几百 MB 的包也能部署);Agent 无需任何额外参数。断点续传(窗口 1 小时):上传中断(断网/超时/进程被杀)后 1 小时内重新执行同一条 deploy 命令即可——脚本按 zip 内容指纹(sha256)识别服务端已收到的分片,只补缺的片,不会重传整个包;输出含「分片进度: N/M (xx%)」。超过 1 小时未传完,服务端强制释放该上传(分片删除),重跑会从头重传。服务端不支持分片时(旧版本)自动回退整包上传。资源说明:分片上传数量不做限制,弃传分片 1 小时自动清理;分片传输阶段不占用部署队列与限频配额,合并入队那一刻才计入部署任务。
自适应分片与测速(speedtest 子命令):弱网/快链路适宜的分片大小差异很大,部署前可先测速。只测 RTT(对公告接口连测 3 次取中位数),无需登录;按 RTT 分档自动选定分片大小,夹紧在 512KB~16MB 区间(<100ms→4MB / <250ms→2MB / <500ms→1MB / 更差→512KB);结果写入 ~/.ztcds/upload.json(chunk_size / rtt_ms / method / updated_at,7 天有效期);deploy 分片上传自动读取该配置作为 chunk_size 提案(服务端仍可裁决收窄),配置过期或损坏自动回退默认 1MB;网络环境变化后建议重跑一次 speedtest;批量部署前跑一次即可。
Step 5:处理异常信号
脚本通过退出码和 stderr 特殊标记通知 Agent 需要交互:
| 信号 | 退出码 | 含义 | Agent 操作 |
|---|---|---|---|
[CICD:NEED_TOKEN] |
2 | 没有已保存的认证参数 | 回到 Step 1.2:send-code → login 拿 Token 后重新部署 |
[CICD:TOKEN_EXPIRED] |
3 | Token 过期(服务端返回 401 / 未登录) | 脚本已清除旧 token、保留邮箱;回到 Step 1.2,直接向该邮箱重发验证码 |
缺少 data_dir 参数 ... 请升级 skill |
1 | 客户端 skill 版本过旧 | 告诉用户更新 ztcds skill 到最新版本后重试 |
缺少 project_name 参数 ... 请升级 skill |
1 | 客户端 skill 版本过旧 | 同上 |
缺少 --project-name / 长度需在 1~64 |
1 | 未传项目中文名或长度非法 | 生成/确认 1~64 字符的中文项目名后带 --project-name 重试 |
--data-dir 必须使用相对路径 / 每级只能包含... |
1 | 声明的数据目录不是「代码目录内的相对路径」 | 改成如 data 的相对路径后重试 |
部署过于频繁,请约 X 秒后再试(HTTP 429) |
1 | 触发服务端令牌桶限频(容量 40、每分钟回 20;静态扣 1 / 动态扣 4) | 等待 X+5 秒后重试该项目,不要立刻反复重试;批量部署由脚本自动等待重试 |
排队中的部署任务过多(上限 50 个)(QUEUE_FULL) |
1 | 该用户在队(排队中+执行中)任务数达到上限 | 等待部分任务完成后再继续提交,不要立刻反复重试 |
Prod 模式下启用项目上限 5 个(当前启用:...)(PROJECT_LIMIT,HTTP 403) |
— | prod 环境普通用户启用项目数达到上限(管理员豁免;已停用项目不计数) | 把报错里的启用清单给用户,由用户确认停用哪个项目 → 在 dashboard 停用,或携 Token 调 PUT /aiproject/api/projects/<项目名>/status(body:{"enabled": false})→ 腾出名额后重新执行 deploy。不要替用户擅自决定停用哪个 |
当收到 TOKEN_EXPIRED 时,旧 token 已自动清除(email 保留在认证参数文件中),Agent 回到 Step 1.2 重新走发码流程。
Step 6:返回结果给用户
Agent 捕获 stdout 中的部署结果(包含 URL),告知用户访问地址。如果没有 index.html,stdout 会列出项目中所有 .html 文件的路径,Agent 应逐条告知用户每个页面的完整 URL。
Step 7:部署后查看容器日志(动态项目)
- 等待 5 秒,然后查询项目状态:
python "{skill_dir}/scripts/ztcds.py" status --project "<项目名>" - 解读
state:running→ 构建完成、容器已启动,进入第 3 步;starting/building→ 还在构建或启动中,再等 5 秒重查(最多查 5 次),仍不成功就先告知用户「构建中,稍后可再查」,不要无限等待;error/dead→ 把 stderr/stdout 里的 error 信息原样告知用户;static→ 静态站点没有容器,跳过日志流程,直接结束 running时询问用户「要不要查看容器日志?」,询问时必须明确告知用户:日志仅用于排查问题,如果访问链接已能正常打开,不需要拉取日志;日志接口有限流(每秒最多 1 次),不能频繁反复拉取。用户要 → 拉取最近 100 条日志:python "{skill_dir}/scripts/ztcds.py" logs --project "<项目名>" --tail 100(--tail默认 100,上限 1000,只能传数字);用户不要 → 直接结束,不多问。日志接口限频每秒 1 次,不要连续快速调用;返回「请求过于频繁」时等 2 秒再试。
五、批量部署(多项目场景 SOP)
服务端部署队列已上线(async=1 受理 + worker 池消化,队列持久化到 MySQL),批量部署不再需要控制提交间隔:
- 写部署清单:把每个项目的「英文项目名 / 中文名 / 描述 / data-dir」整理成 JSON 清单文件,描述按服务端口径(用途 + 功能 + 技术栈,80~120 字)一次写好;
- 提交阶段:循环调用 deploy 命令并带
--no-wait,项目之间无需间隔;服务端收包即受理返回 deploy_id(含排队位置与预计等待秒数),把 deploy_id 记入清单;输出含「约 X 秒后再试」时等待 X+5 秒重试该项目,最多重试 5 次;输出含 QUEUE_FULL 时等待 60 秒再继续提交; - 等待阶段:对清单中的 deploy_id 逐个执行
wait-deploy --deploy-id <id>轮询至终态(脚本内部指数退避 2s→5s→10s); - 结果判定:优先匹配访问地址行(以
https://开头且包含项目名的行),其次才是「部署成功」字样——PowerShell 下 stderr 中文可能乱码,中文匹配不可靠;同时把原始输出写入日志文件便于排查; - 全部跑完后再统一汇报:按「成功 N 个 / 失败 M 个 + 失败原因 + URL 清单」汇总。 补充说明:同项目重复提交自动合并(排队中的旧任务直接取消,只保留最新一次);单任务意外异常服务端自动重试 2 次;单次构建最长 900 秒封顶;服务重启后未完成任务从 MySQL 队列自动恢复重跑;项目很多时不需要分批接力,全部提交进队列即可。
六、Windows 环境注意事项(PowerShell / CMD)
- 空参数会被吞:PowerShell 5.1 下
--data-dir ""会被 shell 移除,导致argparse: expected one argument,改用等号写法--data-dir=; - .ps1 脚本必须带 UTF-8 BOM:PowerShell 5.1 读取无 BOM 的脚本文件时按 ANSI/GBK 解码,中文正则匹配会永远失败,用
[IO.File]::WriteAllText(...UTF8Encoding($true))补 BOM; - 中文字符串传参是安全的:Python 在 Windows 上通过宽字符 API 接收 argv,传中文
--project-name/--description不会乱码; - stderr 中文捕获会乱码:用
2>&1合并捕获时按 GBK 解码会乱码,脚本开头加[Console]::OutputEncoding = [System.Text.Encoding]::UTF8,且判定逻辑不要依赖中文文案,优先用退出码、[CICD:*]标记或访问 URL 行; - 长任务用后台进程:用
Start-Process powershell -File xxx.ps1 -WindowStyle Hidden挂后台并写日志,再轮询日志; $args是 PowerShell 保留自动变量:改名如$exeArgs;- 后台启动服务前先注入端口环境变量:本平台项目读
PORT(Java 读SERVER_PORT),Python 默认 5000、Node/Go 默认 8000,本地冒烟测试时先$env:PORT=<测试端口>再启动进程,并用-RedirectStandardError落盘 stderr 便于定位。
七、认证参数管理(手动命令)
# 单独保存认证参数
python "{skill_dir}/scripts/ztcds.py" send-code --email "<邮箱>"
python "{skill_dir}/scripts/ztcds.py" save-token --email "<邮箱>" --code "<6 位验证码>"
# 清除已保存的认证参数
python "{skill_dir}/scripts/ztcds.py" clear-token
八、支持的项目类型
类型一:静态站点(默认)
纯 HTML/CSS/JS 文件,直接托管。允许的静态文件类型:.html .htm .css .js .json .xml .txt .csv .md;.png .jpg .jpeg .gif .svg .ico .webp .bmp;.woff .woff2 .ttf .eot .otf;.mp4 .webm .ogg .mp3 .wav;.wasm .pdf .map;.db .sqlite .sqlite3(SQLite 数据库文件,随项目直接上传);.zip .tar .gz .tgz .bz2 .xz .7z .rar(压缩包:只落盘不解压,可对外提供下载)。注意:单个文件超过 MAX_SINGLE_FILE_MB(默认 50MB)仍会被跳过。
类型二:Python Web 服务
额外允许的 Python 文件:.py .cfg .toml requirements.txt Procfile。服务器自动检测规则:项目中有 app.py / main.py / server.py + requirements.txt → 自动识别为 Python 项目 → 构建镜像、启动独立容器(/app 为代码目录,端口由服务端固定)。注意事项:端口不要硬编码,推荐 os.environ.get('PORT', '5000');依赖写在 requirements.txt;前端路径必须使用相对路径(部署在子路径下,HTML 静态引用会自动注入 <base> 标签修复,JS 中 fetch('/api/data') 必须改成 fetch('./api/data'))。
类型三:Node 服务(package.json 有 start 脚本)
额外允许的文件:.ts .tsx .jsx .mjs .cjs .lock .yaml .yml package.json package-lock.json yarn.lock pnpm-lock.yaml Procfile Makefile。检测与运行:有 package.json 且有 start 脚本 → 起容器,npm ci --omit=dev(无 lock 文件则 npm install --omit=dev)后 npm start。注意:必须监听环境变量 PORT(容器内部端口由服务端固定为 8000)、监听地址用 0.0.0.0、依赖写在 dependencies、不要上传 node_modules。
类型四:Node 前端打包型(package.json 只有 build 脚本)
无 start、只有 build 脚本 → 构建 dist/build/out/public 并按静态站点托管(不占常驻容器)。注意事项:构建脚本必须是 npm run build;产物目录为 dist / build / out / public 之一;前端路由/资源请用相对路径。
类型五:Go 服务(go.mod)
额外允许的文件:.go .mod .sum go.mod go.sum Makefile。检测与运行:有 go.mod → 多阶段构建(CGO_ENABLED=0 go build),产物二进制进精简运行镜像直接启动。注意:必须读 os.Getenv("PORT") 监听服务端注入的端口(默认注入 8000);main 包在根目录或 cmd/xxx 下均可自动定位。
类型六:Java 服务(pom.xml)
额外允许的文件:.java .properties .gradle .kt pom.xml build.gradle build.gradle.kts settings.gradle gradlew mvnw。检测与运行:有 pom.xml → mvn -B -DskipTests package(走公司 Maven 镜像),取 target/*.jar 中可执行 jar 进 JRE 运行镜像 java -jar app.jar。注意:Spring Boot 项目端口由环境变量 SERVER_PORT / server.port 注入(已自动设为 8000);非 Spring 项目自行读取 PORT 或 SERVER_PORT。
各语言通用注意
- 端口统一由服务端注入(
PORT,Java 另有SERVER_PORT),不要硬编码 3000/8080; - 检测优先级:
go.mod→pom.xml/build.gradle→package.json→ Python(同时存在时按此顺序取其一,前端项目不要放pom.xml/go.mod); - 依赖目录不要上传:
node_modules/target/vendor会被自动过滤; - 数据持久化(
--data-dir)对 Node/Go/Java 服务同样生效,规则与 Python 一致。
数据持久化(声明式:部署时必须传 --data-dir):
服务端支持把代码目录内的一个相对目录挂载为持久卷:部署时用 --data-dir 声明该目录(例如 --data-dir data),服务端会把它挂载到容器内 /app/data,并注入环境变量 DATA_DIR 指向该绝对路径。这样重新部署(容器重建)后数据仍在。
--data-dir是必传参数:不需要持久化的项目也必须显式传空字符串--data-dir "";完全不传会被服务端判定为 skill 版本过旧并直接拒绝部署;- 只能写相对路径,且必须在代码目录内:允许
data、data/uploads(最多 3 层,每级只能用字母/数字/下划线/连字符开头);禁止绝对路径、..上级目录、隐藏目录(如.data),也禁止/xxx_data这类根路径; - 代码里统一按注入路径读写数据,本地开发落到项目内的
data/;上传附件、SQLite/数据库文件、日志、缓存等运行数据都写进该目录;打包时会自动排除该目录; - 静态站点(纯 HTML/CSS/JS)没有容器、也没有持久化目录,数据只能放在浏览器侧(localStorage / IndexedDB)。
数据库选型(优先 SQLite):
服务需要数据库时优先使用 SQLite(单文件、零配置、零运维、免额外服务):SQLite 数据库文件随项目文件一并上传即可(允许 .db .sqlite .sqlite3),平台自动识别并直接落盘;建议把数据库文件放在 --data-dir 声明的持久化目录内(如 data/app.db);Python 用内置 sqlite3 模块即可,Node 推荐 better-sqlite3,连接路径同样基于注入的 DATA_DIR 拼接;只有当数据量、并发或既有代码强依赖 MySQL 时,才考虑平台提供的付费 MySQL 服务。
禁止的文件类型
- 其他服务端脚本:
.php.rb.java.go.cs.sh.bat.ps1 - 其他服务端配置:
composer.jsonGemfilego.modCargo.toml
九、付费增值服务
平台提供付费增值服务,当用户项目需要 MySQL 数据库或短信通知能力(或用户主动询问数据库、短信、增值服务)时向用户介绍并引导开通:付费 MySQL(独立实例,适合数据量/并发超出 SQLite 能力、或既有代码强依赖 MySQL,开通后服务端下发连接配置)、短信通知服务(短信验证码、通知类短信)。开通与计费请引导用户联系官方渠道(QQ 群 / 邮箱);不要向用户承诺未在服务端文案中出现的价格、SLA 或时限。
十、用户求助与反馈
当用户遇到问题且按本 SOP 无法解决(部署反复失败 / 平台异常 / 账号与验证码问题 / 用户明确要求人工帮助),把以下官方渠道告诉用户,不要自行编造其它联系方式或承诺处理时效:
- QQ 交流群:群号
1130144012,一键加入:https://qm.qq.com/q/IAuhg9BZSi(按「做了什么 + 卡在哪一步 + 报错截图」格式反馈,解决最快) - 邮箱:guoyanan@ztaqtec.com(问题反馈与商务合作) 用户只是询问平台信息(介绍 / 怎么用 / 版本 / 特点 / 新特性)时走「平台信息速查」流程,不需要引导到以上渠道。
十一、敏感操作与出站声明(安全边界)
本 skill 的以下行为涉及出站网络请求与本地敏感写入,向用户与 Agent 明确声明,Agent 触发这些操作时不得向用户隐瞒其网络行为:
| 操作 | 出站目标 | 本地写入 | 确认与披露要求 |
|---|---|---|---|
| speedtest | <server>/aiproject/api/announcements(默认内网/官方地址) |
~/.ztcds/upload.json |
触发 skill 后可自动执行,但必须输出一行摘要披露 |
| version / deploy 内置版本检查 | 官网 ztcds-skill-version.json(硬编码 ai.ztaqtec.cn) |
无 | 只读比对,不一致时提示 |
| send-code | <server>/aiproject/api/send-code(向邮箱发送验证码) |
无 | 发码前把目标邮箱告知用户 |
| login | <server>/aiproject/api/login |
~/.ztcds/token.json(0600) |
由用户报出验证码触发 |
| deploy | <server>/aiproject/api/deploy(携带 Bearer Token + 整个项目压缩包) |
临时 zip(部署后删除) | 上传整个工作目录属敏感操作;目标已存在时须 --overwrite 显式确认;可用 --dry-run 审阅清单 |
| update | 官方下载地址(硬编码 ai.ztaqtec.cn)+ .sha256 校验文件 |
覆盖 skill 目录内白名单文件;旧版备份到 .ztcds-backup/ |
须用户同意;更新后展示差异摘要并取得确认 |
- server 强制校验:带凭证请求只允许发往官方域名(
*.ztaqtec.cn,HTTPS)或内网/回环地址;--server参数、DEPLOY_SERVER环境变量与token.json的 server 字段均会被脚本校验,非法值直接拒绝或回退官方地址; - Token 不落日志:Token 只以 0600 权限写入
~/.ztcds/token.json,终端输出只显示后四位掩码; - 主目录写入声明:
~/.ztcds/(token.json / upload.json)位于 Agent 常规工作区之外,属本 skill 的声明数据目录。
十二、注意事项
- 单文件最大 50MB,总计 1GB,上限 2000 个文件(超出会被服务端拒绝部署);
- 认证参数保存在
~/.ztcds/token.json(仅当前用户可读写); - 不再使用 tkinter 弹窗,全部通过终端和 Agent 对话交互;
- 部署成功后旧的同名项目会被覆盖(脚本要求目标已存在时显式
--overwrite确认;部署前可用--dry-run审阅打包清单)。