@livx.cc/appwrap 0.43.0 → 0.46.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/package.json +1 -1
- package/runtime-desktop/bridge-shim/build.sh +9 -0
- package/runtime-desktop/bridge-shim/content-entry.ts +87 -0
- package/runtime-desktop/bridge-shim/shim.ts +317 -0
- package/runtime-desktop/src-tauri/Cargo.lock +2 -0
- package/runtime-desktop/src-tauri/Cargo.toml +2 -0
- package/runtime-desktop/src-tauri/src/bridge_mac.rs +664 -0
- package/runtime-desktop/src-tauri/src/main.rs +198 -2
- package/runtime-desktop/src-tauri/src/popup_mac.rs +63 -10
- package/runtime-desktop/src-tauri/src/server.rs +156 -0
- package/src/cli.ts +70 -13
- package/src/config.ts +36 -0
- package/src/desktop.ts +48 -1
package/src/config.ts
CHANGED
|
@@ -89,6 +89,42 @@ export interface AppwrapConfig {
|
|
|
89
89
|
* the app dir, so `build desktop` apps must keep their repo (+ node_modules) around at runtime —
|
|
90
90
|
* embedding the handler file into the `.app` is out of scope for phase-0. macOS-only. */
|
|
91
91
|
handlers?: string;
|
|
92
|
+
/** Local-server mode: boot a command that serves the app locally, then load it LIVE in the window
|
|
93
|
+
* (instead of the bundled `pwaDist`). The shell shows a bundled splash, spawns `command` (+`args`)
|
|
94
|
+
* in a background thread, polls `http://localhost:<port><healthPath>` until it answers, then
|
|
95
|
+
* navigates the window there; on window-close it kills the child so the stack never outlives the
|
|
96
|
+
* shell. Use for a desktop app that IS a local dev/server stack (e.g. `para-chat`). Absent → the
|
|
97
|
+
* desktop lane loads the bundled `pwaDist` as usual. The CLI resolves `command` (when a bare name)
|
|
98
|
+
* and `cwd` to absolute paths at stamp time (a GUI-launched .app inherits the minimal launchd PATH,
|
|
99
|
+
* so a bare `bun`/PATH lookup would fail). `build desktop` apps must keep the server (+ its repo)
|
|
100
|
+
* present at runtime — bundling the server INTO the .app is a future phase. macOS-only. */
|
|
101
|
+
server?: {
|
|
102
|
+
/** Command to spawn (argv[0]). A bare name is PATH-resolved at stamp time; an absolute path is used as-is. */
|
|
103
|
+
command: string;
|
|
104
|
+
/** Extra arguments passed to the command. */
|
|
105
|
+
args?: string[];
|
|
106
|
+
/** Working directory to spawn in (default: the app project root). */
|
|
107
|
+
cwd?: string;
|
|
108
|
+
/** How the shell learns the URL to load. Provide EXACTLY ONE:
|
|
109
|
+
* - `urlMarker` (preferred for servers that print their address, e.g. vite/para-chat): the shell
|
|
110
|
+
* pipes the server's stdout and, on the first line CONTAINING this marker, extracts the first
|
|
111
|
+
* `http(s)://…` token and loads it. This tracks whatever port the server auto-picked — no
|
|
112
|
+
* hardcoded port, no mismatch. e.g. `"Frontend:"` matches `Frontend: https://localhost:5050`.
|
|
113
|
+
* - `port` (+ optional `https`) for a silent server on a KNOWN fixed port: the shell TCP-polls
|
|
114
|
+
* `localhost:<port>` and loads `<http|https>://localhost:<port>`. */
|
|
115
|
+
urlMarker?: string;
|
|
116
|
+
/** Fixed port the server listens on (used only when `urlMarker` is absent). */
|
|
117
|
+
port?: number;
|
|
118
|
+
/** Load over https in fixed-`port` mode (default false = http). Ignored in `urlMarker` mode (the
|
|
119
|
+
* captured URL carries its own scheme). The server's TLS cert CA must be trusted by the system
|
|
120
|
+
* keychain and its SANs cover `localhost`/`127.0.0.1`, or the WebView shows a cert error. */
|
|
121
|
+
https?: boolean;
|
|
122
|
+
/** Health path polled for readiness (default `/`). Ready = any HTTP response (even 4xx/5xx). */
|
|
123
|
+
healthPath?: string;
|
|
124
|
+
/** Max ms to wait for the port before showing an error in the splash (default 120000 — a first-run
|
|
125
|
+
* production build can be slow). */
|
|
126
|
+
readyTimeoutMs?: number;
|
|
127
|
+
};
|
|
92
128
|
};
|
|
93
129
|
/** Custom URL scheme for deep links (e.g. "hellowrap" → hellowrap://...). */
|
|
94
130
|
urlScheme?: string;
|
package/src/desktop.ts
CHANGED
|
@@ -44,6 +44,31 @@ export interface DesktopShellConfig {
|
|
|
44
44
|
* ~/.bun/bin, so a bare `bun` spawn fails. The Rust shell falls back to `bun` when this is
|
|
45
45
|
* missing/nonexistent. */
|
|
46
46
|
handlersRuntime: string;
|
|
47
|
+
/** True when `modules` includes 'media' → the .app carries an NSMicrophoneUsageDescription so
|
|
48
|
+
* `getUserMedia` (voice mode) can pass macOS TCC. The WebKit-layer grant (popup_mac) is
|
|
49
|
+
* unconditional; this only adds the OS usage string an app that actually uses the mic needs. */
|
|
50
|
+
microphone: boolean;
|
|
51
|
+
/** Local-server mode. When present the Rust shell boots `command` (+`args`) in a background thread,
|
|
52
|
+
* polls `http://localhost:<port><healthPath>` until it answers, then navigates the window there
|
|
53
|
+
* (instead of the bundled dist); it kills the child on window-close. Absent → bundled-PWA load.
|
|
54
|
+
* `command`/`cwd` are resolved to ABSOLUTE by the CLI (see `regenerateDesktop`) because a
|
|
55
|
+
* GUI-launched .app has the minimal launchd PATH (no ~/.bun/bin). Empty when the app isn't a
|
|
56
|
+
* local-server app. */
|
|
57
|
+
server?: {
|
|
58
|
+
command: string;
|
|
59
|
+
args: string[];
|
|
60
|
+
cwd: string;
|
|
61
|
+
/** Stdout marker → capture the URL the server prints (dynamic port). '' when using fixed `port`. */
|
|
62
|
+
urlMarker: string;
|
|
63
|
+
/** Fixed port (used only when `urlMarker` is ''). 0 when unused. */
|
|
64
|
+
port: number;
|
|
65
|
+
https: boolean;
|
|
66
|
+
healthPath: string;
|
|
67
|
+
readyTimeoutMs: number;
|
|
68
|
+
/** PATH the child is spawned with — the CLI stamps its own (build-time) PATH so a GUI launch can
|
|
69
|
+
* still resolve neighbouring tools (bun, node) the launchd PATH omits. */
|
|
70
|
+
path: string;
|
|
71
|
+
};
|
|
47
72
|
}
|
|
48
73
|
|
|
49
74
|
/** Resolve the desktop shell config from an appwrap config: identity + `urlScheme` come from the
|
|
@@ -65,6 +90,21 @@ export function deriveDesktopConfig(cfg: AppwrapConfig): DesktopShellConfig {
|
|
|
65
90
|
handlers: d.handlers ?? '',
|
|
66
91
|
pushSigned: false, // stamped by the CLI when a signing identity + macOS profile resolve — see buildDesktop
|
|
67
92
|
handlersRuntime: '', // stamped by the CLI (process.execPath) when handlers is set — see regenerateDesktop
|
|
93
|
+
microphone: (cfg.modules ?? []).includes('media'),
|
|
94
|
+
// `command`/`cwd`/`path` are resolved to absolute by the CLI (regenerateDesktop); carried as authored here.
|
|
95
|
+
server: d.server
|
|
96
|
+
? {
|
|
97
|
+
command: d.server.command,
|
|
98
|
+
args: d.server.args ?? [],
|
|
99
|
+
cwd: d.server.cwd ?? '',
|
|
100
|
+
urlMarker: d.server.urlMarker ?? '',
|
|
101
|
+
port: d.server.port ?? 0,
|
|
102
|
+
https: d.server.https ?? false,
|
|
103
|
+
healthPath: d.server.healthPath ?? '/',
|
|
104
|
+
readyTimeoutMs: d.server.readyTimeoutMs ?? 120_000,
|
|
105
|
+
path: '',
|
|
106
|
+
}
|
|
107
|
+
: undefined,
|
|
68
108
|
};
|
|
69
109
|
}
|
|
70
110
|
|
|
@@ -134,6 +174,13 @@ export function buildInfoPlist(
|
|
|
134
174
|
<key>CFBundleIconName</key>
|
|
135
175
|
<string>${xmlEscape(iconName)}</string>`
|
|
136
176
|
: '';
|
|
177
|
+
// NSMicrophoneUsageDescription: required for getUserMedia (voice mode) to pass macOS TCC — without
|
|
178
|
+
// it the OS silently denies mic access (no prompt). Added only when the app declares the `media` module.
|
|
179
|
+
const mic = shell.microphone
|
|
180
|
+
? `
|
|
181
|
+
<key>NSMicrophoneUsageDescription</key>
|
|
182
|
+
<string>${xmlEscape(shell.name)} uses the microphone for voice input.</string>`
|
|
183
|
+
: '';
|
|
137
184
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
138
185
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
139
186
|
<plist version="1.0">
|
|
@@ -153,7 +200,7 @@ export function buildInfoPlist(
|
|
|
153
200
|
<key>CFBundlePackageType</key>
|
|
154
201
|
<string>APPL</string>
|
|
155
202
|
<key>NSHighResolutionCapable</key>
|
|
156
|
-
<true/>${icon}${iconAsset}${urlTypes}
|
|
203
|
+
<true/>${icon}${iconAsset}${mic}${urlTypes}
|
|
157
204
|
</dict>
|
|
158
205
|
</plist>
|
|
159
206
|
`;
|