create-opentray 0.0.0 → 0.19.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 +163 -0
- package/dist/assets/create-openspec-template-iOS-Dark-1024@1x.png +0 -0
- package/dist/assets/create-openspec-template-iOS-Default-1024@1x.png +0 -0
- package/dist/bin-B9VeXatR.mjs +3830 -0
- package/dist/bin-B9VeXatR.mjs.map +1 -0
- package/dist/bin-CeFW1wxR.d.mts +15 -0
- package/dist/bin-CeFW1wxR.d.mts.map +1 -0
- package/dist/bin.d.mts +2 -0
- package/dist/bin.mjs +3 -0
- package/dist/icon-codec-BQ3cGV1n.mjs +13 -0
- package/dist/icon-codec-BQ3cGV1n.mjs.map +1 -0
- package/dist/index.d.mts +557 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/shell/assets/__vite-browser-external-2447137e.js +1 -0
- package/dist/shell/assets/browse.js +1 -0
- package/dist/shell/assets/ghostty-web.js +13 -0
- package/dist/shell/assets/index.css +1 -0
- package/dist/shell/assets/index.js +9 -0
- package/dist/shell/assets/input.js +1 -0
- package/dist/shell/assets/main.js +43 -0
- package/dist/shell/assets/terminal-pane.js +2 -0
- package/dist/shell/assets/terminal.js +1 -0
- package/dist/shell/browse.html +15 -0
- package/dist/shell/ghostty-vt.wasm +0 -0
- package/dist/shell/index.html +15 -0
- package/dist/shell/terminal.html +15 -0
- package/dist/webui/assets/__vite-browser-external-2447137e.js +1 -0
- package/dist/webui/assets/browse.js +1 -0
- package/dist/webui/assets/ghostty-web.js +13 -0
- package/dist/webui/assets/index.css +1 -0
- package/dist/webui/assets/index.js +9 -0
- package/dist/webui/assets/input.js +1 -0
- package/dist/webui/assets/main.js +43 -0
- package/dist/webui/assets/terminal-pane.js +2 -0
- package/dist/webui/assets/terminal.js +1 -0
- package/dist/webui/browse.html +15 -0
- package/dist/webui/ghostty-vt.wasm +0 -0
- package/dist/webui/index.html +16 -0
- package/dist/webui/terminal.html +15 -0
- package/dist/webui/vendor/ghostty-vt.wasm +0 -0
- package/dist/webui/vendor/ghostty-web.js +2963 -0
- package/package.json +45 -5
- package/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# create-opentray
|
|
2
|
+
|
|
3
|
+
Turn any start command that serves HTTP locally into an OpenTray-hosted
|
|
4
|
+
desktop app — through a browser wizard, without writing OpenTray code.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
npx create-opentray
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Requires Node >= 20 (native `sharp` icon pipeline).
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
1. Starts a token-guarded WebUI (React + shadcn/ui) on `127.0.0.1` and opens
|
|
15
|
+
your browser.
|
|
16
|
+
2. You paste a start command (e.g. `npx somecommand start --xx`). It runs
|
|
17
|
+
immediately in a **real interactive terminal** inside a Chrome-style tabs
|
|
18
|
+
panel: prompts, TUI output, and keystrokes all work.
|
|
19
|
+
3. Confirmed HTTP services (TCP listener owned by the command's process tree
|
|
20
|
+
**and** answering an HTTP probe) each open an iframe tab automatically —
|
|
21
|
+
newly sniffed tabs take focus — and stay alive across switches. The tab
|
|
22
|
+
strip sits above the context toolbar; on service tabs it shows an editable
|
|
23
|
+
URL with back/forward/reload backed by a per-tab history. The terminal tab's status bar shows cursor position,
|
|
24
|
+
selection range, and clickable service entries that jump to the matching
|
|
25
|
+
iframe tab by hostname.
|
|
26
|
+
4. Auto-derived defaults (scraped title, derived appId) are shown as
|
|
27
|
+
**input placeholders** — an empty field means "use the default"; edits win
|
|
28
|
+
over later scrapes. The icon row is a square file picker plus scraped
|
|
29
|
+
candidates: every icon the page declares (SVG, apple-touch-icon, sized
|
|
30
|
+
PNG sets, /favicon.ico) is collected, measured by true pixel clarity,
|
|
31
|
+
deduplicated perceptually, and ranked; clicking a candidate (or uploading
|
|
32
|
+
a local image) selects it, and the clearest candidate is the default.
|
|
33
|
+
5. 高级选项 — the settings button beside the command bar opens an accordion:
|
|
34
|
+
- 命令选项: 参数输入模式 (string vs 数组/argv — array mode commits ONE argv
|
|
35
|
+
element per tag, verbatim, never splitting strings), 工作目录 (cwd;
|
|
36
|
+
default is the USER_HOME directory, displayed in full — relative paths
|
|
37
|
+
resolve from there), and 环境变量 (env overlay; also persisted into the
|
|
38
|
+
generated app).
|
|
39
|
+
- 应用选项: the tray-icon picker (defaults to the app icon choice; solid
|
|
40
|
+
black/white silhouettes derived from every candidate) and the two
|
|
41
|
+
generated-app window options 显示启动终端 / 显示地址栏 (both default off).
|
|
42
|
+
Service ports are NEVER hard-bound: the form has no manual port input, and
|
|
43
|
+
the generated app resolves its address exclusively by sniffing the
|
|
44
|
+
command's owned listening ports (HTTP-verified) at runtime.
|
|
45
|
+
6. 确定创建 freezes the resolved identity, shows a confirmation dialog, then
|
|
46
|
+
确认生成 runs the pipeline with live logs: scaffold → icon generation →
|
|
47
|
+
dependency install → first launch → (macOS) stable bundle verification.
|
|
48
|
+
7. Success offers 打开应用 plus a platform pinning hint (Windows taskbar /
|
|
49
|
+
macOS Dock).
|
|
50
|
+
|
|
51
|
+
## CLI
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
create-opentray [targetDir] [--no-open] [--port <n>] [--pm npm|pnpm|bun]
|
|
55
|
+
[--skip-install] [--force]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- `--no-open` — print the wizard URL instead of opening a browser.
|
|
59
|
+
- `--pm` — force the package manager used for the generated project.
|
|
60
|
+
- `--skip-install` — scaffold without installing dependencies.
|
|
61
|
+
- `--force` — allow materializing into a non-empty directory.
|
|
62
|
+
|
|
63
|
+
## Generated project
|
|
64
|
+
|
|
65
|
+
Projects default to `~/.opentray/create/<name>/` (stable per app — re-running
|
|
66
|
+
the wizard for the same command regenerates the same location and never
|
|
67
|
+
pollutes the invocation directory). Pass a positional argument to place the
|
|
68
|
+
project elsewhere. When the target directory already exists, the wizard
|
|
69
|
+
warns in 高级选项 and offers 强制覆盖, which CLEARS the directory and
|
|
70
|
+
regenerates it (equivalent to `--force`; the generated tree is fully
|
|
71
|
+
wizard-owned and regenerable).
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
<project>/
|
|
75
|
+
package.json deps: opentray, @opentray/ext-webview (+ @lydell/node-pty
|
|
76
|
+
when the startup terminal is enabled)
|
|
77
|
+
opentray.app.json frozen identity, command vector, service port, window size,
|
|
78
|
+
tray icon, shell options
|
|
79
|
+
main.mjs entry: supervises the command, owns tray + windows
|
|
80
|
+
app-shell-server.mjs local shell host (only when a shell option is enabled):
|
|
81
|
+
serves app-shell/ + SSE state + terminal input
|
|
82
|
+
app-shell/ prebuilt shell UI pages (terminal.html, browse.html)
|
|
83
|
+
app-icon/ generated ICNS/ICO/Linux PNGs + app-icon.json manifest
|
|
84
|
+
+ tray-icon.png (always, when any icon source exists)
|
|
85
|
+
|
|
86
|
+
Icon composition: the wizard analyzes the chosen foreground (alpha-weighted
|
|
87
|
+
luminance + opaque coverage, read at full size so no resampling padding
|
|
88
|
+
skews the reading) and composites it — ORIGINAL pixels preserved, never
|
|
89
|
+
recolored — over one of three backgrounds: light art → black, dark art →
|
|
90
|
+
white, fully-opaque art → transparent. Live preview, auto/manual selection,
|
|
91
|
+
and a 50–95% foreground scale control. Every composition is clipped to the
|
|
92
|
+
squircle alpha carried by the bundled backgrounds (including the transparent
|
|
93
|
+
one), which rounds the composite's corners on macOS. For macOS the ENTIRE tile
|
|
94
|
+
(background + art) is scaled to 824 and centered on the transparent 1024
|
|
95
|
+
canvas — Dock icons since Big Sur carry those margins — while Windows/Linux
|
|
96
|
+
use the full-bleed 1024. The tray icon stays on the raw source.
|
|
97
|
+
README.md
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The entry spawns the recorded command (output → `app.log`), waits for the
|
|
101
|
+
service port via TCP, then calls `createTray` with the frozen `appId`,
|
|
102
|
+
`appName`, generated `appIcon`, an optional tray icon, and an explicit absolute
|
|
103
|
+
`appLaunch` vector, and opens an `appMode: true` WebView window on the service
|
|
104
|
+
URL. Quit lives in the tray menu.
|
|
105
|
+
|
|
106
|
+
### Shell options (dedicated windows)
|
|
107
|
+
|
|
108
|
+
- 显示启动终端 — the command runs through a PTY and a DEDICATED terminal
|
|
109
|
+
window opens: command bar on top, the same ghostty renderer the wizard uses,
|
|
110
|
+
status bar with cursor, size, and live listened ports (detached ports are
|
|
111
|
+
marked). Input flows back through the shell server.
|
|
112
|
+
- 显示地址栏 — every service window renders as an address-bar wrapper: the bar
|
|
113
|
+
sits above the service iframe and navigation is managed through the Web
|
|
114
|
+
Navigation API (same-origin `?url=` pseudo-routes are intercepted so only
|
|
115
|
+
the iframe moves; a history fallback covers engines without the API). With
|
|
116
|
+
the option off, service windows open the service URL directly.
|
|
117
|
+
- Every listened HTTP port owned by the command opens its own window
|
|
118
|
+
automatically; when a port stops listening, its window title becomes
|
|
119
|
+
`AppName (detached)` and reverts when the port returns.
|
|
120
|
+
- Generated entries always launch with Node even when the wizard ran under Bun
|
|
121
|
+
(the native PTY transport requires a Node host).
|
|
122
|
+
|
|
123
|
+
## Platform notes
|
|
124
|
+
|
|
125
|
+
- **Objective terminal transport**: the preview runs through
|
|
126
|
+
[@lydell/node-pty](https://github.com/lydell/node-pty) (prebuilt per-platform
|
|
127
|
+
binaries; no compiler needed) and is rendered by
|
|
128
|
+
[ghostty-web](https://github.com/coder/ghostty-web). The backend forwards the
|
|
129
|
+
PTY binding's chunks verbatim — no re-decoding, no analysis; the renderer
|
|
130
|
+
owns every escape sequence. Invalid bytes are replaced with U+FFFD *inside
|
|
131
|
+
the PTY binding* (its documented text-channel contract, shared with every
|
|
132
|
+
node-pty consumer); the wizard adds no interpretation on top.
|
|
133
|
+
- The optional PTY dependency degrades to a read-only pipe mode with a visible
|
|
134
|
+
notice when it cannot load; the wizard itself keeps working.
|
|
135
|
+
- **Runtime-native PTY backends**: under Bun the terminal attaches through
|
|
136
|
+
the built-in `Bun.Terminal` + `Bun.spawn({ terminal })` (no native npm
|
|
137
|
+
dependency, fully interactive — verified output, stdin echo, resize, and
|
|
138
|
+
exit codes on Bun 1.3.14). Under Node it uses prebuilt `@lydell/node-pty`.
|
|
139
|
+
Both transport the PTY's chunks verbatim. Only when neither backend exists
|
|
140
|
+
(Node without the optional dependency, or a Bun older than 1.2.19) does the
|
|
141
|
+
preview degrade to read-only pipes with a visible notice.
|
|
142
|
+
- The Run button becomes an Interrupt button while the preview process is
|
|
143
|
+
alive and returns to Run when the process exits — including when it is
|
|
144
|
+
killed outside the wizard.
|
|
145
|
+
- The generated app runs the command supervised but headless (output goes to
|
|
146
|
+
`app.log`); commands that require an interactive TTY at runtime are not
|
|
147
|
+
supported inside the generated app.
|
|
148
|
+
- macOS: the stable `.app` bundle is materialized by the OpenTray runtime on
|
|
149
|
+
first launch; 打开应用 uses `open <bundle>.app` (cold launch via the launch
|
|
150
|
+
descriptor, warm reopen focuses the retained window). Pin it to the Dock.
|
|
151
|
+
- Windows: the appMode window participates in the taskbar/Alt-Tab; pin it from
|
|
152
|
+
the taskbar. Persistent shortcut generation is not provided yet.
|
|
153
|
+
- Linux: taskbar pinning depends on the desktop environment; `.desktop`
|
|
154
|
+
generation is not provided yet.
|
|
155
|
+
|
|
156
|
+
## Programmatic use
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { createWizardSession, deriveDefaultAppId } from "create-opentray";
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
See the package's TypeScript definitions (dist/index.d.mts) for the full surface (wizard session, server,
|
|
163
|
+
discovery, scraping, launch-vector resolution, scaffold, materialize).
|
|
Binary file
|
|
Binary file
|