@gd-kirie/tray 0.11.0 → 0.13.0

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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # `@gd-kirie/tray`
2
2
 
3
- `@gd-kirie/tray` exposes system tray and native menu capabilities over an
4
- existing Kirie Eventa context.
3
+ `@gd-kirie/tray` adds system tray support to desktop Kirie applications. It
4
+ uses the application's existing Eventa context.
5
5
 
6
- Install the plugin explicitly in `kirie.config.ts`:
6
+ Add the plugin to `kirie.config.ts`:
7
7
 
8
8
  ```ts
9
9
  import tray from "@gd-kirie/tray/plugin";
@@ -15,34 +15,16 @@ export default defineKirieConfig({
15
15
  });
16
16
  ```
17
17
 
18
- Create the browser client from the same context used by the application:
18
+ Install the plugin dependencies:
19
19
 
20
- ```ts
21
- import { createContext } from "@gd-kirie/ipc-eventa";
22
- import { createTrayClient, trayMenuItemActivated } from "@gd-kirie/tray";
23
-
24
- const eventa = createContext();
25
- const tray = createTrayClient(eventa.context);
26
-
27
- await tray.configure({
28
- icon: "res://tray-template.svg",
29
- iconAsTemplate: true,
30
- tooltip: "Kirie",
31
- });
32
- await tray.setMenu([
33
- { id: "show", text: "Show Kirie" },
34
- { id: "enabled", text: "Enabled", type: "check", checked: true },
35
- ]);
36
- const stop = eventa.context.on(trayMenuItemActivated, ({ body }) => console.log(body?.id));
37
- await tray.updateItem({ id: "enabled", checked: false });
20
+ ```sh
21
+ pnpm kirie doctor --fix plugin:tray
38
22
  ```
39
23
 
40
- Browser icons are imported Godot resources referenced by `res://` paths. Use
41
- black artwork with transparency when `iconAsTemplate` is enabled. The option is
42
- supported only on macOS; other platforms reject `true`. See Apple's
43
- [`NSImage.isTemplate`](https://developer.apple.com/documentation/appkit/nsimage/istemplate)
44
- documentation for the native rendering behavior.
24
+ This command installs `addons/kirie_tray` and the `GdKirie.Tray` NuGet host.
25
+ The npm package bundles the desktop GDExtension libraries. Godot selects the
26
+ library for the current platform and includes it in application exports.
27
+ macOS, Windows, and Linux support x64 and Arm64. Linux requires a
28
+ StatusNotifierItem host.
45
29
 
46
- Menu types are `item`, `check`, `radio`, `multistate`, `separator`, and
47
- `submenu`. IDs must be non-empty and unique across the menu tree. The tray
48
- survives browser reloads and is destroyed explicitly or with its C# host.
30
+ See the [`tray` example](../../examples/tray/README.md) for a complete setup.
File without changes
@@ -0,0 +1,11 @@
1
+ [configuration]
2
+ entry_symbol = "gdext_rust_init"
3
+ compatibility_minimum = "4.7"
4
+
5
+ [libraries]
6
+ macos.arm64 = "./bin/osx-arm64/libkirie_tray_native.dylib"
7
+ macos.x86_64 = "./bin/osx-x64/libkirie_tray_native.dylib"
8
+ linux.arm64 = "./bin/linux-arm64/libkirie_tray_native.so"
9
+ linux.x86_64 = "./bin/linux-x64/libkirie_tray_native.so"
10
+ windows.arm64 = "./bin/win-arm64/kirie_tray_native.dll"
11
+ windows.x86_64 = "./bin/win-x64/kirie_tray_native.dll"
@@ -0,0 +1,5 @@
1
+ [plugin]
2
+ name="Kirie Tray"
3
+ description="Native Tray GDExtension"
4
+ author="Moeru AI"
5
+ version="0.13.0"
package/dist/index.d.ts CHANGED
@@ -2,42 +2,39 @@ import { InboundEventa } from "@moeru/eventa";
2
2
  import { KirieEventaContext } from "@gd-kirie/ipc-eventa";
3
3
 
4
4
  //#region src/index.d.ts
5
- type TrayMenuItemType = "item" | "check" | "radio" | "multistate" | "separator" | "submenu";
6
- interface TrayConfiguration {
5
+ interface TrayIcon {
7
6
  icon: string;
8
- /** Render the icon as a macOS template image. Non-macOS hosts reject `true`. */
9
7
  iconAsTemplate?: boolean;
10
- tooltip?: string;
11
- visible?: boolean;
12
8
  }
13
- interface TrayMenuItem {
9
+ type TrayMenuItem = {
10
+ type: "item";
14
11
  id: string;
15
12
  text: string;
16
- type?: TrayMenuItemType;
17
- icon?: string;
18
- accelerator?: number;
19
- disabled?: boolean;
20
- checked?: boolean;
21
- state?: number;
22
- maxStates?: number;
23
- tooltip?: string;
24
- indent?: number;
25
- children?: TrayMenuItem[];
26
- }
27
- interface TrayMenuItemUpdate extends Omit<Partial<TrayMenuItem>, "id" | "type" | "children"> {
13
+ enabled?: boolean;
14
+ } | {
15
+ type: "check";
28
16
  id: string;
29
- clearIcon?: boolean;
30
- }
17
+ text: string;
18
+ enabled?: boolean;
19
+ checked?: boolean;
20
+ } | {
21
+ type: "submenu";
22
+ text: string;
23
+ enabled?: boolean;
24
+ children: TrayMenuItem[];
25
+ } | {
26
+ type: "separator";
27
+ };
31
28
  interface TrayClient {
32
- configure: (configuration: TrayConfiguration) => Promise<void>;
29
+ create: (icon: TrayIcon) => Promise<void>;
30
+ setIcon: (icon: TrayIcon) => Promise<void>;
33
31
  setMenu: (items: TrayMenuItem[]) => Promise<void>;
34
- updateItem: (update: TrayMenuItemUpdate) => Promise<void>;
32
+ setTooltip: (tooltip: string | null) => Promise<void>;
33
+ setVisible: (visible: boolean) => Promise<void>;
35
34
  destroy: () => Promise<void>;
36
35
  }
37
- declare const trayMenuItemActivated: InboundEventa<{
38
- id: string;
39
- }>;
36
+ declare const trayMenuItemActivated: InboundEventa<string>;
40
37
  declare function createTrayClient(context: KirieEventaContext): TrayClient;
41
38
  //#endregion
42
- export { TrayClient, TrayConfiguration, TrayMenuItem, TrayMenuItemType, TrayMenuItemUpdate, createTrayClient, trayMenuItemActivated };
39
+ export { TrayClient, TrayIcon, TrayMenuItem, createTrayClient, trayMenuItemActivated };
43
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;KAIY,gBAAA;AAAA,UAEK,iBAAA;EACf,IAAA;EAHU;EAKV,cAAA;EACA,OAAA;EACA,OAAA;AAAA;AAAA,UAGe,YAAA;EACf,EAAA;EACA,IAAA;EACA,IAAA,GAAO,gBAAA;EACP,IAAA;EACA,WAAA;EACA,QAAA;EACA,OAAA;EACA,KAAA;EACA,SAAA;EACA,OAAA;EACA,MAAA;EACA,QAAA,GAAW,YAAA;AAAA;AAAA,UAGI,kBAAA,SAA2B,IAAA,CAAK,OAAA,CAAQ,YAAA;EACvD,EAAA;EACA,SAAA;AAAA;AAAA,UAGe,UAAA;EACf,SAAA,GAAY,aAAA,EAAe,iBAAA,KAAsB,OAAA;EACjD,OAAA,GAAU,KAAA,EAAO,YAAA,OAAmB,OAAA;EACpC,UAAA,GAAa,MAAA,EAAQ,kBAAA,KAAuB,OAAA;EAC5C,OAAA,QAAe,OAAA;AAAA;AAAA,cAYJ,qBAAA,EAAuB,aAAA;EAAgB,EAAA;AAAA;AAAA,iBAIpC,gBAAA,CAAiB,OAAA,EAAS,kBAAA,GAAqB,UAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;UAIiB,QAAA;EACf,IAAA;EACA,cAAA;AAAA;AAAA,KAGU,YAAA;EACN,IAAA;EAAc,EAAA;EAAY,IAAA;EAAc,OAAA;AAAA;EAC1C,IAAA;EAAe,EAAA;EAAY,IAAA;EAAc,OAAA;EAAmB,OAAA;AAAA;EAC5D,IAAA;EAAiB,IAAA;EAAc,OAAA;EAAmB,QAAA,EAAU,YAAA;AAAA;EAC5D,IAAA;AAAA;AAAA,UAEa,UAAA;EACf,MAAA,GAAS,IAAA,EAAM,QAAA,KAAa,OAAA;EAC5B,OAAA,GAAU,IAAA,EAAM,QAAA,KAAa,OAAA;EAC7B,OAAA,GAAU,KAAA,EAAO,YAAA,OAAmB,OAAA;EACpC,UAAA,GAAa,OAAA,oBAA2B,OAAA;EACxC,UAAA,GAAa,OAAA,cAAqB,OAAA;EAClC,OAAA,QAAe,OAAA;AAAA;AAAA,cAcJ,qBAAA,EAAuB,aAAA;AAAA,iBAIpB,gBAAA,CAAiB,OAAA,EAAS,kBAAA,GAAqB,UAAA"}
package/dist/index.js CHANGED
@@ -1,23 +1,31 @@
1
1
  import { defineInboundEventa, defineInvokeEventa, defineInvokes } from "@moeru/eventa";
2
2
  //#region src/index.ts
3
3
  const events = {
4
- configure: defineInvokeEventa("kirie:tray:configure"),
4
+ create: defineInvokeEventa("kirie:tray:create"),
5
+ setIcon: defineInvokeEventa("kirie:tray:set-icon"),
5
6
  setMenu: defineInvokeEventa("kirie:tray:set-menu"),
6
- updateItem: defineInvokeEventa("kirie:tray:update-item"),
7
+ setTooltip: defineInvokeEventa("kirie:tray:set-tooltip"),
8
+ setVisible: defineInvokeEventa("kirie:tray:set-visible"),
7
9
  destroy: defineInvokeEventa("kirie:tray:destroy")
8
10
  };
9
11
  const trayMenuItemActivated = defineInboundEventa("kirie:tray:menu-item-activated");
10
12
  function createTrayClient(context) {
11
13
  const invokes = defineInvokes(context, events);
12
14
  return {
13
- async configure(configuration) {
14
- await invokes.configure(configuration);
15
+ async create(icon) {
16
+ await invokes.create(icon);
17
+ },
18
+ async setIcon(icon) {
19
+ await invokes.setIcon(icon);
15
20
  },
16
21
  async setMenu(items) {
17
22
  await invokes.setMenu(items);
18
23
  },
19
- async updateItem(update) {
20
- await invokes.updateItem(update);
24
+ async setTooltip(tooltip) {
25
+ await invokes.setTooltip(tooltip);
26
+ },
27
+ async setVisible(visible) {
28
+ await invokes.setVisible(visible);
21
29
  },
22
30
  async destroy() {
23
31
  await invokes.destroy({});
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { KirieEventaContext } from \"@gd-kirie/ipc-eventa\";\nimport type { InboundEventa } from \"@moeru/eventa\";\nimport { defineInboundEventa, defineInvokeEventa, defineInvokes } from \"@moeru/eventa\";\n\nexport type TrayMenuItemType = \"item\" | \"check\" | \"radio\" | \"multistate\" | \"separator\" | \"submenu\";\n\nexport interface TrayConfiguration {\n icon: string;\n /** Render the icon as a macOS template image. Non-macOS hosts reject `true`. */\n iconAsTemplate?: boolean;\n tooltip?: string;\n visible?: boolean;\n}\n\nexport interface TrayMenuItem {\n id: string;\n text: string;\n type?: TrayMenuItemType;\n icon?: string;\n accelerator?: number;\n disabled?: boolean;\n checked?: boolean;\n state?: number;\n maxStates?: number;\n tooltip?: string;\n indent?: number;\n children?: TrayMenuItem[];\n}\n\nexport interface TrayMenuItemUpdate extends Omit<Partial<TrayMenuItem>, \"id\" | \"type\" | \"children\"> {\n id: string;\n clearIcon?: boolean;\n}\n\nexport interface TrayClient {\n configure: (configuration: TrayConfiguration) => Promise<void>;\n setMenu: (items: TrayMenuItem[]) => Promise<void>;\n updateItem: (update: TrayMenuItemUpdate) => Promise<void>;\n destroy: () => Promise<void>;\n}\n\ntype EmptyPayload = Record<string, never>;\n\nconst events = {\n configure: defineInvokeEventa<EmptyPayload, TrayConfiguration>(\"kirie:tray:configure\"),\n setMenu: defineInvokeEventa<EmptyPayload, TrayMenuItem[]>(\"kirie:tray:set-menu\"),\n updateItem: defineInvokeEventa<EmptyPayload, TrayMenuItemUpdate>(\"kirie:tray:update-item\"),\n destroy: defineInvokeEventa<EmptyPayload, EmptyPayload>(\"kirie:tray:destroy\"),\n};\n\nexport const trayMenuItemActivated: InboundEventa<{ id: string }> = defineInboundEventa(\n \"kirie:tray:menu-item-activated\",\n);\n\nexport function createTrayClient(context: KirieEventaContext): TrayClient {\n const invokes = defineInvokes(context, events);\n\n return {\n async configure(configuration) {\n await invokes.configure(configuration);\n },\n async setMenu(items) {\n await invokes.setMenu(items);\n },\n async updateItem(update) {\n await invokes.updateItem(update);\n },\n async destroy() {\n await invokes.destroy({});\n },\n };\n}\n"],"mappings":";;AA2CA,MAAM,SAAS;CACb,WAAW,mBAAoD,sBAAsB;CACrF,SAAS,mBAAiD,qBAAqB;CAC/E,YAAY,mBAAqD,wBAAwB;CACzF,SAAS,mBAA+C,oBAAoB;AAC9E;AAEA,MAAa,wBAAuD,oBAClE,gCACF;AAEA,SAAgB,iBAAiB,SAAyC;CACxE,MAAM,UAAU,cAAc,SAAS,MAAM;CAE7C,OAAO;EACL,MAAM,UAAU,eAAe;GAC7B,MAAM,QAAQ,UAAU,aAAa;EACvC;EACA,MAAM,QAAQ,OAAO;GACnB,MAAM,QAAQ,QAAQ,KAAK;EAC7B;EACA,MAAM,WAAW,QAAQ;GACvB,MAAM,QAAQ,WAAW,MAAM;EACjC;EACA,MAAM,UAAU;GACd,MAAM,QAAQ,QAAQ,CAAC,CAAC;EAC1B;CACF;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { KirieEventaContext } from \"@gd-kirie/ipc-eventa\";\nimport type { InboundEventa } from \"@moeru/eventa\";\nimport { defineInboundEventa, defineInvokeEventa, defineInvokes } from \"@moeru/eventa\";\n\nexport interface TrayIcon {\n icon: string;\n iconAsTemplate?: boolean;\n}\n\nexport type TrayMenuItem =\n | { type: \"item\"; id: string; text: string; enabled?: boolean } |\n { type: \"check\"; id: string; text: string; enabled?: boolean; checked?: boolean } |\n { type: \"submenu\"; text: string; enabled?: boolean; children: TrayMenuItem[] } |\n { type: \"separator\" };\n\nexport interface TrayClient {\n create: (icon: TrayIcon) => Promise<void>;\n setIcon: (icon: TrayIcon) => Promise<void>;\n setMenu: (items: TrayMenuItem[]) => Promise<void>;\n setTooltip: (tooltip: string | null) => Promise<void>;\n setVisible: (visible: boolean) => Promise<void>;\n destroy: () => Promise<void>;\n}\n\ntype EmptyPayload = Record<string, never>;\n\nconst events = {\n create: defineInvokeEventa<EmptyPayload, TrayIcon>(\"kirie:tray:create\"),\n setIcon: defineInvokeEventa<EmptyPayload, TrayIcon>(\"kirie:tray:set-icon\"),\n setMenu: defineInvokeEventa<EmptyPayload, TrayMenuItem[]>(\"kirie:tray:set-menu\"),\n setTooltip: defineInvokeEventa<EmptyPayload, string | null>(\"kirie:tray:set-tooltip\"),\n setVisible: defineInvokeEventa<EmptyPayload, boolean>(\"kirie:tray:set-visible\"),\n destroy: defineInvokeEventa<EmptyPayload, EmptyPayload>(\"kirie:tray:destroy\"),\n};\n\nexport const trayMenuItemActivated: InboundEventa<string> = defineInboundEventa(\n \"kirie:tray:menu-item-activated\",\n);\n\nexport function createTrayClient(context: KirieEventaContext): TrayClient {\n const invokes = defineInvokes(context, events);\n\n return {\n async create(icon) {\n await invokes.create(icon);\n },\n async setIcon(icon) {\n await invokes.setIcon(icon);\n },\n async setMenu(items) {\n await invokes.setMenu(items);\n },\n async setTooltip(tooltip) {\n await invokes.setTooltip(tooltip);\n },\n async setVisible(visible) {\n await invokes.setVisible(visible);\n },\n async destroy() {\n await invokes.destroy({});\n },\n };\n}\n"],"mappings":";;AA0BA,MAAM,SAAS;CACb,QAAQ,mBAA2C,mBAAmB;CACtE,SAAS,mBAA2C,qBAAqB;CACzE,SAAS,mBAAiD,qBAAqB;CAC/E,YAAY,mBAAgD,wBAAwB;CACpF,YAAY,mBAA0C,wBAAwB;CAC9E,SAAS,mBAA+C,oBAAoB;AAC9E;AAEA,MAAa,wBAA+C,oBAC1D,gCACF;AAEA,SAAgB,iBAAiB,SAAyC;CACxE,MAAM,UAAU,cAAc,SAAS,MAAM;CAE7C,OAAO;EACL,MAAM,OAAO,MAAM;GACjB,MAAM,QAAQ,OAAO,IAAI;EAC3B;EACA,MAAM,QAAQ,MAAM;GAClB,MAAM,QAAQ,QAAQ,IAAI;EAC5B;EACA,MAAM,QAAQ,OAAO;GACnB,MAAM,QAAQ,QAAQ,KAAK;EAC7B;EACA,MAAM,WAAW,SAAS;GACxB,MAAM,QAAQ,WAAW,OAAO;EAClC;EACA,MAAM,WAAW,SAAS;GACxB,MAAM,QAAQ,WAAW,OAAO;EAClC;EACA,MAAM,UAAU;GACd,MAAM,QAAQ,QAAQ,CAAC,CAAC;EAC1B;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;cAMA,QAAA,EAQM,WAAA"}
1
+ {"version":3,"file":"plugin.d.ts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;cAQA,QAAA,EAmBM,WAAA"}
package/dist/plugin.js CHANGED
@@ -1,11 +1,23 @@
1
1
  import { defineKiriePlugin } from "kirie/plugin";
2
+ //#region package.json
3
+ var version = "0.13.0";
2
4
  //#endregion
3
5
  //#region src/plugin.ts
6
+ const bundledAddonUrl = new URL("../addon/kirie_tray", import.meta.url).href;
4
7
  var plugin_default = defineKiriePlugin({
5
8
  id: "tray",
6
9
  dotnetPackages: [{
7
10
  id: "GdKirie.Tray",
8
- version: "0.11.0"
11
+ version
12
+ }],
13
+ godotAddons: [{
14
+ id: "kirie-tray",
15
+ path: "addons/kirie_tray",
16
+ source: {
17
+ type: "bundled",
18
+ url: bundledAddonUrl
19
+ },
20
+ version
9
21
  }]
10
22
  });
11
23
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":["packageJson.version"],"sources":["../package.json","../src/plugin.ts"],"sourcesContent":["","import type { KiriePlugin } from \"kirie/plugin\";\nimport { defineKiriePlugin } from \"kirie/plugin\";\nimport packageJson from \"../package.json\" with { type: \"json\" };\n\n// ADR-0012: Tray is installed explicitly and owns its .NET host dependency.\n// See docs/decisions/0012-extract-system-tray-into-a-kirie-plugin.md.\nexport default defineKiriePlugin({\n id: \"tray\",\n dotnetPackages: [\n {\n id: \"GdKirie.Tray\",\n version: packageJson.version,\n },\n ],\n}) as KiriePlugin;\n"],"mappings":";;;ACMA,IAAA,iBAAe,kBAAkB;CAC/B,IAAI;CACJ,gBAAgB,CACd;EACE,IAAI;EACKA;CACX,CACF;AACF,CAAC"}
1
+ {"version":3,"file":"plugin.js","names":["packageJson.version"],"sources":["../package.json","../src/plugin.ts"],"sourcesContent":["","import type { KiriePlugin } from \"kirie/plugin\";\nimport { defineKiriePlugin } from \"kirie/plugin\";\nimport packageJson from \"../package.json\" with { type: \"json\" };\n\nconst bundledAddonUrl = new URL(\"../addon/kirie_tray\", import.meta.url).href;\n\n// ADR-0015: Godot loads and exports the optional Tray native library.\n// See docs/decisions/0015-load-tray-through-a-gdextension.md.\nexport default defineKiriePlugin({\n id: \"tray\",\n dotnetPackages: [\n {\n id: \"GdKirie.Tray\",\n version: packageJson.version,\n },\n ],\n godotAddons: [\n {\n id: \"kirie-tray\",\n path: \"addons/kirie_tray\",\n source: {\n type: \"bundled\",\n url: bundledAddonUrl,\n },\n version: packageJson.version,\n },\n ],\n}) as KiriePlugin;\n"],"mappings":";;;;;ACIA,MAAM,kBAAkB,IAAI,IAAI,uBAAuB,OAAO,KAAK,GAAG,CAAC,CAAC;AAIxE,IAAA,iBAAe,kBAAkB;CAC/B,IAAI;CACJ,gBAAgB,CACd;EACE,IAAI;EACKA;CACX,CACF;CACA,aAAa,CACX;EACE,IAAI;EACJ,MAAM;EACN,QAAQ;GACN,MAAM;GACN,KAAK;EACP;EACSA;CACX,CACF;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gd-kirie/tray",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,14 +20,15 @@
20
20
  }
21
21
  },
22
22
  "files": [
23
+ "addon",
23
24
  "dist"
24
25
  ],
25
26
  "dependencies": {
26
- "@gd-kirie/ipc-eventa": "0.11.0",
27
+ "@gd-kirie/ipc-eventa": "0.13.0",
27
28
  "@moeru/eventa": "^1.0.2"
28
29
  },
29
30
  "peerDependencies": {
30
- "kirie": "^0.11.0"
31
+ "kirie": "^0.13.0"
31
32
  },
32
33
  "devDependencies": {
33
34
  "tsdown": "^0.22.2",
@@ -39,7 +40,7 @@
39
40
  "registry": "https://registry.npmjs.org"
40
41
  },
41
42
  "scripts": {
42
- "build": "tsdown",
43
+ "build": "tsdown && node scripts/package-addon.ts",
43
44
  "test:run": "vitest run",
44
45
  "typecheck": "tsc -p tsconfig.json --noEmit"
45
46
  }