@adep/cli
v0.1.1
Published
`adep` 命令行工具包位:登录 / 初始化 / 本地调试 / 部署 / 数据库维护 / 云存储 / 静态托管 / 微前端组件(widget),实现见任务单 CLI-001 ~ CLI-003 与 FE-002;子路径 `@adep/cli/vite` 提供云函数 vite 插件(CLI-014)
Readme
adep — AgentDeploy CLI
面向终端开发者的 AgentDeploy 命令行工具:登录 / 初始化 / 本地调试 / 部署 / 数据库维护 / 云存储 / 静态托管 / 全栈工程(functions/ + web/ 前端) 一站式闭环。
adep 让你在一个项目目录里完成从脚手架 → 本地调试 → 部署上线 → 数据与资源运维的完整流程。它复用平台运行时内核(@adep/runtime),本地与线上的执行语义一致,离线、不装 Docker 也能开发。
目录
安装
# 通过 npm 全局安装
npm install -g @adep/cli
# 或使用 bun
bun add -g @adep/cli
# 发布前本地调试:从仓库根目录
bun run packages/cli/src/index.ts --help要求:Node ≥ 22.19,或 Bun ≥ 1.3(Bun 可免编译直接运行 TS,推荐用于本地开发)。 安装后运行
adep --help查看全部可用命令。
快速开始
# 1. 登录平台(凭据保存在 ~/.adep/credentials,权限 0600)
adep login
# 或指定平台与邮箱:adep login -s https://platform.example.com -e [email protected]
# 2. 初始化一个函数项目
adep init my-app --template function
# 3. 进入项目,本地调试(监听 functions/,支持热重载)
cd my-app
adep dev
# → http://127.0.0.1:8787/hello
# 4. 部署上线(全栈:函数 + 前端)
adep publish三步即可把本地 functions/hello.ts 与 web/ 前端发到线上并得到公网访问地址。
只发布函数:adep publish --only functions;只发布前端:adep publish --only frontend。
子命令
所有子命令都支持全局 --json 标志,以机器可读的 JSON 信封输出(适合 Agent / 脚本调用):
adep --json whoami
# → {"ok":true,"command":"whoami","data":{"email":"...","server":"..."}}失败时返回退出码 1 + {"ok":false,"command":"...","error":{"code":"...","message":"..."}}。
adep init
初始化项目(脚手架)。默认 fullstack 模板:生成与 Web IDE 项目同一结构的全栈骨架
(functions/ 云函数 + web/ 标准 Vite 前端工程 + database/schema.sql):
| 模板 | 说明 |
| ----------- | ------------------------------------------------------------------------------ |
| fullstack | 全栈骨架:functions/ + web/(Vite + Vue 3)+ database/schema.sql(默认) |
| function | 仅云函数:单个示例函数 functions/hello.ts |
| empty | 仅项目骨架(adep.config.ts + 类型提示入口,不生成示例产物) |
adep init my-app # 默认 fullstack 模板(与 Web IDE 项目同构)
adep init my-app -t function # 仅云函数
adep init my-app -t empty # 空模板
adep init --list # 从平台 GET /api/v1/templates 列出可用模板
adep init --list -s https://platform.example.com产物结构(fullstack 模板,CLI-014:vite 工程根在项目根目录):
my-app/
├── package.json # 应用定义:@adep/cli + 前端依赖同根声明 + scripts(dev/build/site:deploy/serve/deploy/doctor)+ engines
├── vite.config.ts # vite 配置:vue 插件 + adep() 云函数插件;build.outDir = site/
├── index.html # vite 入口(引用 /web/src/main.ts)
├── adep.config.ts # 项目配置:name / template / functionsDir / functions_prefix(默认 /api)
├── tsconfig.json # 云函数 TypeScript 编辑器配置(strict + noEmit)
├── adep.d.ts # 云函数上下文环境类型声明(ctx: AdepContext 补全)
├── functions/
│ ├── hello.ts # 示例函数(deploy 后经 /api/hello 触发)
│ └── README.md
├── web/src/ # 前端源码(Vue 3;与 Web IDE 的 web/ 工程共用同一份 src/)
│ ├── main.ts
│ └── App.vue
├── site/ # vite build 构建产物(站点托管目录,adep hosting deploy site 上传;已 gitignore)
├── database/
│ └── schema.sql # 数据库结构(占位;表由平台控制台 / adep db 管理)
├── README.md
└── .gitignore # 已忽略 node_modules/ data/ .adep/ site/根 package.json:与导出的离线部署包(adep export / 平台自托管导出)的应用定义同构——
声明 @adep/cli 版本依赖(值来自 CLI 自身发布版本,不硬编码)与常用 scripts:
pnpm dev(= vite,全栈开发:前端 HMR + 云函数代理)/ pnpm build(= vite build → site/)/
pnpm site:deploy(= adep hosting deploy site --spa)/ pnpm serve / pnpm deploy / pnpm doctor。
全栈开发(vite + 云函数代理):pnpm dev 启动 vite 后,@adep/cli/vite 插件在 vite 进程内
启动 adep dev(模拟运行时,函数热重载 / .env.local / cloud.* 全可用),并把
/{functions_prefix}/* 请求代理到云函数——默认前缀 /api(与线上函数路由对齐),
前端 fetch('/api/hello') 即调用 functions/hello.ts。
functions_prefix(云函数路由前缀):adep.config.ts 的 functions_prefix(默认 /api):
adep dev访问路径/{prefix}/{fnName}(如/api/hello);vite 插件按同一前缀代理。adep serve为/api/{prefix}/{fnName}(前缀拼接在/api/之后)。- 留空(旧项目):
adep dev为/{fnName},adep serve为/api/{fnName}; vite 插件在配置为空时强制/api并同步覆盖 dev 路由,保证代理与路由一致。 - 边界:只影响本地 HTTP 入口路由;函数互调
ctx.cloud.invoke('name')与线上部署路径 按函数名,不随前缀变化(与线上同构)。
前端源码(web/src/):与 Web IDE 内 web/ 工程的 src/ 完全同构(同一份模板真相源);
vite 工程根在项目根目录(vite.config.ts / index.html / 根 package.json),构建产物输出到
site/(站点托管目录),pnpm site:deploy 上传部署。
类型提示:adep init 产出的项目自带 tsconfig.json 与 adep.d.ts,用 VSCode 打开即可在
functions/ 下获得 AdepContext / ctx.cloud.* 补全,无需本机安装 @adep/types。
函数签名写 export default async (ctx: AdepContext) => {...} 即可。
目录已存在时会拒绝覆盖(fail loud),不会静默改写你的代码。
adep dev
本地调试:监听 functions/(以及 .env.local / adep.config.ts)变化并热重载,默认监听 http://127.0.0.1:8787/<fnName>,冷启动 ≤ 1.5s,文件变更到可被调用 ≤ 300ms。
adep dev # 默认端口 8787
adep dev -p 3000 # 指定端口模拟运行时:默认使用进程内模拟运行时(
@adep/runtime+ 本地模拟器),不连云端、不装 Docker、断网也能开发——只替换传输与持久化,不改写函数语义。能力注入:自动装配
cloud.db/cloud.storage/cloud.realtime,语义与线上一致。环境变量:读取
.env.local/.env的键值,注入执行沙箱(process.env[KEY])。能力边界:启动时打印一行边界清单(如下),提示本地与线上的差异:
定时/事件触发器只登记,本地以手工 HTTP 调用替代;
realtime 为单进程内存广播,线上多实例语义不同;
本地不执行计量 / 配额门禁,不计费。
[adep] dev server listening on http://127.0.0.1:8787(Ctrl-C 退出)
[adep] curl 示例:curl http://127.0.0.1:8787/hello
...adep serve
开发态服务器:把函数(/api/{fn})、/healthz、静态托管与组件预览合并到一个进程里常驻,默认只绑回环地址,是本地开发服务器而非生产服务器。自托管部署包内用它指向包内 web/ 站点。
adep serve # 默认 127.0.0.1:8787(PORT / HOST 环境变量可覆盖)
adep serve -p 9000 # 指定端口
adep serve --static web # 指定静态托管目录(缺省 public/)缺省值优先级为「命令行旗标 > 环境变量(
PORT/HOST/ADEP_SERVE_STATIC_DIR)> 内置缺省」,容器编排注入的PORT/HOST不会被命令行缺省盖掉。绑定非回环地址时给出对外暴露警告(它不带生产级加固)。
adep publish
全栈发布顶层命令(CLI-010):函数部署 + 前端构建托管一把梭。
adep publish # 缺省全栈:函数 deploy + 前端平台侧构建托管
adep publish --only functions # 只发布云函数
adep publish --only frontend # 只触发平台侧前端构建(FN-024)并切换站点版本
adep publish -p my-app # 显式指定目标 slug函数部分:扫描本地
functions/计算内容哈希 → 调平台/api/v1/deploy/diff拿差异清单 → 仅上传变更函数 → 发布 → 输出访问域名(与adep deploy同一管线)。前端部分:调平台
POST /api/v1/projects/:id/frontend/publish(服务端真实构建web/草稿), 再读/frontend/versions取当前版本与siteUrl。未登录由createClient统一抛NOT_LOGGED_IN。成功输出每个函数的名字 / 版本 / 访问地址,末尾汇总函数部署数 + 前端构建状态 + 站点 URL:
hello v1 https://my-app.platform.example.com/api/hello
✓ 1 functions deployed in 3.2s
✓ frontend built v2 · https://my-app.platform.example.com--json输出统一信封{ ok, command, data: { scope, functions?, frontend? } }。
兼容别名:
adep deploy/adep functions deploy/adep hosting deploy保留原行为, 仅在 stderr 打印 deprecation 提示指向本命令(见下文)。
adep deploy(deprecated)
已废弃:推荐使用
adep publish(全栈)或adep publish --only functions(仅函数)。 本命令保留向后兼容,运行时在 stderr 打印迁移提示。
增量部署:扫描本地 functions/ 计算内容哈希 → 调平台 /api/v1/deploy/diff 拿差异清单 → 仅上传变更函数 → 发布 → 输出访问域名。
adep deploy # 项目 slug 取 adep.config.ts 的 name
adep deploy -p my-app # 显式指定目标 slug本地
functions/<name>.ts对应平台函数<name>(入口文件固定为index.ts)。幂等:内容与已发布版本一致时输出
no changes,不产生新版本。成功输出每个函数的名字 / 版本 / 访问地址,末尾给一行汇总:
hello v1 https://my-app.platform.example.com/hello
✓ 1 functions deployed in 3.2s汇总只在真的产生新版本时写
deployed;全部复用时写✓ no changes · N functions up to date in Ts,不把幂等说成重新发布。
adep projects
项目子命令组:创建 / 列出 / 查看。子域地址由平台回显(projectBaseUrl),CLI 不自行拼域名。
adep projects create game-arcade # → ✓ Project created · https://game-arcade.adep.top
adep projects create game-arcade -n 游戏厅 # 展示名与 slug 分开
adep projects list # slug \t name \t url
adep projects info game-arcade # id \t slug \t name \t url--name缺省取 slug:一行命令即可建项目。目标 slug 已占用 → 平台返回
PROJECT_SLUG_TAKEN,CLI 原样透传并退出码 1。未登录 / 会话失效 → 打印错误后附带
提示:先执行 adep login。
adep functions(deprecated)
functions deploy已废弃:推荐使用adep publish --only functions(或adep publish --only functions -- <dir>等价语义)。functions list/functions logs保留不变。
云函数子命令组:部署(可指定目录)/ 列出 / 查日志。
adep functions deploy ./handlers # 覆盖 adep.config.ts 的 functionsDir(deprecated)
adep functions deploy # 等价于 adep deploy(deprecated)
adep functions list -p my-app # name \t 访问地址
adep functions logs hello -p my-app --tail 50deploy与adep deploy共用同一执行体,输出逐字一致(两个入口各写一遍迟早只有一处有汇总行)。日志缓冲在平台进程内(环形),未执行过的函数为空——命令会如实说明而非报错。
adep mcp
MCP Tool 子命令组:把云函数发布为项目 MCP Tool / 取消发布 / 列出。发布后外部 Agent 即可通过项目 /mcp 端点调用你的后端能力(只消费平台既有的 POST|DELETE /api/v1/functions/:id/mcp-publish 与 tools/list,CLI 不重实现发布逻辑)。
adep mcp publish --function stock # → ✓ MCP tool published · stock
adep mcp publish --function stock --name get-stock # 以别名注册(tools/list 里出现 get-stock)
adep mcp publish --function query-database --description "查询库存" # 覆盖面向 Agent 的描述
adep mcp unpublish --function stock # 取消发布(别名发布过则加 --name get-stock)
adep mcp list # 打印端点地址 + 已发布 tool(name \t description)--function是函数名,--name是可选的注册 Tool 名(缺省取函数名);目标项目缺省取adep.config.ts的name,也可用-p <slug>指定。服务端错误原样透出:函数入参无法映射为 JSON Schema 时返回
MCP_SCHEMA_UNSERIALIZABLE并以退出码 1 结束(CLI 不改写、不兜底,原因由服务端指出)。mcp list读的是项目/mcp端点的tools/list(与外部 Agent 同一条路径):项目 MCP 鉴权模式为public时可直接读取;为api-key时未带 Key 会返回MCP_UNAUTHORIZED。unpublish默认按函数名移除;若曾以别名发布,需加--name <tool>指向该别名。取消一个不存在的工具会如实说明、不报成功也不报错。
adep doctor
环境自检:凭据状态、平台可达性、离线可用范围与本地模拟运行时的能力边界。
adep doctor
adep doctor --json # { server, credentials, network, serverHealth, offlineCommands, boundaries }已登录时体检的是凭据里记录的那个平台(
login --server可指到任意环境),未登录才回退ADEP_SERVER缺省。平台可达性 = 对
GET /api/v1/health的一次真实探测;拿到任何 HTTP 应答都算可达。凭据文件权限宽于
0600会给告警;命令本身不因体检结论失败(它是诊断,不是门)。
adep db
项目数据库维护子命令组:启动 / 状态 / 停止 / SQL 执行 / 快照 / 时间点回滚。项目参数缺省取 adep.config.ts 的 name(也可用 -p 显式指定)。
adep db start # 启动项目数据库(已存在则重新激活,不重建数据)
adep db status # 查询状态与用量(体积 / 表数 / 行数)
adep db stop # 停止数据库(连接关闭并标记;文件保留)
# 执行单条 SQL;写 / 破坏性语句需 --confirm-table 二次确认目标表名
adep db exec --sql "SELECT * FROM users"
adep db exec --sql "DELETE FROM users WHERE id = 1" --confirm-table users
# 快照(付费档位):列出 / 创建 / 还原
adep db snapshot list
adep db snapshot create
adep db snapshot restore <snapshotId>
# 时间点回滚(团队版,基于变更流重放)
adep db rollback --to 2026-01-01T00:00:00.000Zdb exec 人读模式下返回对齐文本表(结果行截断时会提示),--json 输出结构化结果。
adep storage
云存储 / 文件存储子命令组:上传 / 下载 / 列表 / 删除。
adep storage upload ./avatar.png --path avatars/a.png # 缺省 private(签名访问)
adep storage upload ./banner.png --path site/banner.png --visibility public # public 直连
adep storage download avatars/a.png [-o 本地输出路径] # 自动解析签名 / 直连 URL 落盘
adep storage ls [--prefix site/] # 按前缀列出(附访问 URL)
adep storage rm avatars/a.png上传:multipart,单文件 ≤ 50MB;
path为桶内相对路径,visibility决定 public 直连或 private 签名。下载:先列表解析出服务端生成的 URL(public 直连 / private 15 分钟签名),再取回内容——private 文件无需 CLI 自行签发签名。
所有命令都支持
-p <slug>指定项目。
adep hosting(deprecated)
hosting deploy已废弃:推荐使用adep publish --only frontend(平台侧构建web/草稿)。 如确需上传预构建目录(如本地vite build产物),hosting deploy <dir>仍可用,仅 stderr 提示迁移。hosting info/pull/config保留(运维类操作不并入 publish)。
静态托管子命令组:查看 / 部署 / 拉取 / 配置。站点文件即项目桶 site/ 前缀下的 public 文件。
adep hosting info # 查看托管配置、站点地址与文件树
adep hosting deploy ./dist # 递归上传目录到 site/ 并打开托管(deprecated)
adep hosting deploy ./dist --spa # 同时启用 SPA 回退(deprecated)
adep hosting pull [-o ./site] # 拉取站点公开文件到本地(跳过 private 托管配置)
adep hosting config --enabled true --spa true # 更新托管开关 / SPA 回退(幂等)deploy:把本地目录递归上传为
site/<rel>(public)→ 打开托管开关 → 输出站点地址。pull:只拉公开站点文件,private 侧载的托管配置(
site/.hosting.json)不会进站点目录。
adep export
导出自托管部署包:触发平台长任务 → 轮询进度 → 下载 zip → 按 manifest 逐项自检,产出一个「解压即可运行」的可部署包(含应用定义、adep.config.ts、Docker 产物与静态站点)。
adep export # 目标项目取 adep.config.ts 的 name
adep export -p my-app --with-data # 显式指定项目并包含数据库行数据(缺省仅 schema)
adep export --out ./dist-export # 指定输出目录(缺省 ./exports)--with-data附带行数据,--with-source附带函数源码(平台缺省已含,显式给出不改变默认)。--json输出单个结果信封;导出失败(长任务未产出 / 自检不过)以退出码 1 +EXPORT_FAILED结束,不静默给半截产物。
配置
环境变量
| 变量 | 说明 | 缺省 |
| ------------- | --------------------------------- | ----------------------- |
| ADEP_SERVER | 平台地址(CLI 请求的默认 server) | http://localhost:3000 |
| ADEP_HOME | 凭据目录(测试隔离用) | ~/.adep |
export ADEP_SERVER=https://platform.example.com
export ADEP_HOME=~/.adep也可通过
-s/-e/-p等子命令参数覆盖。
adep.config.ts
adep init 生成的项目配置文件,CLI 的 dev / serve / deploy 按此识别项目(CLI 直接 import 后读 default 的字段,无需任何辅助包):
// adep 项目配置:CLI(dev / serve / deploy)与云函数 vite 插件按 default export 读取。
export default {
name: 'my-app', // 项目名(deploy 的默认 slug)
template: 'fullstack', // 模板:empty | function | fullstack
functionsDir: 'functions', // 云函数目录
functions_prefix: '/api', // 云函数路由前缀(默认 /api,与线上 /api/{fn} 对齐)
}functionsDir:云函数目录(dev/serve/deploy读取,缺省functions/)。functions_prefix:影响本地路由与 vite 插件代理前缀(见上方adep init产物结构说明)—— 默认/api:adep dev访问/{prefix}/{fnName}、adep serve访问/api/{prefix}/{fnName}、 vite 插件按/{prefix}/*代理;函数互调与线上部署路径不随前缀变化。
常用示例
# 登录后查看当前身份
adep whoami
# 登出并清除本地凭据
adep logout
# 列出平台可用的脚手架模板
adep init --list
# 数据库运维:启动 → 看状态 → 跑 SQL → 打快照
adep db start
adep db status
adep db exec --sql "SELECT count(*) FROM users"
adep db snapshot create
# 云存储:上传 / 下载 / 删除
adep storage upload ./logo.png --path assets/logo.png --visibility public
adep storage download assets/logo.png -o ./logo.png
# 静态托管:本地构建产物一键上线,随时拉回
adep hosting deploy ./dist # deprecated:推荐 adep publish --only frontend
adep hosting pull -o ./site
# 以 JSON 输出(Agent / CI 可用)
adep --json publish -p my-appFAQ
Q:adep login 失败提示 NOT_LOGGED_IN / SERVER_UNREACHABLE?
先确认 ADEP_SERVER(或 -s)指向可访问的平台地址,再重新 adep login。凭据保存在 ~/.adep/credentials(权限 0600)。
Q:adep dev 需要 Docker / 云连接吗?
不需要。默认使用进程内模拟运行时(@adep/runtime),断网也能开发——只替换传输与持久化,不改变函数语义。
Q:本地开发与线上行为会不一致吗?
模拟器刻意保持执行语义一致:cloud.db / cloud.storage / cloud.realtime 能力装配复用线上逻辑。差异点仅限传输层与持久化层,且 adep dev 启动时会打印边界清单(触发器不自动执行、无跨实例广播、不在本地计量计费)。
Q:adep deploy 显示 no changes?
这是幂等设计:本地函数内容与已发布版本一致时复用当前版本,不产生新版本。想强制更新需修改函数内容。
Q:项目名的命名规则?
init 项目名:小写字母开头,仅含小写字母 / 数字 / 连字符(≤ 63 字符)。
Q:adep db exec 的 --confirm-table 是做什么的?
写 / 破坏性语句(DELETE / DROP / ALTER…)服务端要求二次确认目标表名,--confirm-table users 即输入目标表名以放行;只读查询无需该参数。
Q:adep storage / adep hosting 需要在平台项目目录里跑吗?
不需要。它们通过 -p <slug> 指定目标项目,缺省才读取 adep.config.ts 的 name——在任何目录下都能对指定项目做资源运维。
Q:private 文件如何下载?
adep storage download 会自动调用平台列表接口拿到服务端生成的 15 分钟签名 URL 再取回内容,无需 CLI 自行签发签名;公网访问同样走该 URL。
Q:--json 输出长什么样?
每个命令输出一个 JSON 对象:成功 {"ok":true,"command":"...","data":{...}},预期内失败 {"ok":false,"command":"...","error":{"code":"...","message":"..."}} 且退出码为 1。
相关
@adep/runtime—— 平台运行时内核(执行器 + 本地模拟运行时 + 能力装配),adep dev复用其保证本地/线上语义一致。
