wox.plugin.nodejs/README.md
TypeScript type definitions and SDK for developing Wox plugins in TypeScript/JavaScript.
npm install wox-plugin
import { Plugin, Context, Query, Result, NewContext, WoxImage } from "wox-plugin"
class MyPlugin implements Plugin {
private api: PublicAPI
async init(ctx: Context, initParams: PluginInitParams): Promise<void> {
this.api = initParams.API
await this.api.Log(ctx, "Info", "MyPlugin initialized")
}
async query(ctx: Context, query: Query): Promise<Result[]> {
const results: Result[] = []
for (const item of this.getItems(query.Search)) {
results.push({
Title: item.name,
SubTitle: item.description,
Icon: { ImageType: "emoji", ImageData: "🔍" },
Score: 100,
Actions: [
{
Name: "Open",
Icon: { ImageType: "emoji", ImageData: "🔗" },
IsDefault: true,
Action: async (ctx, actionCtx) => {
await this.openItem(item)
}
}
]
})
}
return results
}
}
Every plugin must implement the Plugin interface:
interface Plugin {
init: (ctx: Context, initParams: PluginInitParams) => Promise<void>
query: (ctx: Context, query: Query) => Promise<Result[]>
}
INPUT (typing) or SELECTION (selected content)EXECUTE (immediate) or FORM (show form)Supported image types:
absolute: Absolute file pathrelative: Path relative to plugin directorybase64: Base64 encoded image with data URI prefix (data:image/png;base64,...)svg: SVG string contenturl: HTTP/HTTPS URLemoji: Emoji characterlottie: Lottie animation JSON// Emoji icon
{ ImageType: "emoji", ImageData: "🔍" }
// Base64 image
{ ImageType: "base64", ImageData: "data:image/png;base64,iVBORw0..." }
// Relative path
{ ImageType: "relative", ImageData: "./icons/icon.png" }
Methods for interacting with Wox:
showApp(), hideApp(), isVisible(), notify()changeQuery(), refreshQuery(), pushResults()getSetting(), saveSetting(), onSettingChanged()log()getTranslation()getUpdatableResult(), updateResult()llmStream()onMruRestore()onUnload(), onDeepLink()registerQueryCommands()copy()Actions are operations users can perform on results:
ResultAction({
name: "Copy",
icon: { ImageType: "emoji", ImageData: "📋" },
isDefault: true,
hotkey: "Ctrl+C",
action: async (ctx, actionCtx) => {
await this.copyToClipboard(actionCtx.contextData)
}
})
Define settings for your plugin:
const settings: PluginSettingDefinitionItem[] = [
{
Type: "textbox",
Value: {
Key: "apiKey",
Label: "API Key",
Suffix: "",
DefaultValue: "",
Tooltip: "Enter your API key",
MaxLines: 1,
Validators: [],
Style: {
PaddingLeft: 0,
PaddingTop: 0,
PaddingRight: 0,
PaddingBottom: 0,
Width: 0
}
} as PluginSettingValueTextBox,
DisabledInPlatforms: [],
IsPlatformSpecific: false
},
{
Type: "checkbox",
Value: {
Key: "enabled",
Label: "Enable Feature",
DefaultValue: "true",
Tooltip: "",
Style: {
PaddingLeft: 0,
PaddingTop: 0,
PaddingRight: 0,
PaddingBottom: 0,
Width: 0
}
} as PluginSettingValueCheckBox,
DisabledInPlatforms: [],
IsPlatformSpecific: false
}
]
Stream responses from AI models:
const conversations: AI.Conversation[] = [
{ Role: "system", Text: "You are a helpful assistant.", Timestamp: Date.now() },
{ Role: "user", Text: "Hello!", Timestamp: Date.now() }
]
await api.LLMStream(ctx, conversations, (data: AI.ChatStreamData) => {
if (data.Status === "streaming") {
console.log("Chunk:", data.Data)
} else if (data.Status === "finished") {
console.log("Complete:", data.Data)
}
})
Plugins must declare metadata in a plugin.json file:
{
"ID": "com.myplugin.example",
"Name": "My Plugin",
"Author": "Your Name",
"Version": "1.0.0",
"MinWoxVersion": "2.0.0",
"Runtime": "nodejs",
"Entry": "main.js",
"TriggerKeywords": ["my"],
"Description": "My awesome Wox plugin",
"Website": "https://github.com/user/myplugin",
"Icon": "https://example.com/icon.png"
}
plugin.query() with:
query.triggerKeyword = "my"query.command = ""query.search = "query"Result[]