Kunkun
构建扩展

无头命令

无 UI 的后台命令——可手动触发、定时执行或事件驱动。

无头命令运行逻辑而不显示 UI:它们可手动触发、定时执行或由事件驱动,完成工作后可选地显示提示,然后退出。

模式运行时Node.js使用场景
worker-headlessWeb Worker简单的后台工作,无需文件系统
node-headlessNode.js / Deno系统操作、文件系统、外部 API

生命周期入口

使用 startKunkunHeadlessPlugin 注册你的命令。宿主驱动 init → onTrigger → destroy

// src/index.ts
import { startKunkunHeadlessPlugin, type TriggerContext } from "@kunkunsh/sdk/runtime";
import { showToast, Toast, LocalStorage } from "@kunkunsh/sdk";

startKunkunHeadlessPlugin({
  async init() {
    // 一次性设置:加载偏好设置、打开连接
  },
  async onTrigger(context: TriggerContext) {
    const raw = await LocalStorage.getItem("count");
    const count = (parseInt(raw ?? "0", 10) || 0) + 1;
    await LocalStorage.setItem("count", String(count));
    await showToast({ title: "已运行", message: `#${count}`, style: Toast.Style.Success });
  },
  async destroy() {
    // 清理:刷新、关闭连接
  },
});

context 描述了命令触发的原因(手动启动、定时任务或订阅的事件)。

构建

// build.ts — worker-headless
import { kunkunCommandPlugin } from "@kunkunsh/sdk/build";
import type { BunPlugin } from "bun";

await Bun.build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  target: "browser", format: "esm", minify: true,
  plugins: [kunkunCommandPlugin({ mode: "no-view" }) as BunPlugin],
});

对于 node-headless,使用 target: "node"outdir: "./dist/node"

Tarball 安装不会填充 node_modules——请将 JS 依赖打包到输出中。原生 .node 插件:打包加载程序 + 平台文件,或惰性加载。

清单

{
  "name": "sync",
  "title": "立即同步",
  "mode": "node-headless",
  "main": "dist/node/index.js",
  "permissions": [{ "permission": "fs-read", "allow": ["$HOME/**"] }, "notifications"]
}

调度与触发器

无头命令可以在用户未启动的情况下运行:

{ "name": "poll", "mode": "node-headless", "main": "dist/node/index.js", "interval": "5m" }
{ "name": "nightly", "mode": "node-headless", "main": "dist/node/index.js", "cron": "0 3 * * *" }
  • interval"30s" | "5m" | "1h" | "1d" 或秒数(数字)。
  • cron — 标准 cron 表达式。

你也可以在无头 worker 中通过事件 API 订阅系统事件(如 clipboard:change);sample-headless-worker 扩展演示了这一点。

Node 访问权限

node-headless 中你拥有 fsshellpathdialog 和网络访问权限:

import { fs, shell, path } from "@kunkunsh/sdk";

const home = await path.homeDir();
const entries = await fs.readDir(home);
const { stdout } = await shell.execute("echo", ["hi"]);

运行时选择

node-headless 按以下顺序选择运行时:Deno → Node v20+ → utilityProcess(自动)。强制指定:

{ "name": "deno-only", "mode": "node-headless", "main": "dist/node/index.js", "runtime": "deno" }

最佳实践

  1. 保持运行快速且幂等。
  2. 在适当的时候用 showToast 提供反馈。
  3. 捕获并报告错误——不要让定时任务静默失败。
  4. 使用 LocalStorage记录存储持久化计数器/缓存。

实际示例

  • sample-headless-node — cron 风格的 Node 任务
  • sample-headless-worker — 由 clipboard:change 触发的 worker

On this page