爱笑的毛毛虫 7ec51732f7 feat(editor): AI 编辑助手悬浮面板、插件权限体系与时间线渲染管线(M4–M6.3) (#411)
* feat(editor): 编辑器实施 M0-M1 - 剪辑入口占位与插件 SDK v2 垂直切片

- detail.tsx 新增剪辑成片视图(editor tab,常驻),概览页插入剪辑步骤卡
- plugin-types.ts 新增 v2 类型(EditorSlotKind/EditorPluginPermission/PluginManifestV2),修复权限数组交叉归约 bug
- editor-slot-registry.ts 插槽注册表(优先级排序、幂等注册、订阅机制)
- plugin-registry.ts 注册器 v1/v2 分支校验,v1 路径零改动
- editor-shell.tsx 垂直切片插件:timeline-panel 插槽真实渲染,验证插件链路全通
- 测试:插槽注册表 5 用例 + 命令测试骨架,v1 插件回归 21 例零回归

* feat(editor): 命令协议黄金文件 - editor-commands 纯函数 reducer + 8 个黄金 op

* feat(editor): 快照撤销历史 - editor-history 有界 200 层 undo/redo

* feat(editor): 命令状态机 store - dispatch/手势预览/1.5s 防抖保存/串行保存链

* fix(editor): createEditorStore 返回 zustand hook 类型修复 typecheck

* feat(editor): 手势 echo 最小件 - 时间线面板拖拽移动/裁剪 + store 接线与本地持久化

* docs(editor): M2 完成状态记录

* feat(editor): M3.1 时间线面板选中联动 - store 选中状态 + 片段高亮/点击取消

* feat(editor): M3.2 预览监视器 - preview-renderer 插槽 + 真实媒体帧/播放头/时间码

* feat(editor): M3.3 片段检查器 - inspector 插槽 + 属性编辑入队可撤销

* feat(editor): M3.4 asset-ingest 素材库插件(addClip 命令入轨)

* feat(editor): M3.4 补充 - host 上下文(项目信息+资产)、editor.tsx 接线、asset-ingest 纯函数、死代码清理

* feat(editor): M3.5 subtitle-tools - SRT import/export + rebuild from node snapshot

* feat(editor): M3.6 transcription - deterministic mock ASR to subtitle track

* feat(editor): M3.7 export - render plan + ffmpeg.wasm fallback export

* feat(editor): M3.8 - render all 8 editor slots in three-pane layout + ai-assistant placeholder

* docs(editor): M3 完成状态 - 8 插件 + 全插槽接线,冒烟待确认

* feat(editor): 编辑器媒体与时间线打磨 - 资产来源分组筛选、时间线全宽布局、拖拽末片段修复、OSS 降级本地存储、Concat 风格控制条与检查器

* fix(plugins): 合并上游后修复插件分类筛选对 v2 清单的类型兼容

* feat(editor): 时间线工具态与轨道操作打磨 - 工具按钮选中仅图标变色、监视器 Concat 式控制条、removeTrack 黄金命令与轨道行头移除按钮、maskClosable 迁移

* fix(api): 资源上传超 MaxBytesReader 上限时报中文大小限制而非英文裸 400

* fix(editor): 监视器控制条 - 修复播放按钮 JSX 模板闭合花括号缺失导致的编译错误

* feat(api): 本地媒体导入分片化对齐 Concat - >50MB 视频不再失败 - 分片会话三接口(POST开始/PUT单片/complete合并)、前端超50MB自动切8MB分片并失败整传重试、默认配额放宽(日200MB→2GB、总2GB→20GB)、UploadResourceFile 豁免单文件限

* feat(editor): 轨道行头新增可见性/静音开关按钮 - 复用现有图标资源,按轨道类型显隐;命令层新增 setTrackFlag 黄金命令(flag 白名单 fail-closed)并补单测

* docs(progress): 记录轨道可见/静音开关改动与复测项

* docs(editor): M4 转写与渲染任务设计 - 复用 Task 表与状态机、独立创建 API、worker 领取类型过滤、whisper HTTP provider(OpenAI 兼容 /v1/audio)

* fix(api): OSS 上传失败自动降级本地存储时 body 已被 Transport 关闭 - newOSSRequest 用 NopCloser 包装请求体,服务端提前返回(签名 403)时不再关闭调用方持有的文件,降级分支 Seek 重读生效;补回归测试

* docs(progress): 记录媒体导入根治(分片+OSS 降级修复)复测项

* feat(api): 视频播放副本转码 H.265→H.264 + variant=playback 服务与启动回填 - 上传视频后异步探测 codec,H.265/AV1 走 moov 快速探测并转码 H.264 播放副本;GET /api/user-data/...?variant=playback 就绪时服务副本(独立 ETag :pb),未就绪回退原件并撤销后缀防 304 黑屏;storeResource 触发、启动幂等回填存量;前端播放失败自动轮询副本就绪后刷新

* fix(editor): 轨道至少保留一条 - 不可移除轨道点击 X 时居中浮现原因提示(2.2s 自动消失, aria-live);修正可见性 toggle 传参 (visible===false 语义) ;轨道行内移除按钮改为常驻(不可移除时点击给提示)

* feat(timeline): M4.1 字幕转写后台任务 - whisper.cpp 本地执行 - 新增 timeline_transcription 任务类型,worker 按类型分叉独立执行器(不走计费与模型渠道);输入 resourceId+language,读取用户资源后 ffmpeg 预处理 16k 单声道 wav,POST 本地 whisper.cpp /inference,结果写回 segments+srt+language;未配置 CANVAS_WHISPER_BASE_URL 等失败均落明确终态;feature 门控;进度分阶段;含解析/SRT/快速失败单元测试

* feat(media): 素材卡片时长与媒体面板打磨 - 导入媒体解析时长(前端 media-metadata + 后端 project_asset durationMs 透出)随卡片展示;媒体面板/监视器/时间线相关样式细节收尾

* docs(progress): 阶段 C 监视器播放复检清单 - H.265 播放副本/真实播放驱动/时长链路待浏览器确认

* feat(timeline): M4.1 转写任务创建 API - POST /api/timeline/transcriptions - service CreateTimelineTranscriptionTask:IsDraining 守护 + feature 门控 + 资源归属与可转写类型校验 + 排队计 active 限额(含任务级/项目级存储估算);local/whisper.cpp 标记,任务不经过模型路由与计费;createTaskWithinStorageQuota 复用与 ErrActiveTaskLimit 用户可读映射;测试覆盖排队成功(owner/type/provider 断言)、跨用户资源拒绝、非音视频拒绝

* feat(timeline): M4.3 字幕转写前端接线 - 真实任务替换 mock - 新增 services/api/timeline-tasks.ts(POST /timeline/transcriptions,复用 apiClient+request);EditorTranscription 改为 创建任务→waitForGenerationTask 轮询(25min)→结果 segments 映射 SrtEntry[]→rebuildSubtitleClips 写入字幕轨道;实时展示 stage/progress,失败/空识别/无字幕轨道分别提示;素材选择支持音频与视频(取 storageKey 中的 resource id 提交)

* fix(media): 播放副本状态收敛与轮询终态 - 无ffmpeg/远端存储/编码不可处理落 none 避免重复探测;前端 none 停轮询回原生播放并加 processing 上限

* feat(timeline): M4.2 时间线渲染任务 - POST /api/timeline/renders 创建(buildRenderPlan 校验含可渲染媒体、配额入队、local/ffmpeg、60min 超时);worker 顶部按类型分叉 processTimelineRender;ffmpeg 合成产物写资源存储并经 ResultJSON 记 resourceId;render 计划/结果测试 PASS

* fix(resource): 转码原子抢占与 OSS 请求体加固 - ClaimPlaybackTranscode 空/none→processing 单实例抢占避免重复转码,runPlaybackTranscode defer recover 落 failed;If-Range 与带 :pb 后缀的 serveETag 比较;无请求体的 OSS 请求不再包 NopCloser(nil)(防 Go 1.26 body 探测 nil 解引用)

* style(editor): 修正字幕回写面板缩进

* docs(timeline): M4 设计文档按实现回写 - 单一 worker 池 + processClaimedTask 顶部按类型分叉(决策 3/4),端点统一为复数 /api/timeline/transcriptions 与 /api/timeline/renders(注册于 RegisterTaskRoutes),ResultJSON/feature gate/ffmpeg env 同步;Runbook M4 表格与状态行更新;auth.go API 前缀白名单补 timeline

* fix(service): 修复上游 v1.2.5 公告配图删除保护自锁与测试夹具缺口

上游 #385 资源引用走查器对公告配图/草稿做了硬性引用检查,导致三个问题:
- UpdateAnnouncement 在更新公告前对旧配图走查,必然命中当前公告自身引用而自锁,
  公告替换配图功能实际不可用;DiscardAnnouncementImage 同理被草稿自身引用阻塞。
  修复:ensureResourceHasNoBusinessReferences 支持忽略指定引用(当前公告/当前草稿),
  其余引用仍按原语义拦截。
- admin DeleteAdminResources 将公告草稿引用视为阻塞,但删除事务会级联清理草稿与
  资源绑定,service 层永不进入事务,回滚审计注入测试无法到达预期路径。修复:service
  预检时过滤公告草稿引用,与 repository 级联语义对齐。
- project_settings_test.go 夹具未建 ResourceReferenceSnapshot 走查的 Task/Session/
  Message/TaskLog/Result/Announcement/AnnouncementImageDraft 表,报 no such table。
  修复:夹具 AutoMigrate 补齐。

后端全量 go test ./... 通过。

* feat(editor): 成片导出接入后端渲染任务(M4.2 前端接线)- timeline-tasks 增 createTimelineRenderTask;editor-export 主路径改 POST /timeline/renders 轮询取 resourceId 内嵌预览/下载,ffmpeg.wasm 降级保留

* feat(editor): M5 插件权限执行(fail-closed)- plugin-permission-check 新建(8 插槽最小权限表/判定/断言);SlotStack 渲染前过滤缺权限插槽改诊断条;editor-shell manifest 补 timeline.command/export.run;测试 10 用例含 editor-shell 真实回归

* feat(editor): M6.1 AI 命令 schema + M6.2 时间线摘要 - ai-command-schema(parse/dry-run 校验/12-op 提示词契约/版本化+golden);timeline-summary(确定性中文摘要/折叠上限);各 20/10 用例全绿

* docs(progress): M6 质检清单 - M6.1 schema/M6.2 摘要标记完成(含测试计数),M6.3 待模型源确认;清理 M5.1 重复条目

* feat(editor): AI 命令 schema 支持只读问答 - commands 空数组合法化(无法执行/纯提问时 reasoning 直接作答),新增 AI_EDITING_MAX_COMMANDS=8 上限防失控编辑,提示词同步

* feat(editor): AI 助手重构为右上悬浮对话面板(M6.3)+ 素材入库原子化收尾

- editor-ai-assistant.tsx: 占位面板替换为 OpenAI Canvas 风格右上悬浮对话面板;
  面板内文本模型选择器(effective.textModels,选择即持久化并覆写请求模型),
  消息流 user/assistant/error/preview 四类气泡 + 思考中占位,空态引导示例 chips
  一键发送,底部输入条;顶部工具栏常驻 Sparkles 入口(aria-pressed 切换)。
  修复上一版重复/截断函数声明(appendToEntry 双定义、settleAnswer 三声明等)。
  宿主链路:buildAiEditingSystemPrompt(summarizeTimeline(project)) 喂上下文 →
  parseAiCommandPlan → validateAiCommandBatch dry-run(任一非法整批拒绝)→
  ≤3 条 dispatch 直执行 / >3 条预览确认卡片;宿主拒绝时 failTurn 回填 FAILED_MARK 可重试。
- editor-asset-ingest/editor-preview-monitor/detail/editor.tsx: 配套接线与打磨
  (编辑器顶栏 AI 入口、素材导入面板、预览监视、项目页顶栏整理)。
- backend: LinkProjectAsset 事务内原子创建资产 + 项目链接(OnConflict 幂等),
  资产首次入库不再预落库,失败整体回滚,消除"有资产无链接"孤儿记录。
- docs: pending-test.mdx / runbook M6.3 状态更新(tsc + 测试 + 构建通过,
  浏览器冒烟待真实文本渠道)。
2026-09-04 14:03:33 +08:00

影策 logo

影策

让一个故事,从文字走向银幕

GitHub · 功能 · 文档 · 安全策略

影策是一个开源的 AI 影视与短剧创作工作台。它把自由画布、结构化分镜、角色与风格资产、图片/视频/音频生成、异步任务和本地 Agent 放在同一条创作链路里,让创作者从文字 brief 走到可复用的镜头资产。

项目仍在快速开发,数据结构和外部接口可能直接调整。默认适合个人、本地或可信环境部署;未经安全配置,不要直接作为公网多人服务使用。

演示环境:https://ddcat.pronhubcn.com

  • 账号:test
  • 密码:test123456

赞助商

感谢以下赞助商对影策项目的支持:

LOGO 类型 赞助商名称 说明 网站
ArtDance 商业 ArtDance 本项目 Seedance 模型的天使投资人。 artbox.top
快乐机艺术小组 团队 快乐机艺术小组 一支跨学科的艺术创作团队,持续探索数字与艺术的全新表达形式。 暂无
秘塔 企业 秘塔 提供 MiniMax H3 视频生成 API,支持原生 2K、音画同步和 OpenAI 兼容协议。 metaso.cn
浮瑞万相AI 企业 浮瑞万相AI 一家专注于AI视听的AI Native公司 暂无
喜马抓马 团队 喜马抓马 中国AI视听先锋厂牌/AI 视听全链路综合服务平台 himadrama.com
羽宇科技 企业 羽宇科技 一站式AI应用平台。提供模型算力入口、AI短剧视频制作(Studio)、企业数字员工(Agent)及内容出海(OPC)全栈解决方案。 暂无

贡献者与团队

感谢参与产品设计、开发、测试、内容和社区建设的成员:

头像 昵称 邮箱 个性签名
爱笑的毛毛虫 爱笑的毛毛虫
用户名:sikongyue
315515767@qq.com 正在啃 main 分支,争取下次 merge 的时候变成蝴蝶
delve-s delve-s 3013141136@qq.com 我亦无他,惟手熟尔
CyrusAuyeung CyrusAuyeung cyrusauyeungho@gmail.com HKUST(GZ) UG
奶大佬 奶大佬 1304634970@qq.com 人生就是要不断的探索
dyh dyh 1613203335@qq.com 无
kyori kyori 1771634408@qq.com 励志成为未来最好用的画布仓库的贡献者
Bowen Bowen admin@bowen.games 剑走偏峰,雷厉风行。
ken ken 2506802@qq.com 走自己的路
fish fish cihai.sea@gmail.com AI 界热于助人的拖油瓶
QAyong QAyong
ID:QAyong
B站:QAyong
2110491559@qq.com AI 短剧合规,资产确权
_K37ix. _K37ix. 2773843782@qq.com Making things that think
Rou Rou rou325089@163.com 上善若水
vv vv
dy/xhs:荣灵
2838033228@qq.com 就是水水
Dominic1556 Dominic1556 184026530@qq.com Done is better than perfect
宇熙 宇熙 53121904@qq.com 年轻的时候不狂,老了拿什么回忆
影子 影子 305818148@qq.com 年纪大佬才明白人要顺势而为。
Ray Ray cnraylee@qq.com AI时代的全栈落地工,欢迎找我聊需求

交流与反馈

Issue 反馈、技术讨论和产品升级建议都可以在 QQ 群中沟通。群内还会不定期组织 AI 学习与培训交流会。

影策 QQ 交流群 影策 微信交流群

当前能力

  • 自由画布:项目、节点、连线、框选、缩放、小地图、撤销重做、导入导出和公开只读分享。
  • 影视工作流:剧本、角色、场景、风格板、参考素材、结构化分镜和 3D 导演台。
  • 多媒体生成:文本、图片、视频、音频任务,支持参考图、首尾帧、运镜、视频续写、局部修改和批量生成。
  • 任务与素材:后端异步队列、任务日志、取消/重试、账号素材库、资源引用校验和登录后的跨设备同步。
  • Agent 协作:画布助手、本地 Canvas Agent、MCP 工具、Codex App 插件和技能库。
  • 管理与渠道:系统渠道、逻辑模型、用量/积分、功能开关、对象存储、响应拦截和管理后台。

详细功能清单见 docs/content/docs/overview/features.mdx,实现入口见 docs/content/docs/backend/code-map.mdx。

架构概览

浏览器(web/)
  ├─ React 工作区、画布、任务中心、素材库
  ├─ localForage/Zustand 本地状态与降级缓存
  └─ request.ts / channel relay
          │ 登录态 JSON、SSE、资源请求
          ▼
后端(backend/)
  ├─ Gin handler -> service -> repository/model
  ├─ SQLite(本地)或 PostgreSQL + Redis(部署)
  ├─ 异步任务 worker、资源存储、权限和模型中转
  └─ provider/outbound -> 外部模型渠道

本地 Agent(canvas-agent/) <-> 浏览器画布 <-> Codex MCP / 本机 CLI
Codex 插件(`plugins/yingce/`)负责把 MCP 接入 Codex App。

前端默认把 /api 代理到 http://127.0.0.1:8080;生产环境由网页容器的 Nginx 代理到后端,只有 web 的 3000 端口需要对外暴露。系统模型和文本任务的 SSE 只在明确的流式路径关闭代理缓冲,详见 nginx.conf 和 SSE 文档。

本地开发

环境

  • Bun(前端和文档站)
  • Go 1.25(后端)
  • Node.js 18+(Canvas Agent)
  • 如使用 Docker 开发,需要 Docker Compose

宿主机启动

git clone https://github.com/ddcat-ai/open-ai-canvas.git
cd open-ai-canvas

# 开发数据必须使用 Git 忽略的目录,不要直接使用 backend/data
mkdir -p .local/project-workbench-debug .local/cache/go-build .local/cache/go-mod

# 终端一:后端
cd backend
CANVAS_BACKEND_DATA_DIR=../.local/project-workbench-debug go run ./cmd/server

# 终端二:前端
cd ../web
bun install
bun run dev

Windows PowerShell 用户也可以在仓库根目录执行一键启动脚本:

.\scripts\start-local.ps1

脚本会使用 .local/project-workbench-debug 作为后端开发数据目录,并分别打开前后端窗口。缺少 web/node_modules 时会自动执行 bun install --frozen-lockfile。详细说明见 本地开发。

打开 http://localhost:3000,注册第一个管理员账号,再在设置中配置模型渠道。前端的 Vite 配置会把 /api 代理到本机 8080。

如需修改代理目标,设置 VITE_API_PROXY_TARGET;如生产前端与后端不共源,构建时设置 VITE_CANVAS_BACKEND_URL。用户的模型 Base URL、API Key 和模型名保存在浏览器本地,真实密钥只应发送到可信且启用 HTTPS 的自部署后端。

Docker 开发和本地构建

源码热更新(Vite HMR + Air):

LOCAL_UID=$(id -u) LOCAL_GID=$(id -g) \
  docker compose -f docker-compose.dev.yml up --build

本地构建前后端 release 镜像:

docker compose -f docker-compose.local.yml up -d --build

两种方式都使用容器内的数据卷;源码热更新编排额外绑定 .local/project-workbench-debug,避免 Compose 静默创建另一套开发账号数据。端口冲突时可通过 CANVAS_WEB_HOST_PORT、CANVAS_BACKEND_HOST_PORT 覆盖开发端口。

私网模型和本机渠道

后端默认拒绝本机、私网和链路本地模型地址。开发时只为可信主机设置精确白名单:

CANVAS_ALLOWED_PRIVATE_UPSTREAM_HOSTS=192.168.1.10

不要用 CANVAS_ALLOW_PRIVATE_UPSTREAMS=true 代替白名单。桌面本机渠道是另一项能力,只有后端绑定 127.0.0.1:8080 且设置 CANVAS_DESKTOP_LOCAL_CHANNELS_ENABLED=true 才会生效,云端和 Docker 默认不会获得该能力。

服务器部署

一键源码构建(推荐)

适用于 Linux 云服务器。脚本会安装 Docker,拉取源码,生成受保护的 .env,构建网页/后端镜像并启动 PostgreSQL、Redis、后端和网页:

curl -fsSL https://raw.githubusercontent.com/ddcat-ai/open-ai-canvas/main/scripts/install-server.sh | sudo bash

默认访问 http://服务器IP:3000。第一个注册账号会成为管理员;公开注册默认关闭。更新或排查:

cd /opt/open-ai-canvas
sudo docker compose --env-file .env \
  -f docker-compose.deploy.yml -f docker-compose.build.yml ps
sudo docker compose --env-file .env \
  -f docker-compose.deploy.yml -f docker-compose.build.yml logs -f --tail=200

直接使用 GHCR 镜像

服务器不需要源码时可使用镜像脚本:

curl -fsSL https://raw.githubusercontent.com/ddcat-ai/open-ai-canvas/main/scripts/install-server-image.sh | sudo bash

容器包不可匿名拉取时,先通过 GHCR_USERNAME 和 GHCR_TOKEN 登录 GHCR。生产环境应在 /opt/open-ai-canvas/.env 中把 CANVAS_IMAGE_TAG 固定为具体 Release(不要使用 latest),端口由 CANVAS_HTTP_PORT 配置。

固定版本的 GHCR 部署可安装宿主机在线更新器;安装后管理后台会出现“系统配置 → 系统更新”,更新器会在切换前强制生成并校验 PostgreSQL 与数据目录 ZIP 备份:

cd /opt/open-ai-canvas
curl -fsSL https://raw.githubusercontent.com/ddcat-ai/open-ai-canvas/main/scripts/install-host-updater.sh | sudo bash
sudo docker compose --env-file .env -f docker-compose.deploy.yml up -d --force-recreate backend web --wait

更新流程、数据库迁移、健康验证和异常回退说明见 docs/content/docs/backend/system-update.mdx。

公网必做事项

  • 先在受控网络注册首个管理员,再开放公网入口;保持 CANVAS_REGISTRATION_ENABLED=false。
  • 设置准确的 CANVAS_CORS_ORIGINS,不要在公网使用 *。
  • 使用 HTTPS,并保留反向代理的 Host、X-Forwarded-For、X-Forwarded-Proto。
  • 只对 /api/tasks/:id/text-events 和系统模型事件流路径关闭缓冲、缓存和 gzip;不要把 SSE 配置复制给所有 /api/ 请求。
  • 限制 .env、数据库、PostgreSQL/Redis 数据卷、上传目录、备份和 .settings-key 的权限;数据卷不等于备份。
  • 后端 8080 留在 Compose 网络内,不要直接暴露到公网。

具体 Nginx/Caddy 示例和断线恢复方式见 docs/content/docs/overview/docker.mdx。

数据和安全边界

  • 画布、项目、任务和素材登录后同步到后端;浏览器 localForage 仍承担缓存和后端不可用时的降级存储。
  • 本地默认使用 SQLite;部署 Compose 使用 PostgreSQL 和 Redis。多实例 PostgreSQL 模式需要 REDIS_URL 用于限流、并发和熔断协调。
  • 媒体资源可使用后端数据目录、阿里云 OSS 或腾讯云 COS。资源长期引用使用 resource:<id>,删除素材前会检查业务引用。
  • 用户 API Key 不应出现在 URL、日志、错误上报或服务端长期明文存储中;使用真实 Key 前确认部署可信且链路为 HTTPS。
  • 自定义渠道经后端 /api/ai/custom 中转;默认 SSRF 防护拒绝本机和私网目标,可信开发主机必须显式白名单。

安全问题请按 SECURITY.md 报告,不要在公开 Issue 中粘贴密钥、Cookie、数据库或生产日志。

Canvas Agent 和 Codex 插件

本地 Agent 用来连接网页画布与本机 Codex/CLI:

npx -y @ddcat666/open-ai-canvas-agent

仓库内开发构建:

cd canvas-agent
npm install
npm run build
node dist/index.js

启动后将终端输出的 Local URL 和 Connect token 填入画布右上角 Agent 面板。Agent 默认只监听 127.0.0.1,token 不应写入 URL、日志或任务正文。完整 MCP 工具、Codex App 插件安装和本地安全边界见 canvas-agent/README.md 与 plugins/yingce/README.md。

验证命令

项目不会在每次修改后自动执行验证;按改动范围手动运行:

# 前端
cd web && bun run build

# 后端
cd backend && go test ./...

# Canvas Agent
cd canvas-agent && npm test && npm run build

# 文档站
cd docs && bun run types:check

前端专项测试和后端集成测试较多,优先运行与改动模块相关的测试;UI 改动还应在浏览器检查关键路由、主题、弹窗、滚动和空态。验证结果必须在提交或交付说明中如实记录。

文档导航

根目录 AGENTS.md 约束协作方式;docs/index.md 是面向 AI 的文档索引。

许可证和上游

本项目采用 MIT 协议。影策基于 basketikun/infinite-canvas 的早期版本进行二次开发,上游作者和贡献者保留其对应代码的权利与署名。

Description
No description provided
Readme MIT 862 MiB
Languages
TypeScript 50.7%
Go 33.1%
CSS 11.8%
JavaScript 2.5%
Python 1.7%
Other 0.1%