opentray 0.0.0-alpha-20260605111358
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 +161 -0
- package/dist/cli.d.mts +23 -0
- package/dist/cli.d.mts.map +1 -0
- package/dist/cli.mjs +525 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-B_zxQOo5.mjs +111 -0
- package/dist/client-B_zxQOo5.mjs.map +1 -0
- package/dist/client-h6gZdeOk.d.mts +37 -0
- package/dist/client-h6gZdeOk.d.mts.map +1 -0
- package/dist/index.d.mts +23 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +21 -0
- package/dist/index.mjs.map +1 -0
- package/dist/local-broker-CEIHPBcK.mjs +504 -0
- package/dist/local-broker-CEIHPBcK.mjs.map +1 -0
- package/dist/node.d.mts +47 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +2 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# opentray
|
|
2
|
+
|
|
3
|
+
Developer-facing OpenTray package.
|
|
4
|
+
|
|
5
|
+
This is the package users install directly:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add opentray
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Role
|
|
12
|
+
|
|
13
|
+
- Resolve or auto-start the OpenTray broker.
|
|
14
|
+
- Expose `createSpace()`, default space resolution, and `createTray()`.
|
|
15
|
+
- Route extension packages through public OpenTray contracts.
|
|
16
|
+
- Resolve per-platform optional binary packages.
|
|
17
|
+
|
|
18
|
+
`packages/cli` is the only unscoped npm package in this monorepo.
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
|
|
22
|
+
Run a protocol-only example that creates a space, creates a tray, dispatches an extension command, and prints each client frame:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm --filter opentray example:basic
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The top-level SDK now exposes the mainline broker-backed path directly:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { createSpace, createTray, resolveDefaultSpace } from "opentray";
|
|
32
|
+
|
|
33
|
+
const space = await createSpace({ id: "com.example.status", default: true });
|
|
34
|
+
await space.createTray({
|
|
35
|
+
trayId: "status",
|
|
36
|
+
title: "Status",
|
|
37
|
+
icon: { type: "rgba", data: [0, 0, 0, 0], width: 1, height: 1 },
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const defaultSpace = await resolveDefaultSpace();
|
|
41
|
+
await createTray({
|
|
42
|
+
trayId: "secondary",
|
|
43
|
+
title: "Secondary",
|
|
44
|
+
icon: { type: "rgba", data: [0, 0, 0, 0], width: 1, height: 1 },
|
|
45
|
+
}, { space: defaultSpace.space });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`createTray()` resolves the broker default space when no explicit target is provided. If you already know the target, pass `space: defaultSpace.space` in the second argument instead of relying on default-space lookup.
|
|
49
|
+
|
|
50
|
+
Run the human-visible daemon tray example:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pnpm --filter opentray example:daemon-tray
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Run the direct webview control demo:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pnpm --filter opentray example:webview-control
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
That demo opens a native WebView window immediately and puts the controls inside the page itself, so you can exercise frameless, transparent, keep-on-top, title, icon, screen, and navigation behavior without going through the tray menu first.
|
|
63
|
+
Treat `example:webview-control` as the API exercise surface. It is useful for probing capabilities and events, but it is not the canonical recipe for a tray-anchored glass shell.
|
|
64
|
+
|
|
65
|
+
Run the dedicated tray-panel demo:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
cargo build -p opentray-bin -p opentray-ext-webview
|
|
69
|
+
pnpm --filter opentray example:tray-panel
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This demo is the canonical custom TrayPanel case: one `primaryEvent` tray item, backend `tray.getBounds()`, page `navigator.opentray.tray.getBounds()`, screen-aware repositioning, and a frameless glass panel with `keepOnTop`.
|
|
73
|
+
It also follows the native-glass rule strictly: transparent native window background, no root HTML shell styling, and content padding only inside the page.
|
|
74
|
+
It now also pins `style.platform.macos.materialState: "active"` so the tray-launched material surface does not immediately fall back to the inactive grey AppKit appearance.
|
|
75
|
+
For a step-by-step walkthrough of the examples and expected behavior, read [examples/EXAMPLE.md](./examples/EXAMPLE.md).
|
|
76
|
+
|
|
77
|
+
## Release Channels And Maturity
|
|
78
|
+
|
|
79
|
+
OpenTray uses release channels and capability maturity together. Do not read a published platform package as proof that every visible runtime path is already stable.
|
|
80
|
+
|
|
81
|
+
- `latest`: the stable package line
|
|
82
|
+
- `alpha`: the prerelease/testing package line, installed as `npm i opentray@alpha`
|
|
83
|
+
|
|
84
|
+
Current WebView truth:
|
|
85
|
+
|
|
86
|
+
- macOS is the current `stable` human-visible acceptance path
|
|
87
|
+
- Windows and Linux are currently `alpha` for WebView runtime behavior, even though their platform packages are published
|
|
88
|
+
- some requests are `unsupported by design`, such as asking the macOS runtime to apply a Windows-only style family
|
|
89
|
+
- some results are `unavailable by context`, such as tray-bounds projection when the current session has no authoritative tray anchor
|
|
90
|
+
|
|
91
|
+
When run from the repo worktree, the example automatically discovers `target/debug` or `target/release` `libopentray_ext_webview` and wires it through `OPENTRAY_EXT_PATH` before starting the daemon. That keeps the example on the real `load-ext` path without requiring a manual staging step for routine source-level testing.
|
|
92
|
+
|
|
93
|
+
After installing from npm, use the published CLI smoke path instead of workspace scripts:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
opentray smoke daemon-tray
|
|
97
|
+
opentray smoke daemon-lynx --bundle ./research/lynx/app/dist/main.lynx.bundle
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
This example starts or reuses the same-version daemon automatically, creates a real tray through the public SDK, and prints broker-routed menu events. Use manual lifecycle commands only for operator/debug control:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pnpm --filter opentray cli -- daemon start
|
|
104
|
+
pnpm --filter opentray cli -- daemon stop
|
|
105
|
+
pnpm --filter opentray cli -- daemon restart
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The menu intentionally declares only one plain item: `Open WebView` with `primaryEvent: true`. On macOS, that single primary item lets clicking the status item direct-trigger the normal `menuClick` event without opening a menu, so the example can behave like a one-action launcher for a WebView-built surface.
|
|
109
|
+
|
|
110
|
+
On platforms that expose a direct tray activation gesture, the same item opens the WebView immediately while still remaining a normal native menu item on platforms or gestures that show a menu.
|
|
111
|
+
|
|
112
|
+
The host side of that example can call `await tray.getBounds()` to read the current tray geometry before opening the window. The rendered page can also opt into `navigator.opentray.tray.getBounds()` when it needs the same tray anchor for layout.
|
|
113
|
+
|
|
114
|
+
The opened WebView also enables the injected page bridge so the rendered page can call `navigator.window` / `navigator.opentrayWindow` and, for the demo only, opt into `window.close()` / `window.moveTo()` / `window.resizeTo()` overrides. Use the in-page buttons to verify `getCapabilities`, `getStyle`, `setStyle({ frameless })`, move, resize, close, and tray-bounds behavior visually instead of relying only on terminal logs.
|
|
115
|
+
|
|
116
|
+
The Lynx smoke path uses the same generic extension loader but launches a real `LynxExplorer.app.zip` runtime sidecar from `@opentray/ext-lynx-darwin-*`. It starts the requested `.lynx.bundle` immediately on run and exposes `Reload Bundle`, `Hide Window`, and `Quit Smoke` through tray-routed events.
|
|
117
|
+
|
|
118
|
+
First-stage platform packages are published for macOS, Linux, and Windows. macOS is the current human-visual acceptance path. Linux and Windows artifacts are present for package topology validation, but unsupported broker/WebView capability must fail explicitly rather than pretending a visible UI exists. Lynx is intentionally macOS-first for now and should fail honestly on other platforms instead of pretending the runtime exists.
|
|
119
|
+
|
|
120
|
+
If you are validating the current prerelease branch before stable publication, install from the alpha channel and treat that as alpha evidence rather than stable evidence:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm i opentray@alpha
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For local native smoke before npm publish, stage the current platform artifacts first:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
cargo build -p opentray-bin -p opentray-ext-webview -p opentray-ext-lynx
|
|
130
|
+
bun run scripts/binaries/stage-local.ts --kind daemon --source target/debug/opentray
|
|
131
|
+
bun run scripts/binaries/stage-local.ts --kind webview --source target/debug/libopentray_ext_webview.dylib
|
|
132
|
+
bun run scripts/binaries/stage-local.ts --kind lynx --source target/debug/libopentray_ext_lynx.dylib
|
|
133
|
+
bash scripts/release/build-lynx-runtime.sh /tmp/LynxExplorer.app.zip
|
|
134
|
+
bun run scripts/binaries/stage-local.ts --kind lynx-runtime --source /tmp/LynxExplorer.app.zip
|
|
135
|
+
OPENTRAY_EXAMPLE_WEBVIEW_SMOKE=1 pnpm --filter opentray cli -- smoke daemon-tray
|
|
136
|
+
pnpm --filter opentray cli -- smoke daemon-lynx --bundle ./research/lynx/app/dist/main.lynx.bundle
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
During source-level daemon work, restart the daemon with the freshly built broker binary before testing tray behavior. Otherwise the CLI may reuse the already staged same-version daemon:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
cargo build -p opentray-bin
|
|
143
|
+
OPENTRAY_BROKER_BIN="$PWD/target/debug/opentray" pnpm --filter opentray cli -- daemon restart
|
|
144
|
+
OPENTRAY_BROKER_BIN="$PWD/target/debug/opentray" pnpm --filter opentray cli -- smoke daemon-tray
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The daemon exits automatically after 30 seconds with no connected clients. Set `OPENTRAY_DAEMON_IDLE_TIMEOUT_MS=0` to keep it alive during debugging, or provide another millisecond value for a custom idle release window.
|
|
148
|
+
|
|
149
|
+
`OPENTRAY_HOME` should point at a home root, not the `.opentray` state directory itself. OpenTray always stores versioned state under `"$OPENTRAY_HOME/.opentray/<package-version>"`.
|
|
150
|
+
|
|
151
|
+
To confirm the native runtime split on macOS after a release build:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
cargo build -p opentray-bin -p opentray-ext-webview -p opentray-ext-lynx --release
|
|
155
|
+
wc -c target/release/opentray target/release/libopentray_ext_webview.dylib target/release/libopentray_ext_lynx.dylib
|
|
156
|
+
otool -L target/release/opentray
|
|
157
|
+
otool -L target/release/libopentray_ext_webview.dylib
|
|
158
|
+
otool -L target/release/libopentray_ext_lynx.dylib
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Current native icon support is `rgba`. `encoded` and `file` are typed protocol shapes, but the native `tray-icon` backend reports them as unsupported until decoding and file loading policy are implemented.
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DaemonHealth } from "@opentray/spec";
|
|
2
|
+
|
|
3
|
+
//#region src/cli.d.ts
|
|
4
|
+
type CliCommand = {
|
|
5
|
+
type: "daemon";
|
|
6
|
+
action: "start" | "stop" | "restart" | "health";
|
|
7
|
+
} | {
|
|
8
|
+
type: "smoke";
|
|
9
|
+
name: "daemon-tray";
|
|
10
|
+
} | {
|
|
11
|
+
type: "smoke";
|
|
12
|
+
name: "daemon-lynx";
|
|
13
|
+
bundlePath?: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: "help";
|
|
16
|
+
};
|
|
17
|
+
declare const parseCliCommand: (argv: string[]) => CliCommand;
|
|
18
|
+
declare const runCli: (argv: string[]) => Promise<number>;
|
|
19
|
+
declare const formatDaemonHealthOutput: (health: DaemonHealth) => string;
|
|
20
|
+
declare const isCliEntrypoint: (argvEntryPath: string | undefined, modulePath: string) => boolean;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { formatDaemonHealthOutput, isCliEntrypoint, parseCliCommand, runCli };
|
|
23
|
+
//# sourceMappingURL=cli.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";;;KAiBK,UAAA;EACC,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;EAAe,IAAA;AAAA;EACf,IAAA;EAAe,IAAA;EAAqB,UAAA;AAAA;EACpC,IAAA;AAAA;AAAA,cAEO,eAAA,GAAmB,IAAA,eAAiB,UAmBhD;AAAA,cAEY,MAAA,GAAgB,IAAA,eAAiB,OAAO;AAAA,cAsFxC,wBAAA,GAA4B,MAAoB,EAAZ,YAAY;AAAA,cAoBhD,eAAA,GAAmB,aAAA,sBAAmC,UAAkB"}
|