@open-pets/plugin-sdk 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # @open-pets/plugin-sdk
2
+
3
+ Type definitions for building [OpenPets](https://openpets.dev) desktop pet plugins.
4
+
5
+ This package is **types only**. There is no runtime to import — the OpenPets
6
+ desktop app injects the `OpenPetsPlugin` global into your plugin's sandbox and
7
+ passes your `start(ctx)` handler the SDK. Installing this package gives your
8
+ editor autocomplete and type-checking; it never ships in your plugin.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm i -D @open-pets/plugin-sdk
14
+ ```
15
+
16
+ ## Use
17
+
18
+ A plugin is a single browser-style JavaScript file. Reference the types for
19
+ IntelliSense:
20
+
21
+ ```js
22
+ /// <reference types="@open-pets/plugin-sdk" />
23
+
24
+ OpenPetsPlugin.register({
25
+ async start(ctx) {
26
+ await ctx.pet.speak("Hello!")
27
+ await ctx.pet.react("waving")
28
+ },
29
+ })
30
+ ```
31
+
32
+ Or, in TypeScript, import the contract directly:
33
+
34
+ ```ts
35
+ import type { OpenPetsContext, OpenPetsPluginDefinition } from "@open-pets/plugin-sdk"
36
+ ```
37
+
38
+ ## Docs
39
+
40
+ - SDK guide: https://openpets.dev/sdk
41
+ - Full reference: https://openpets.dev/docs/plugin-sdk
42
+ - Example plugins: https://github.com/alvinunreal/openpets/tree/main/plugins/official
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Contract test for @open-pets/plugin-sdk.
3
+ *
4
+ * This file does double duty: it only compiles if the exported types match the
5
+ * real SDK surface, and at runtime it exercises a sample plugin against a mock
6
+ * context. The `createMockContext` helper below is the recommended pattern for
7
+ * unit-testing a plugin's `start` handler without the desktop app.
8
+ */
9
+ import type { OpenPetsContext, OpenPetsStatus } from "./index.js";
10
+ interface MockCalls {
11
+ speak: string[];
12
+ react: string[];
13
+ status: OpenPetsStatus[];
14
+ storage: Map<string, unknown>;
15
+ schedules: Map<string, () => void | Promise<void>>;
16
+ commands: Map<string, (values?: Record<string, unknown>) => void | Promise<void>>;
17
+ }
18
+ /** Build a recording {@link OpenPetsContext} for tests. Copy this into your plugin's tests. */
19
+ export declare function createMockContext(config?: Record<string, unknown>): {
20
+ ctx: OpenPetsContext;
21
+ calls: MockCalls;
22
+ };
23
+ export {};
24
+ //# sourceMappingURL=check-plugin-sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-plugin-sdk.d.ts","sourceRoot":"","sources":["../src/check-plugin-sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EACV,eAAe,EAEf,cAAc,EACf,MAAM,YAAY,CAAC;AAkBpB,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACnF;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG;IACvE,GAAG,EAAE,eAAe,CAAC;IACrB,KAAK,EAAE,SAAS,CAAC;CAClB,CAoDA"}
@@ -0,0 +1,97 @@
1
+ const assert = {
2
+ ok(value, message) {
3
+ if (!value)
4
+ throw new Error(message ?? "Assertion failed.");
5
+ },
6
+ equal(actual, expected, message) {
7
+ if (actual !== expected)
8
+ throw new Error(message ?? `Expected ${String(expected)}, got ${String(actual)}.`);
9
+ },
10
+ deepEqual(actual, expected, message) {
11
+ if (JSON.stringify(actual) !== JSON.stringify(expected)) {
12
+ throw new Error(message ?? `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}.`);
13
+ }
14
+ },
15
+ };
16
+ /** Build a recording {@link OpenPetsContext} for tests. Copy this into your plugin's tests. */
17
+ export function createMockContext(config = {}) {
18
+ const calls = {
19
+ speak: [],
20
+ react: [],
21
+ status: [],
22
+ storage: new Map(),
23
+ schedules: new Map(),
24
+ commands: new Map(),
25
+ };
26
+ const ctx = {
27
+ pet: {
28
+ speak: async (message) => void calls.speak.push(message),
29
+ react: async (reaction) => void calls.react.push(reaction),
30
+ moveBy: async () => undefined,
31
+ wander: async () => undefined,
32
+ moveToHome: async () => undefined,
33
+ },
34
+ schedule: {
35
+ once: async (id, _delayMs, handler) => void calls.schedules.set(id, handler),
36
+ every: async (id, _intervalMs, handler) => void calls.schedules.set(id, handler),
37
+ daily: async (id, _spec, handler) => void calls.schedules.set(id, handler),
38
+ cancel: async (id) => void calls.schedules.delete(id),
39
+ cancelAll: async () => void calls.schedules.clear(),
40
+ },
41
+ storage: {
42
+ get: async (key) => calls.storage.get(key),
43
+ set: async (key, value) => void calls.storage.set(key, value),
44
+ delete: async (key) => void calls.storage.delete(key),
45
+ },
46
+ config: {
47
+ get: async () => config,
48
+ onChange: () => () => undefined,
49
+ },
50
+ commands: {
51
+ register: async (command, handler) => void calls.commands.set(command.id, handler),
52
+ unregister: async (id) => void calls.commands.delete(id),
53
+ },
54
+ status: {
55
+ set: async (status) => void calls.status.push(status),
56
+ clear: async () => undefined,
57
+ },
58
+ http: {
59
+ fetch: async () => ({ status: 200, ok: true, headers: {}, text: "" }),
60
+ },
61
+ log: {
62
+ debug: async () => undefined,
63
+ info: async () => undefined,
64
+ warn: async () => undefined,
65
+ error: async () => undefined,
66
+ },
67
+ };
68
+ return { ctx, calls };
69
+ }
70
+ // A representative plugin, typed against the public contract.
71
+ const plugin = {
72
+ async start(ctx) {
73
+ await ctx.status.set({ text: "Ready", tone: "info" });
74
+ await ctx.pet.speak("Hello!");
75
+ await ctx.pet.react("waving");
76
+ await ctx.schedule.every("tick", 60_000, async () => {
77
+ await ctx.storage.set("lastTick", "now");
78
+ });
79
+ await ctx.commands.register({ id: "greet", title: "Greet" }, async () => {
80
+ await ctx.pet.speak("Hi again!");
81
+ });
82
+ },
83
+ };
84
+ const { ctx, calls } = createMockContext();
85
+ await plugin.start(ctx);
86
+ assert.deepEqual(calls.speak, ["Hello!"]);
87
+ assert.deepEqual(calls.react, ["waving"]);
88
+ assert.equal(calls.status.length, 1);
89
+ assert.ok(calls.schedules.has("tick"));
90
+ assert.ok(calls.commands.has("greet"));
91
+ // Registered callbacks behave as expected.
92
+ await calls.schedules.get("tick")?.();
93
+ assert.equal(calls.storage.get("lastTick"), "now");
94
+ await calls.commands.get("greet")?.();
95
+ assert.deepEqual(calls.speak, ["Hello!", "Hi again!"]);
96
+ console.log("Plugin SDK contract tests passed.");
97
+ //# sourceMappingURL=check-plugin-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-plugin-sdk.js","sourceRoot":"","sources":["../src/check-plugin-sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Type definitions for OpenPets plugins.
3
+ *
4
+ * This package ships **types only**. There is no runtime to import — the
5
+ * OpenPets desktop app injects the `OpenPetsPlugin` global into the plugin
6
+ * sandbox and passes your `start(ctx)` handler an {@link OpenPetsContext}.
7
+ *
8
+ * In a plain JavaScript plugin, reference these types for editor IntelliSense:
9
+ *
10
+ * ```js
11
+ * /// <reference types="@open-pets/plugin-sdk" />
12
+ *
13
+ * OpenPetsPlugin.register({
14
+ * async start(ctx) {
15
+ * await ctx.pet.speak("Hello!")
16
+ * },
17
+ * })
18
+ * ```
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ /** Capabilities a plugin can request in its manifest's `permissions` array. */
23
+ export type OpenPetsPermission = "pet:speak" | "pet:reaction" | "pet:move" | "schedule" | "storage" | "status" | "commands" | "network";
24
+ /**
25
+ * Reaction name passed to {@link OpenPetsPetApi.react}. Common values are
26
+ * listed for autocomplete; any string the host accepts is allowed.
27
+ */
28
+ export type OpenPetsReaction = "idle" | "thinking" | "working" | "editing" | "running" | "testing" | "waiting" | "waving" | "success" | "error" | "celebrating" | (string & {});
29
+ /** Tone shown alongside a plugin's status line in the Plugins window. */
30
+ export type OpenPetsStatusTone = "info" | "success" | "warning" | "error";
31
+ /** A status line, either a bare string or text plus a {@link OpenPetsStatusTone}. */
32
+ export type OpenPetsStatus = string | {
33
+ text: string;
34
+ tone?: OpenPetsStatusTone;
35
+ };
36
+ /** A single field in a command's input form. */
37
+ export interface OpenPetsCommandFormField {
38
+ /** Identifier for this field; the submitted value is keyed by it. */
39
+ id: string;
40
+ type: "text" | "textarea" | "number";
41
+ label: string;
42
+ default?: string | number;
43
+ /** Minimum value (number fields only). */
44
+ min?: number;
45
+ /** Maximum value (number fields only). */
46
+ max?: number;
47
+ /** Maximum length (text/textarea fields only). */
48
+ maxLength?: number;
49
+ required?: boolean;
50
+ }
51
+ /** Optional input form attached to a command. */
52
+ export interface OpenPetsCommandForm {
53
+ fields: OpenPetsCommandFormField[];
54
+ submitLabel?: string;
55
+ }
56
+ /** A right-click pet action registered via {@link OpenPetsCommandsApi.register}. */
57
+ export interface OpenPetsCommand {
58
+ /** Short, stable id (`[A-Za-z0-9._:-]`, 1–64 chars). */
59
+ id: string;
60
+ title: string;
61
+ description?: string;
62
+ /** When present, the host opens a dialog and passes validated values to the handler. */
63
+ form?: OpenPetsCommandForm;
64
+ }
65
+ /** A daily schedule time, optionally restricted to specific weekdays. */
66
+ export type OpenPetsDailySpec = string | {
67
+ time: string;
68
+ days?: number[];
69
+ };
70
+ /** Options for {@link OpenPetsPetApi.moveBy}. */
71
+ export interface OpenPetsMoveByOptions {
72
+ x: number;
73
+ y: number;
74
+ durationMs?: number;
75
+ }
76
+ /** Options for {@link OpenPetsPetApi.wander}. */
77
+ export interface OpenPetsWanderOptions {
78
+ distance?: number;
79
+ durationMs?: number;
80
+ }
81
+ /** Options for {@link OpenPetsHttpApi.fetch}. GET-only by design. */
82
+ export interface OpenPetsHttpOptions {
83
+ method?: "GET";
84
+ headers?: Record<string, string>;
85
+ timeoutMs?: number;
86
+ }
87
+ /** Response returned by {@link OpenPetsHttpApi.fetch}. */
88
+ export interface OpenPetsHttpResponse {
89
+ status: number;
90
+ ok: boolean;
91
+ headers: Record<string, string>;
92
+ text: string;
93
+ json?: unknown;
94
+ }
95
+ /** Make the default pet speak, react, or move. */
96
+ export interface OpenPetsPetApi {
97
+ /** Requires `pet:speak`. Messages are capped at 140 chars and content-filtered. */
98
+ speak(message: string): Promise<void>;
99
+ /** Requires `pet:reaction`. */
100
+ react(reaction: OpenPetsReaction): Promise<void>;
101
+ /** Requires `pet:move`. Movement is bounded to the work area. */
102
+ moveBy(options: OpenPetsMoveByOptions): Promise<void>;
103
+ /** Requires `pet:move`. */
104
+ wander(options?: OpenPetsWanderOptions): Promise<void>;
105
+ /** Requires `pet:move`. */
106
+ moveToHome(): Promise<void>;
107
+ }
108
+ /** A callback fired by a schedule. */
109
+ export type OpenPetsScheduleHandler = () => void | Promise<void>;
110
+ /** Run callbacks once, on an interval, or daily. Requires `schedule`. */
111
+ export interface OpenPetsScheduleApi {
112
+ /** Fire once after `delayMs`. */
113
+ once(id: string, delayMs: number, handler: OpenPetsScheduleHandler): Promise<void>;
114
+ /** Fire repeatedly every `intervalMs` (a minimum interval is enforced). */
115
+ every(id: string, intervalMs: number, handler: OpenPetsScheduleHandler): Promise<void>;
116
+ /** Fire daily at `HH:mm`, optionally only on the given weekdays (0–6, Sunday = 0). */
117
+ daily(id: string, spec: OpenPetsDailySpec, handler: OpenPetsScheduleHandler): Promise<void>;
118
+ cancel(id: string): Promise<void>;
119
+ cancelAll(): Promise<void>;
120
+ }
121
+ /** Persist small per-plugin state across restarts. Requires `storage`. */
122
+ export interface OpenPetsStorageApi {
123
+ get<T = unknown>(key: string): Promise<T | undefined>;
124
+ set(key: string, value: unknown): Promise<void>;
125
+ delete(key: string): Promise<void>;
126
+ }
127
+ /** Read user configuration and react to changes. Always available. */
128
+ export interface OpenPetsConfigApi {
129
+ get<T = Record<string, unknown>>(): Promise<T>;
130
+ /** Subscribe to config changes. Returns an unsubscribe function. */
131
+ onChange<T = Record<string, unknown>>(handler: (config: T) => void | Promise<void>): () => void;
132
+ }
133
+ /** Handler invoked when a command runs, with validated form values when present. */
134
+ export type OpenPetsCommandHandler = (values?: Record<string, unknown>) => void | Promise<void>;
135
+ /** Register right-click pet actions. Requires `commands`. */
136
+ export interface OpenPetsCommandsApi {
137
+ register(command: OpenPetsCommand, handler: OpenPetsCommandHandler): Promise<void>;
138
+ unregister(id: string): Promise<void>;
139
+ }
140
+ /** Show a short status line in the Plugins window. Requires `status`. */
141
+ export interface OpenPetsStatusApi {
142
+ set(status: OpenPetsStatus): Promise<void>;
143
+ clear(): Promise<void>;
144
+ }
145
+ /** Fetch approved HTTPS hosts through the OpenPets proxy. Requires `network`. */
146
+ export interface OpenPetsHttpApi {
147
+ fetch(url: string, options?: OpenPetsHttpOptions): Promise<OpenPetsHttpResponse>;
148
+ }
149
+ /** Write to the desktop app log under the `plugin` scope. Always available. */
150
+ export interface OpenPetsLogApi {
151
+ debug(...args: unknown[]): Promise<void>;
152
+ info(...args: unknown[]): Promise<void>;
153
+ warn(...args: unknown[]): Promise<void>;
154
+ error(...args: unknown[]): Promise<void>;
155
+ }
156
+ /**
157
+ * The capability object passed to {@link OpenPetsPluginDefinition.start}.
158
+ *
159
+ * Each namespace is only functional when the matching permission is approved
160
+ * in the manifest. `config` and `log` are always available.
161
+ */
162
+ export interface OpenPetsContext {
163
+ pet: OpenPetsPetApi;
164
+ schedule: OpenPetsScheduleApi;
165
+ storage: OpenPetsStorageApi;
166
+ config: OpenPetsConfigApi;
167
+ commands: OpenPetsCommandsApi;
168
+ status: OpenPetsStatusApi;
169
+ http: OpenPetsHttpApi;
170
+ log: OpenPetsLogApi;
171
+ }
172
+ /** The object you pass to {@link OpenPetsPluginApi.register}. */
173
+ export interface OpenPetsPluginDefinition {
174
+ /** Runs when the plugin is enabled or the app launches. */
175
+ start(ctx: OpenPetsContext): void | Promise<void>;
176
+ /** Optional cleanup. Schedules and commands are torn down for you. */
177
+ stop?(ctx?: OpenPetsContext): void | Promise<void>;
178
+ }
179
+ /** The injected global used to register a plugin. */
180
+ export interface OpenPetsPluginApi {
181
+ register(definition: OpenPetsPluginDefinition): void;
182
+ }
183
+ /**
184
+ * The signature of an exported `register` function — the testable plugin
185
+ * style used by the official plugins:
186
+ *
187
+ * ```ts
188
+ * export function register(OpenPetsPlugin: OpenPetsPluginApi) {
189
+ * OpenPetsPlugin.register({ async start(ctx) {} })
190
+ * }
191
+ * ```
192
+ */
193
+ export type OpenPetsPluginEntry = (api: OpenPetsPluginApi) => void | Promise<void>;
194
+ /** Field types supported by `configSchema` in the manifest. */
195
+ export type OpenPetsConfigFieldType = "text" | "textarea" | "number" | "boolean" | "select" | "time" | "list" | "multiselect";
196
+ declare global {
197
+ /**
198
+ * Injected by the OpenPets runtime. Call once at the top level of your
199
+ * entry file to register your plugin.
200
+ */
201
+ const OpenPetsPlugin: OpenPetsPluginApi;
202
+ }
203
+ export {};
204
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Type definitions for OpenPets plugins.
3
+ *
4
+ * This package ships **types only**. There is no runtime to import — the
5
+ * OpenPets desktop app injects the `OpenPetsPlugin` global into the plugin
6
+ * sandbox and passes your `start(ctx)` handler an {@link OpenPetsContext}.
7
+ *
8
+ * In a plain JavaScript plugin, reference these types for editor IntelliSense:
9
+ *
10
+ * ```js
11
+ * /// <reference types="@open-pets/plugin-sdk" />
12
+ *
13
+ * OpenPetsPlugin.register({
14
+ * async start(ctx) {
15
+ * await ctx.pet.speak("Hello!")
16
+ * },
17
+ * })
18
+ * ```
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ export {};
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@open-pets/plugin-sdk",
3
+ "version": "2.1.1",
4
+ "description": "Type definitions for building OpenPets desktop pet plugins. Types only — the OpenPets runtime injects the SDK implementation at load time.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/alvinunreal/openpets.git",
9
+ "directory": "packages/sdk"
10
+ },
11
+ "type": "module",
12
+ "main": "dist/index.js",
13
+ "types": "dist/index.d.ts",
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "keywords": [
21
+ "openpets",
22
+ "plugin",
23
+ "sdk",
24
+ "types",
25
+ "desktop-pet"
26
+ ],
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "default": "./dist/index.js"
31
+ }
32
+ },
33
+ "scripts": {
34
+ "test": "node dist/check-plugin-sdk.js",
35
+ "check": "pnpm typecheck && pnpm build && pnpm test",
36
+ "typecheck": "tsc --noEmit",
37
+ "build": "tsc"
38
+ },
39
+ "devDependencies": {
40
+ "typescript": "^6.0.3"
41
+ }
42
+ }