agentsclimarketplace

Create plugin

Skill dootask/skills/skills/create-plugin

从零创建一个 DooTask 插件(脚手架 + 本地构建/安装验证)。From its SKILL.md

Install
npx -y skills add dootask/skills --skill create-plugin

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

3 things to look at

  • reads credentialsReads from 2 credential sources: `DOO_SERVER` and 1 more.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 8 commands, including `git -C <目标父目录> rev-parse --is-inside-work-tree` and 7 more.

SKILL.md

17.5 KB, ~6.4k tokens by cl100k_base, as published. Nobody here has run it

创建 DooTask 插件

把「我要一个 DooTask 插件」变成一个结构正确、能装进主程序跑起来的脚手架,外加一个最小可见的示例页/接口。业务逻辑留给后续开发填充,但骨架的每个文件、每条约定都要正确,这样开发者拿到就能直接迭代,而不是先踩一遍配置坑。

核心原则:对照现成同形态插件,别凭空捏

DooTask 的配置约定有文档漂移(例如 menu_items 的菜单模式在不同插件里写成 url_type:type:),照搬过时文档容易出错。最可靠的做法是:选定形态后,找一个同形态的现成插件作为「参照样板」,逐文件对照它的真实写法来生成,而不是套死模板。本技能给出的模板是起点,参照样板是校准基准。

样板与本地参考资料全部用带 ref: 前缀的代表词指代ref: 是命名空间前缀,把登记条目和正文同名普通词区分开),绝对路径与获取方式统一登记在 references/samples.md(本机有 checkout 就直接读;没有就 git clone --depth=1 到可复用临时目录再读;私有/拿不到则回退本技能 references)。见到 ref:xxx 时先按它的「获取约定」解析。

常用样板(按形态选,详见 references/samples.md):

  • 前后端自建镜像型(默认 JS/TS 全栈首选):ref:crmTanStack Start,扁平布局与本技能 1:1,优先对照)、ref:asset-hubNext.jsdocs/rules/ 是权威规范)
  • 前后端自建镜像型(Go/Python 变体):ref:approve(Go + MySQL)、ref:ai(Python + Vite 前端)
  • 代理 + 上游官方镜像型:ref:memos(包在 dootask-plugin/ 子目录)
  • 纯配置 / 复用现成镜像型:ref:mysql-expose-port
  • 纯前端静态型:参照镜像型,后端换成一个仅托管静态资源的小容器

布局:ref:crm 就是扁平布局(<appid>/src/ + .build.yml + <版本>/),与本技能生成的结构完全一致,优先对照它ref:asset-hub/ref:memosdootask-plugin/ 包裹布局——照抄它们的 Dockerfile / basePath / nginx / @dootask/tools 集成写法即可,目录仍落到扁平结构。

生成前先读样板:解析出样板目录后,读它的 config.yml(顶层与版本目录)、docker-compose.ymlnginx.conf.build.yml,对照真实写法来生成。三档都拿不到时,依赖本技能的参照文件并明确告知用户「未读到现成样板,按规范生成,请重点复核」。

其它本地参考资料(同样登记在 references/samples.md,按代表词获取):ref:appstore-docs(官方插件开发文档)、ref:tools@dootask/tools 前端 + Go/Node/Python SDK 源码)、ref:app-landing(应用落地目录,只读)、ref:dootask(主程序源码)。

工作流

按顺序推进,每一步把假设说清楚,关键岔路口让用户拍板。

1. 收集需求

至少问清下面这些(用户一句话需求里没有的才问,已知的别重复问):

  • 插件名:中文名 + 英文名(config.ymlname.zh / name.en)。
  • appid:小写裸名(如 crmasset-hub),是镜像名 dootask/<appid>、nginx 路径 /apps/<appid>、前端 base path 的统一来源。默认取英文名小写连字符,向用户确认。
  • 作者:AppStore 发布账号(本机为 kuaifan),只用于部署目录名 community_<作者>_<appid>(见第 6 步);不影响 appid/镜像/路径。
  • 一句话描述:中英文,进 description
  • 形态:见第 2 步。
  • 技术栈:默认走全 JS/TS 栈(前后端一套语言,依赖与工具链统一,最好维护)。
    • 前端:Next.jsTanStack Start 平级推荐,都配 shadcn/ui + Tailwind。两者各有取舍(Next 更成熟、ref:asset-hub/ref:kpi 有现成 Next.js 参照;TanStack Start 更轻、Vite 底座、类型安全路由),运行时让用户二选一,别替他默认死。
    • 后端:默认 Node + TypeScript(用 @dootask/tools 的 Node SDK)。
    • 其它语言(Go / Python)仍支持,@dootask/tools 有对应 SDK(见 references/tools.md),但仅在用户明确要求时才用,不作默认。
  • 是否需要后端:纯前端就走「纯前端静态型」,有业务接口才加后端。
  • 菜单入口:放在哪个位置(application 应用菜单 / application/admin 应用管理 / main/menu 主菜单)、用哪种打开模式(iframe 兼容性最好,默认推荐)。
  • 配置字段 fields(可选):安装时让管理员填的参数(端口、密钥、管理员用户等)。
  • 首个版本号:默认 0.1.0

2. 选定形态

四种形态,按需求选一种,然后references/forms.md 里对应小节拿到该形态的目录结构、compose、nginx 写法与构建方式:

形态何时选镜像
前后端自建镜像型有自己的前端页面 + 后端接口(最常见)自建 dootask/<appid>
代理 + 上游官方镜像型想集成一个现成开源服务(如 memos),用轻量代理做鉴权转发上游官方镜像(固定版)+ 自建代理镜像
纯前端静态型只有前端,无业务后端一个仅托管静态资源的小容器
纯配置 / 外链型不写代码:复用现成镜像,或只在主程序里加个外链菜单现成镜像或无镜像

拿不准时默认「前后端自建镜像型」,它覆盖面最广。

3. 确定落地位置(新目录)

本技能默认在一个新目录里创建独立插件项目,不假设当前已经在某个插件仓库里。

  1. 确认目标路径:默认 <cwd>/<appid>/,把绝对路径报给用户确认后再动手。
  2. git 初始化询问:检查目标位置是否已在 git 仓库内(git -C <目标父目录> rev-parse --is-inside-work-tree)。若不是 git 目录,询问用户是否 git init 初始化;同意则初始化,不同意就只建普通目录。
  3. 目录布局——扁平布局:项目根目录就是 <appid>/,直接平铺放 config.yml + logo + README* + <版本>/,镜像型再加 src/.build.yml。这与本技能脚本(build_image.sh / upload_to_appstore.sh)预期的布局一致,部署时把整个项目目录当作「插件目录」传入即可。

注:少数现成项目(如 kpi/memos)把 AppStore 包放在 dootask-plugin/ 子目录、源码与 Dockerfile 放仓库根。那是它们的历史布局,本技能新建项目统一用上面的扁平布局,更简单且与脚本对齐。

4. 生成骨架

动手前:若用户只给了名字/一句话需求,先问一次(可选)要不要聊聊产品需求(实体、页面、流程、权限)再写代码;已说清楚就直接搭。

按所选形态生成文件。务必遵守的硬约定(细节见 references/config-yml.mdreferences/forms.md):

  • 顶层 config.yml 只放元数据name/description/author/website/tags(都支持 en/zh)。标准/镜像型不要把 fields/menu_items/hooks 放顶层——放版本目录(随版本走)。例外:纯配置型 D1(如 ref:mysql-expose-port)没有版本 config.ymlfields 直接放顶层。
  • 版本目录 <版本>/config.yml 放功能配置fields / menu_items / hooks / require_version,以及推荐默认带上的 openapi / knowledge_base(见下条)。
  • 让主程序 AI 能用上你的插件:适合接入 AI 的插件默认带上对应项——插件有值得被调用的后端操作时声明 openapi(指向后端 OpenAPI/Swagger 规范),主程序的用户/AI 即可 doo app call 执行你的功能;插件有面向用户、会被问到的用法时随包带一份 knowledge_base 知识库目录并声明,产品内「AI 助手」即可解答其用法。两者各自独立判断,都没有就都不加。写法/鉴权/目录结构见 references/config-yml.md
  • 菜单角标(有「未读/待办」语义时用):菜单可显示数字角标或红点,按 (应用, 菜单, 用户) per-user、插件没打开也生效。给菜单起 key、按语义设 badge_clear_on_open(通知类打开即清 / 审批中心等计数由插件维护),后端用应用密钥(内置 APP_SECRET/APP_ID)调 SDK 的 setAppBadge 下推。字段见 references/config-yml.md、SDK 用法见 references/tools.md
  • docker-compose.yml:镜像写 dootask/<appid>:${PLUGIN_VERSION};不对外暴露端口(特殊需求除外);环境变量来自 fields 与内置变量;连主程序后端用服务名 service、连主 nginx 用 nginx、数据库用 ${DB_HOST}/${DB_PORT}/${DB_DATABASE}/${DB_USERNAME}/${DB_PASSWORD} 等内置变量。
  • nginx.conflocation 路径必须与 menu_items.url 的基础路径一致;反代到容器内部服务名:端口;末尾 / 用来剥离前缀——是否加要看前端有没有用 basePath 自己接管前缀:Next/TanStack basePath 模式不加、代理/剥前缀模式才加,按形态见 references/forms.md;SSE/WebSocket 记得关 buffering、带 Upgrade/Connection 头、调长超时。
  • CHANGELOG.md + CHANGELOG_zh.md:首版写一句初始化说明即可。
  • logo:放一个占位 logo.svg(提醒用户替换为真实 logo)。
  • 右上角是主程序「胶囊」的领地:插件装进弹窗后,主程序会在内容区右上角浮一个胶囊条(「更多」+「关闭」)盖住页面。前端别把自己的操作/关闭按钮放右上角;需调显隐、位置或往「更多」加菜单项时用 setCapsuleConfig(见 references/tools.md)。
  • 移动端安全距离:移动/沉浸式下屏顶底被系统占位,用 getSafeArea() 让布局让位、别用 CSS env(),详见 references/tools.md
  • README.md + README_zh.md:这是 AppStore 展示文案,不是开发说明。
  • 镜像型还要:.build.ymlimage: dootask/<appid> / context: src / dockerfile: src/Dockerfile)和 src/
  • CLAUDE.md(必须生成,关键):在插件根目录生成一份项目记忆,让后续新会话不丢上下文——它会被每次会话全量注入,价值在「本地参考路径 + 先读本地别上网硬规则 + basePath/端口/部署目录等雷区」,正是新会话最容易忘、会害它跑去联网找 DooTask 文档的部分。做法:读 assets/CLAUDE.md.template填充并裁剪——替换所有 {{...}} 占位(appid/作者/插件名/技术栈/版本/前端 base 配置文件/产品一句话),并删掉本项目不适用的行,逐行套黄金法则「删了 Claude 会不会犯错,不会就删」,保持精简(CLAUDE.md 越长遵从度越低)。模板已内置一份精简的「本地参考登记」表(取自 references/samples.md,让生成的 CLAUDE.md 自带 ref: 解析依据、脱离本技能也能用):按本插件实际栈裁剪掉不相关的样板行(如选 Next.js 就删 ref:crm 行、保留 ref:asset-hub),用到表外样板时从 samples.md 补对应 ref: 行。写到 <appid>/CLAUDE.md。如需更系统地写/优化,可参考用户级技能 claude-md

最小可跑示例(这是本技能区别于纯模板的地方):src/ 里给一个能直接看到效果的最小实现——前端一个页面,启动即 appReady()getUserInfo() 把当前用户名显示出来,证明与主程序握手成功;有后端则加一个 /api/.../ping 之类的接口并由前端调用一次。接入方式见 references/tools.md。**有后端时一并给出一份覆盖该 ping 接口的 openapi.yaml 并在 config.yml 声明 openapi,让主程序 AI 能直接 doo app call 调到它——这是「装上就能被 AI 用起来」的最小证明。**目标是「装上就能看到一个活的页面」,不是空壳。

5. 本地构建镜像(镜像型形态)

.build.yml 本地构建,镜像 tag 必须等于将要安装的版本号(compose 里 ${PLUGIN_VERSION} 会被替换成该版本),否则安装时找不到镜像:

scripts/build_image.sh <插件目录> <版本号>
# 等价于:docker build -t dootask/<appid>:<版本号> -f <context>/<dockerfile> <context>

构建失败要把错误贴给用户、定位到 Dockerfile/依赖问题,别跳过。

6. 上传到本机应用商店(通过 doo)

打包后的内容(不含 src/.build.yml、点文件)打成 .tar.gz,用 doo app upload 导入到本机 DooTask 应用商店(注意:是本机这个开发实例的应用商店,不是公共仓库;公共仓库要靠后续作者发布流程)——等同网页「上传本地应用」,自带后端合规校验,导入后落到 apps/community_<作者>_<appid>/(作者 = 本地 AppStore 账号,本机为 kuaifan):

scripts/upload_to_appstore.sh <插件目录> <版本号> <作者>

打包规则(脚本已实现,理解即可):拷 config.yml + logo.* + README* + 目标 <版本>/ + 其它非版本子目录(如 icon/resources/);排除 src/.build.yml.git 等点文件、非目标的版本目录、以及根目录其它文件(根文件走白名单 config.yml/logo.*/README*,故 CLAUDE.md 等开发文件不会进包)。打成 tar.gz 后调 doo app upload --appid community_<作者>_<appid>,后端做合规校验:缺 config.yml / name 字段非法等会直接报错,不必等到安装时才挂。

前置:本机已装并登录 doosudo npm i -g @dootask/clidoo auth login 或设 DOO_SERVER/DOO_TOKEN)。doo 不可用时脚本立即报错退出。

7. 安装与验证(CLI 全闭环)

doo app upload 走的是后端合规校验通路,与网页「更新应用列表」无关——上传成功即落入本机应用商店,无需再去后台点更新。整套验证可在 CLI 完成:

  1. 报告已生成的文件清单与镜像构建结果(docker images | grep <appid>)。
  2. 列字段并装:doo app fields community_<作者>_<appid> 看 fields 定义(若不为空,说明各项含义/建议值)→ doo app install community_<作者>_<appid> [--param K=V ...],每个必填字段用一个 --param 传值。doo 在装前会做必填校验,缺项立即报错。fields 设计上含密码/密钥的,应在 config.yml 里给 default: $random:N(这是 yaml 写法,不是 CLI 参数),后端会在安装时自动生成。
  3. 验证:
    • doo app containers community_<作者>_<appid> —— 看容器/服务是否在跑;
    • doo app logs community_<作者>_<appid> —— 看安装/运行日志;
    • 打开菜单入口 /apps/<appid>,最小示例页应显示当前用户名 → 证明与主程序握手成功。
  4. 装坏了的回滚:doo app uninstall community_<作者>_<appid> [--delete-data] --yes;先卸载,再doo app remove community_<作者>_<appid> --yes 彻底清掉社区应用的本地目录(直接 remove 已安装应用会被后端拒绝)。uninstall/remove 是危险操作,默认要交互确认;CLI 非交互流程必须显式加 --yes-y),否则会卡在确认提示走不下去。
  5. 如实说明:本技能完成到「镜像已构建 + 已导入 + 已安装 + 容器在跑」才算闭环;最小示例页用于确认握手,业务逻辑待开发。

不要把「已生成骨架」说成「插件已上线可用」。

参考文件

  • references/samples.md —— 样板与本地参考登记表ref: 代表词 → 本机路径 + 在线仓库的映射,以及「本地优先 → 缺失则 git clone --depth=1 到可复用临时目录 → 回退」的获取约定。全技能见到 ref:xxx 都来这里解析。
  • references/forms.md —— 四种形态各自的目录结构、docker-compose.ymlnginx.conf、构建方式、参照样板与适用场景。选定形态后必读对应小节。
  • references/config-yml.md —— config.yml 全字段速查:顶层元数据、版本目录的 fields(含字段类型与 $random/$uuid 语法)、menu_items(location/url 变量/打开模式,含 url_type vs type 的实战说明)、hooksrequire_version/conflict_version、docker-compose 内置变量表。
  • references/tools.md —— @dootask/tools 速查:前端核心 API 与最小握手代码、Go/Node/Python 后端 SDK 的引入与鉴权(默认 http://nginx + token)。
  • references/local-test.md —— 本地构建 + 上传 + 安装验证的完整 CLI 闭环步骤、打包包含/排除规则、常见报错排查。

脚本

  • scripts/build_image.sh —— 读 .build.yml 本地构建镜像,tag 自动打成 dootask/<appid>:<版本号>
  • scripts/upload_to_appstore.sh —— 按打包规则打成 .tar.gz,通过 doo app upload --appid community_<作者>_<appid> 导入本机应用商店(前置:本机已装并登录 doo)。

资源

  • assets/CLAUDE.md.template —— 生成到插件根目录的项目记忆模板(第 4 步填充占位后写入 <appid>/CLAUDE.md),让后续新会话保留本地路径、硬规则与构建部署命令。模板内自带一份精简的「本地参考登记」表ref: 代表词 → 路径 + 在线仓库,取自 references/samples.md):因为生成的插件目录里没有 samples.md,把相关条目随模板带过去,生成的 CLAUDE.md 才能自洽解析 ref:xxx。生成时按实际栈裁剪,保持精简。

What ships with it: 8 files

48.5 KB alongside SKILL.md, 2 of them executable

assets/

references/

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.