
Super Productivity 插件开发指南基于 super-productivity/plugin-api 的 TypeScript 插件开发与发布全流程【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity导读本文围绕 Super Productivity 官方插件开发指南DEVELOPMENT.md展开系统讲解如何基于super-productivity/plugin-api这一官方 TypeScript 类型包从零构建、编译、测试并发布一个插件同时覆盖核心维护者更新 API、与主项目同步类型、执行发布流程的完整链路。读完本文你将掌握插件目录结构、manifest 与权限配置、Hook 事件接入、核心类型体系以及如何把插件发布到 npm 供 Super Productivity 用户安装使用。一、插件 API 包是什么super-productivity/plugin-api是 Super Productivity 官方提供的 TypeScript 定义包发布在 npm 上用于支持插件开发者以全类型安全的方式编写插件。从源码结构看包内只有三个源文件packages/plugin-api/src/index.ts、packages/plugin-api/src/types.ts、packages/plugin-api/src/issue-provider-types.ts其中入口文件仅仅做了两件事导出通用类型和导出 issue-provider 专用类型// Official TypeScript definitions for developing Super Productivity plugins export * from ./types; export * from ./issue-provider-types;包内不携带任何运行时逻辑这一点与官方文档Import types only to avoid runtime dependencies的最佳实践完全一致——插件只消费类型定义真正的执行逻辑由 Super Productivity 主程序提供。该包本身的 package.json 声明了main指向编译产物dist/index.js、types指向dist/index.d.ts并要求 Node.js 18。二、安装与 TypeScript 环境搭建2.1 安装依赖在插件项目根目录执行npm install super-productivity/plugin-api该包在 npm 上的版本历史可从 PUBLISHING.md 得知当前仓库内版本为1.0.1首个发布版本为1.0.0遵循语义化版本。2.2 TypeScript 配置官方指南要求在插件项目中创建tsconfig.json建议配置如下与插件 API 包自身的 tsconfig.json 保持一致的编译口径{ compilerOptions: { target: ES2020, module: commonjs, lib: [ES2020, DOM], strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true }, include: [src/**/*], exclude: [node_modules] }strict: true确保插件代码获得完整的类型检查lib: [ES2020, DOM]与目标运行时Web 渲染进程/Electron匹配插件 API 包自身额外开启了declaration: true、noEmitOnError: true等选项以保证发布给插件的index.d.ts是完整且自洽的。三、插件目录结构官方指南给出的标准插件项目结构如下my-plugin/ ├── src/ │ └── plugin.ts ├── dist/ │ └── plugin.js ├── manifest.json ├── index.html (optional) ├── icon.svg (optional) ├── package.json └── tsconfig.json其中各文件职责src/plugin.ts以 TypeScript 编写的插件主逻辑调用PluginAPI注册 Hook、按钮、快捷键等dist/plugin.jstsc编译产物Super Productivity 实际加载的是编译后的 JavaScriptmanifest.json插件清单声明插件身份、权限、Hook 与界面形态index.html可选当插件声明iFrame: true时用于承载插件自定义 UIicon.svg可选插件图标路径相对于插件根目录。仓库中的 packages/plugin-dev 目录收录了大量真实插件示例如brain-dump、doc-mode、automations、github-issue-provider等是研究 manifest 结构与插件实现的活教材。例如 brain-dump 的 manifest.json 展示了每行一个任务的快速捕获插件如何声明权限{ name: Brain Dump, id: brain-dump, manifestVersion: 1, version: 1.0.0, minSupVersion: 13.0.0, description: Quickly capture many tasks at once. Each line becomes a task., author: Super Productivity, permissions: [ getAllProjects, addTask, showSnack, openDialog, persistDataSynced, loadSyncedData ], hooks: [], iFrame: false, isSkipMenuEntry: true, icon: icon.svg }四、开发工作流官方指南将插件开发提炼为三步循环使用 TypeScript 编写代码享受完整的类型安全PluginAPI、PluginManifest、PluginHooks等均来自super-productivity/plugin-api编译为 JavaScript交给 Super Productivity 的插件系统加载执行在 Super Productivity 插件系统中测试实际行为。4.1 在 package.json 中配置构建脚本官方示例将build、build:watch、dev三个脚本均指向tsc并把插件 API 与 TypeScript 放入devDependencies{ scripts: { build: tsc, build:watch: tsc --watch, dev: tsc --watch }, devDependencies: { super-productivity/plugin-api: ^1.0.0, typescript: ^5.0.0 } }注意将super-productivity/plugin-api放在devDependencies而不是dependencies正是官方最佳实践Import types only的落地方式——编译期类型在构建后即被擦除运行时不需要该依赖可避免向产物引入无用的运行时依赖。4.2 最小可运行示例综合官方 README.md 与PluginAPI接口定义一个典型的plugin.ts长这样import type { PluginAPI, PluginHooks, PluginManifest, } from super-productivity/plugin-api; // 1. 响应任务完成事件 PluginAPI.registerHook(PluginHooks.TASK_COMPLETE, (taskData) { console.log(Task completed!, taskData); PluginAPI.showSnack({ msg: Task completed successfully!, type: SUCCESS, ico: celebration, }); }); // 2. 注册头部按钮点击后展示插件自己的 UI PluginAPI.registerHeaderButton({ label: My Plugin, icon: extension, onClick: () { PluginAPI.showIndexHtmlAsView(); }, }); // 3. 注册自定义快捷键 PluginAPI.registerShortcut({ id: my_shortcut, label: My Custom Shortcut, onExec: () { PluginAPI.showSnack({ msg: Shortcut executed!, type: SUCCESS }); }, }); // 4. 读取应用完整快照 const state await PluginAPI.getAppState();PluginAPI是插件与主程序交互的单一入口。从 src/types.ts 的实现可以看出它提供了注册类 APIregisterHook、registerHeaderButton、registerMenuEntry、registerShortcut、registerSidePanelButton、registerWorkContextHeaderButton、registerIssueProvider、数据读取 APIgetTasks、getAppState、getSelectedTask、getFocusedTask、getAllProjects、getAllTags、数据写入 APIaddTask、updateTask、deleteTask、addProject、deleteProject、reorderTasks以及 UI 桥接 APIshowSnack、notify、openDialog等。类型定义还通过HookPayloadMap将每个 Hook 事件映射到对应的 payload 类型保证registerHook回调参数的类型随 Hook 名自动收窄。五、核心类型参考官方指南按类别列出了类型清单结合源码可给出更精确的定义位置与语义。5.1 核心接口类型说明源码位置PluginAPI插件主 API 接口注册/读写/UI 桥接的入口src/types.tsPluginManifest插件清单配置id、hooks、permissions 等src/types.tsPluginBaseCfg运行时配置主题、应用版本、平台、是否开发模式等src/types.tsPluginBaseCfg尤其值得注意它携带了插件运行环境的元信息export interface PluginBaseCfg { theme: light | dark; appVersion: string; platform: web | desktop | android | ios; isDev: boolean; lang?: { code: string; [key: string]: unknown }; }插件可以根据platform区分 Web、桌面Electron、Android、iOS 上的行为差异例如executeNodeScript仅在 Electron 桌面端可用根据isDev决定是否输出调试信息。5.2 Hook 类型PluginHooks枚举定义了插件可订阅的全部事件源码中的完整清单比文档列举的更全export enum PluginHooks { TASK_CREATED taskCreated, TASK_COMPLETE taskComplete, TASK_UPDATE taskUpdate, TASK_DELETE taskDelete, CURRENT_TASK_CHANGE currentTaskChange, FINISH_DAY finishDay, LANGUAGE_CHANGE languageChange, PERSISTED_DATA_CHANGED persistedDataChanged, ACTION action, ANY_TASK_UPDATE anyTaskUpdate, PROJECT_LIST_UPDATE projectListUpdate, WORK_CONTEXT_CHANGE workContextChange, }PluginHookHandlerT是通用的 Hook 处理器签名借助HookPayloadMap实现按 Hook 名推断 payload 类型export type PluginHookHandlerT extends Hooks Hooks ( payload: T extends keyof HookPayloadMap ? HookPayloadMap[T] : unknown, ) void | Promisevoid;各 Hook 的 payload 均有独立接口定义例如TaskCreatedPayload含taskId与完整Task、WorkContextChangePayload即ActiveWorkContext快照。官方 README 对PERSISTED_DATA_CHANGED有专门约定它在宿主完成初始引导加载后任何持久化数据变更含远端同步投递与批量导入都会触发回调不携带 payload插件需要自行按key重新调用loadSyncedData(key?)获取最新数据契约要求插件在初始化时先loadSyncedData()取得初始状态再依赖此 Hook 跟进后续变化且 Handler 必须幂等。5.3 数据类型文档中的TaskData、ProjectData、TagData在源码中其实是已废弃的别名官方已统一为Task、Project、Tag/** deprecated Use Task instead */ export type TaskData Task; /** deprecated Use Project instead */ export type ProjectData Project; /** deprecated Use Tag instead */ export type TagData Tag;新插件应直接使用Task、Project、Tag。其中Task完整覆盖了标题、备注、时间估算/实际耗时、完成状态、项目/标签归属、子任务、重复配置、议题跟踪字段issueId、issueProviderId 等以及内部 UI 状态字段Project还包含主题色与taskIds/backlogTaskIds排序信息。PluginCreateTaskData则定义了创建任务所需的最小字段标题必填其余如projectId、tagIds、notes、timeEstimate、parentId、dueDay可选。5.4 UI 类型UI 相关类型均可在源码中找到精确定义DialogCfg/DialogResult/DialogButtonCfg对话框配置。注意htmlContent会被宿主做 HTML 清洗白名单重建移除脚本、事件属性、内联 SVG 等非可信内容必须自行转义SnackCfg轻提示配置type可取SUCCESS | ERROR | WARNING | INFONotifyCfg系统通知配置title bodyPluginMenuEntryCfg/PluginShortcutCfg/PluginHeaderBtnCfg菜单项、快捷键、头部按钮配置PluginSidePanelBtnCfg/PluginWorkContextHeaderBtnCfg侧栏按钮以及仅在指定工作上下文PROJECT | TAG | TODAY下显示的上下文感知头部按钮。5.5 进阶类型源码补充除文档列举的类型外src/types.ts 还提供了大量进阶能力值得插件作者关注OAuthFlowConfig/OAuthTokenResultOAuth 授权流程配置与令牌结果支持为 AndroidmobileClientId、iOSiosClientId、WebwebClientId分别指定客户端 IDPluginNodeScriptConfig/PluginNodeScriptRequest/PluginNodeScriptError/PluginNodeScriptResult桌面端执行 Node 脚本的配置、请求与错误模型含超时、内存限制、权限拒绝等错误码PluginAppState应用只读快照tasks/projects/tags/notes/taskRepeatCfgs/simpleCounters/globalConfigBatchUpdateRequest/BatchUpdateResult批处理接口支持 create/update/delete/reorder 组合操作与临时 ID 映射setSecret/getSecret/deleteSecret本地专用凭据存储IMAP 密码、API Token 等不会进入同步、导出或备份按设备隔离PluginIframeMessageType插件 iframe 与宿主的消息协议枚举API 调用、Hook 事件、对话框交互、生命周期 READY 等。此外src/issue-provider-types.ts 专门服务议题/日历类插件IssueProviderPluginDefinition定义了搜索议题、按 ID 获取、字段映射、双向同步、时间块timeBlock等接口PluginFormField支持 input/password/textarea/checkbox/select/multiSelect/link/oauthButton 等配置字段类型PluginFieldMapping负责 Super Productivity 任务字段与远端议题字段的双向映射。六、对核心维护者的开发流程6.1 更新 API 的六个步骤官方指南规定当为插件系统增加新功能时按以下顺序推进更新 src/types.ts添加新的接口/类型更新 src/index.ts导出新类型更新 README.md补充使用示例版本号提升npm version patch|minor|major重新构建并测试发布到 npm。6.2 与主项目同步类型长期目标是让 Super Productivity 主项目从本包导入类型而不是维护本地重复定义// Before: import { PluginManifest } from ./plugin-api.model; // After: import type { PluginManifest } from super-productivity/plugin-api;6.3 本地测试变更官方推荐用npm link进行本地联调# 1. 构建包 npm run build # 2. 在本目录链接全局 npm link # 3. 在测试项目中链接 npm link super-productivity/plugin-api # 4. 验证类型工作正常此外本包自身的 package.json 提供了npm run typechecktsc --noEmit用于纯类型校验prepublishOnly钩子会在发布前自动执行clean build。七、发布流程官方 PUBLISHING.md 给出了标准发布步骤# 1. 提升版本号patch | minor | major npm version patch # 2. 构建 npm run build # 3. 预检打包内容 npm pack --dry-run # 4. 发布稳定版 npm publish --access public # 或发布 beta 版 npm publish --tag beta --access public仓库中还提供了自动化脚本 publish.sh它会依次执行构建、npm pack --dry-run预检并在控制台提示两种发布命令。发布范围由publishConfig.access: public与files字段仅打包dist/**/*.js、dist/**/*.d.ts与README.md共同约束避免把源码目录误发布出去。八、最佳实践官方指南以五条最佳实践收尾可结合源码进一步展开始终使用 TypeScript 开发插件——类型定义本身就是官方文档借助 IDE 自动补全即可获知每个 API 的参数与返回值只导入类型避免运行时依赖——使用import type语法插件 API 包仅作为编译期类型来源不进入运行时依赖树遵循语义化版本发布插件——manifest.json中的version与minSupVersion共同决定插件与主程序版本的兼容关系发布前充分测试——包括类型编译、本地联调npm link以及在插件系统中实际运行验证为插件编写文档——清晰的 README 便于用户安装前理解插件的能力与权限诉求。九、延伸阅读插件开发快速入门packages/plugin-dev/QUICK_START.md插件国际化约定packages/plugin-dev/PLUGIN_I18N.md插件 API 类型定义src/types.ts 与 src/issue-provider-types.ts插件 API 使用说明与完整示例README.md发布与维护规范PUBLISHING.md主项目插件系统文档docs/plugin-development.md需要了解如何在 Super Productivity 中启用、配置和管理插件可继续查阅官方 Wiki 的插件管理指南。【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考