@bobfrankston/msgapidefs 0.1.37 → 0.1.39
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 +15 -9
- package/msgapi-plan.md +47 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,13 +75,18 @@ msger + msga cover every platform, so the Electron host has no platform to itsel
|
|
|
75
75
|
**Do not do feature-parity work on msgview.** New features land in msger (and msga
|
|
76
76
|
where it makes sense); msgview catches up only on demand, if a real need appears.
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
**As of 2026-08-01 msgview has no capability msger lacks.** The two things that
|
|
79
|
+
used to be Electron-only are both settled:
|
|
80
|
+
|
|
81
|
+
- **Unpacked Chrome extensions** (`-extension`) — not how add-ins are done here.
|
|
82
|
+
**`window.msgapi` (this package) plus injected init scripts is the add-in
|
|
83
|
+
mechanism**: `initScript` / `initScriptPath` inject app JS into every document
|
|
84
|
+
before page scripts run, with the full msgapi surface available — host-native,
|
|
85
|
+
works in msger and msga, no Chromium required. If something genuinely needs
|
|
86
|
+
Chrome extension APIs, run it in Chrome.
|
|
87
|
+
- **`-render` off Windows** — ported. msger now captures on Linux/Pi through
|
|
88
|
+
WebKitGTK's snapshot API (see the render row above), verified on a Pi 5 for both
|
|
89
|
+
PNG and JPEG output.
|
|
85
90
|
|
|
86
91
|
Engine currency is *not* a reason: a feature probe on Pi 5 / WebKitGTK 2.50.6
|
|
87
92
|
(2026-07-31) passed 23 of 24 modern checks — `:has()`, CSS nesting, container
|
|
@@ -145,11 +150,12 @@ nothing about capability.
|
|
|
145
150
|
| `tcp.close()` | ✅ | ✅ | ✅ | Close connection |
|
|
146
151
|
| **HTTP Fetch** | | | | **`window.msgapi.http.*`** |
|
|
147
152
|
| `http.fetch()` | ✅ | ✅ | ✅ | Native HTTP — bypasses CORS/mixed-content |
|
|
153
|
+
| **Media capture (mic/camera)** | ❌ | ❌ | ❌ | Not an msgapi API — `getUserMedia` is the engine's. What's missing is the permission grant, which no host makes: wry's WebKitGTK backend has no `permission-request` handling (WebKitGTK denies by default), msger ignores WebView2's `PermissionRequested`, msga lacks `RECORD_AUDIO`. Deferred; direction is an external speech package, not in-page capture — see [msgapi-plan.md](./msgapi-plan.md#not-planned-recorded-so-it-doesnt-get-re-investigated). |
|
|
148
154
|
| **Host Launcher Features** | | | | *Not part of `window.msgapi`; CLI / launcher-side* |
|
|
149
155
|
| Markdown rendering (`.md`/`.markdown` auto-render) | ✅ | ✅ | ❌ | Local `file://` URL → rendered HTML via `msgcommon/markdown` (marked + light/dark CSS). msga could match it in `MainPage.xaml.cs` URL interception — not done yet. |
|
|
150
|
-
| Unpacked Chrome extension loading (`-extension <dir>`) | ✅ | ❌ | ❌ | msgview-only via `session.extensions.loadExtension`. wry has no public extension API; WebKitGTK has none at all.
|
|
156
|
+
| Unpacked Chrome extension loading (`-extension <dir>`) | ✅ | ❌ | ❌ | msgview-only via `session.extensions.loadExtension`. wry has no public extension API; WebKitGTK has none at all. **Not the add-in mechanism here** — app add-ins are `window.msgapi` + injected init scripts (`initScript` / `initScriptPath`), which work in msger and msga without Chromium. Chrome-extension-specific needs go to Chrome. |
|
|
151
157
|
| Headless mode (`-noshow` without `-save`) | ✅ | ✅ | ❌ | msger creates the WebView invisible (`with_visible(false)`) but still loads HTML and runs scripts — an embedded `<script>` can query the engine and `window.ipc.postMessage` a result back. Combined with `-result <fieldname>` for clean stdout, this lets msger act as a headless CSS/JS resolver (`contrast-color()`, `getComputedStyle()`, `CSS.supports()`). msgview matches with `BrowserWindow({show:false})` + `backgroundThrottling:false`. |
|
|
152
|
-
| Render to bitmap (`-render [file]`, `render` option) | ✅ | ✅ | ❌ | Headless page→image capture: the window is never shown; the page loads, settles (`renderDelay`, default 100ms after `load` + two rAFs), is screenshotted, and the host exits. `-render <file>` writes the image (format from extension: `.png`/`.jpg`/`.bmp`) and the JSON result carries `render: {path, width, height, format}`; bare `-render` (or API `render: true`) returns it as `render: {data (base64), width, height, format}`. Library API: `showMessageBox({render: "shot.png" \| true, renderDelay?, renderFormat?})`; a failed capture rejects (msger) or sets `renderError` in the result. Both hosts fall back to capturing whatever rendered if the page hasn't loaded within the timeout (default 30s in render mode). msger: WebView2 DevTools `Page.captureScreenshot`
|
|
158
|
+
| Render to bitmap (`-render [file]`, `render` option) | ✅ | ✅ | ❌ | Headless page→image capture: the window is never shown; the page loads, settles (`renderDelay`, default 100ms after `load` + two rAFs), is screenshotted, and the host exits. `-render <file>` writes the image (format from extension: `.png`/`.jpg`/`.bmp`) and the JSON result carries `render: {path, width, height, format}`; bare `-render` (or API `render: true`) returns it as `render: {data (base64), width, height, format}`. Library API: `showMessageBox({render: "shot.png" \| true, renderDelay?, renderFormat?})`; a failed capture rejects (msger) or sets `renderError` in the result. Both hosts fall back to capturing whatever rendered if the page hasn't loaded within the timeout (default 30s in render mode). msger: WebView2 DevTools `Page.captureScreenshot` on Windows, `webkit_web_view_get_snapshot()` → cairo PNG on Linux/Pi (2026-08-01); msgview: `webContents.capturePage()`. Both msger paths produce the same base64 PNG, so format transcoding and file writing are shared. **Linux caveat:** WebKitGTK cannot snapshot a window that was never mapped, so on Linux the render window IS mapped — made invisible by going fully transparent and skipping the taskbar, since Wayland has no way to park a window off-screen. Width/height are physical pixels (include DPI scale) and cover the WebView viewport, not the window frame. |
|
|
153
159
|
|
|
154
160
|
> **msger** now injects `window.msgapi` via `msger-api.js` with window control, UDP, and HTTP. File system and shell are not yet implemented in msger or msgview.
|
|
155
161
|
>
|
package/msgapi-plan.md
CHANGED
|
@@ -242,6 +242,53 @@ interface MsgAPI {
|
|
|
242
242
|
|
|
243
243
|
---
|
|
244
244
|
|
|
245
|
+
## Not Planned (recorded so it doesn't get re-investigated)
|
|
246
|
+
|
|
247
|
+
### Microphone / camera capture — deferred, direction is an external package
|
|
248
|
+
|
|
249
|
+
**Status 2026-08-01: not in msgapi, and no host grants the permission.** Recorded
|
|
250
|
+
after the wallclock app showed *"Initialization failed: Microphone constraints not
|
|
251
|
+
supported"* under msger on a Pi 5.
|
|
252
|
+
|
|
253
|
+
**Why it isn't an msgapi API.** The mic is reached with the plain web API
|
|
254
|
+
`navigator.mediaDevices.getUserMedia` — the engine already provides it. msgapi
|
|
255
|
+
exists for what a browser *can't* do. What's actually missing is a **permission
|
|
256
|
+
decision**, and none of the hosts makes one:
|
|
257
|
+
|
|
258
|
+
| host | today |
|
|
259
|
+
|------|-------|
|
|
260
|
+
| msger / WebKitGTK (Linux, Pi) | wry 0.54's WebKitGTK backend has no permission-request handling at all; WebKitGTK denies an unhandled `permission-request` by default |
|
|
261
|
+
| msger / WebView2 (Windows) | msger never handles `PermissionRequested`; whatever WebView2 defaults to applies |
|
|
262
|
+
| msga (Android) | manifest doesn't declare `RECORD_AUDIO` (the only hits are inside `Mono.Android.dll`); no `onPermissionRequest` handler |
|
|
263
|
+
|
|
264
|
+
**Unresolved:** whether the Pi failure is the permission gate or the app's
|
|
265
|
+
constraints — WebKitGTK is pickier than Chromium about `echoCancellation`,
|
|
266
|
+
`sampleRate`, etc. One probe settles it: call `getUserMedia({audio: true})` with
|
|
267
|
+
bare constraints via `initScript` and read the error name — `NotAllowedError`
|
|
268
|
+
means permission, `OverconstrainedError` means constraints.
|
|
269
|
+
|
|
270
|
+
**If it ever becomes a priority**, the work is:
|
|
271
|
+
|
|
272
|
+
1. **msger (Rust)** — connect WebKitGTK's `permission-request` signal and WebView2's
|
|
273
|
+
`PermissionRequested` event, granting media for content the caller trusts.
|
|
274
|
+
Opt-in per the no-regression rule in CLAUDE.md (e.g. `permissions:
|
|
275
|
+
["microphone","camera"]` / `-allow mic`), defaulting to today's behavior so no
|
|
276
|
+
existing caller changes.
|
|
277
|
+
2. **msga** — `RECORD_AUDIO` in the manifest, the Android runtime permission
|
|
278
|
+
request, and a `WebChromeClient.onPermissionRequest` handler.
|
|
279
|
+
3. **msgapidefs** — a matrix row for which host grants what. No new
|
|
280
|
+
`window.msgapi` call is needed.
|
|
281
|
+
|
|
282
|
+
**Direction (Bob, 2026-08-01): don't build this speculatively.** The original
|
|
283
|
+
motivation was speech processing, which never worked well enough in-browser to be
|
|
284
|
+
worth it. The likely future is delegating to an **external speech package** —
|
|
285
|
+
msger/msga hand off to a native or networked processor (reachable today through
|
|
286
|
+
`msgapi.shell` / `msgapi.http` / `msgapi.udp`) rather than capturing audio in the
|
|
287
|
+
page. In-page mic support is only worth building if a concrete use case shows up
|
|
288
|
+
that genuinely needs the audio inside the WebView.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
245
292
|
## Implementation Priorities
|
|
246
293
|
|
|
247
294
|
### Phase 1: msga msgapi + UDP ✅ Done
|