@bobfrankston/msgapidefs 0.1.32 → 0.1.34

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
@@ -111,10 +111,23 @@ window.close(); // Instead of msgapi.close() if not passing result
111
111
  | `udp.listen()` | ✅ | ✅ | ✅ | Background receive loop in all hosts |
112
112
  | `udp.sendReceive()` | ✅ | ✅ | ✅ | Send + wait with timeout |
113
113
  | `udp.broadcast()` | ✅ | ✅ | ✅ | 255.255.255.255 broadcast |
114
+ | **TCP Networking** | | | | **`window.msgapi.tcp.*`** |
115
+ | `tcp.connect()` | ✅ | ✅ | ✅ | Node net/tls / Rust TcpStream+native-tls / C# TcpClient+SslStream |
116
+ | `tcp.write()` | ✅ | ✅ | ✅ | UTF-8 string data |
117
+ | `tcp.onData()` | ✅ | ✅ | ✅ | Persistent callback, fires multiple times |
118
+ | `tcp.onClose()` | ✅ | ✅ | ✅ | Connection closed notification |
119
+ | `tcp.onError()` | ✅ | ✅ | ✅ | Error notification |
120
+ | `tcp.upgradeTLS()` | ✅ | ✅ | ✅ | STARTTLS — upgrade plaintext to TLS |
121
+ | `tcp.close()` | ✅ | ✅ | ✅ | Close connection |
114
122
  | **HTTP Fetch** | | | | **`window.msgapi.http.*`** |
115
123
  | `http.fetch()` | ✅ | ✅ | ✅ | Native HTTP — bypasses CORS/mixed-content |
124
+ | **Host Launcher Features** | | | | *Not part of `window.msgapi`; CLI / launcher-side* |
125
+ | 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. |
126
+ | Unpacked Chrome extension loading (`-extension <dir>`) | ✅ | ❌ | ❌ | msgview-only via `session.extensions.loadExtension`. wry has no public extension API; WebKitGTK has none at all. msga would need a separate Android/WebView2 plumbing — not planned. |
116
127
 
117
128
  > **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.
129
+ >
130
+ > **Markdown rendering** (last two rows): both msger and msgview detect `.md`/`.markdown` URLs pointing at local files and render them via the shared `renderMarkdown()` helper in `msgcommon/markdown` — no extensions, no per-machine setup, GFM with light/dark CSS that follows `prefers-color-scheme`. Library callers can `import { renderMarkdown, looksLikeMarkdown } from '@bobfrankston/msgcommon/markdown'` directly. **Extension loading** is msgview-only by design: see the row's note.
118
131
 
119
132
  [httpudp-client](../../homecontrol/utils/udp/httpudp-client/README.md) auto-detects `window.msgapi?.udp` and uses native UDP when available, falling back to the httpudp WebSocket proxy otherwise.
120
133
 
@@ -178,6 +191,36 @@ Native UDP socket access — no WebSocket proxy needed when running inside a msg
178
191
  - `udp.sendReceive(host, port, data, timeoutMs?)` - Send and wait for response
179
192
  - `udp.broadcast(port, data)` - Broadcast to local network
180
193
 
194
+ ### TCP Networking
195
+
196
+ Native TCP/TLS socket access — for IMAP, SMTP, and other stream protocols. Connections are long-lived; use stream IDs to manage multiple connections. TLS is handled natively — JS never sees the raw TLS handshake.
197
+
198
+ - `tcp.connect(host, port, tls)` - Connect to host:port. If `tls` is true, connect with TLS directly (port 993). Returns a `streamId` (number).
199
+ - `tcp.write(streamId, data)` - Write UTF-8 string data to stream.
200
+ - `tcp.onData(streamId, callback)` - Register handler for incoming data. Persistent — fires multiple times as data arrives.
201
+ - `tcp.onClose(streamId, callback)` - Register handler for connection close. `hadError` is true if closed due to error.
202
+ - `tcp.onError(streamId, callback)` - Register handler for errors.
203
+ - `tcp.upgradeTLS(streamId, servername)` - Upgrade a plaintext connection to TLS (STARTTLS). Used by IMAP/SMTP after negotiating capabilities on plaintext.
204
+ - `tcp.close(streamId)` - Close the connection.
205
+
206
+ ```javascript
207
+ // Connect to Gmail IMAP (direct TLS on port 993)
208
+ const id = await window.msgapi.tcp.connect('imap.gmail.com', 993, true);
209
+ window.msgapi.tcp.onData(id, (data) => console.log('Server:', data));
210
+ window.msgapi.tcp.onClose(id, (hadError) => console.log('Closed', hadError));
211
+ window.msgapi.tcp.onError(id, (msg) => console.error('Error:', msg));
212
+
213
+ // STARTTLS example (connect plaintext, then upgrade)
214
+ const id2 = await window.msgapi.tcp.connect('imap.example.com', 143, false);
215
+ // ... negotiate STARTTLS capability ...
216
+ await window.msgapi.tcp.upgradeTLS(id2, 'imap.example.com');
217
+ // ... now on encrypted connection ...
218
+ ```
219
+
220
+ **Platform implementations:** msgview uses Node.js `net`/`tls`, msger uses Rust `std::net::TcpStream` + `native-tls`, msga uses C# `TcpClient` + `SslStream`.
221
+
222
+ **Used by:** `@bobfrankston/iflow-direct` `BridgeTransport` — enables browser/WebView IMAP without a Node.js server.
223
+
181
224
  ### Shell / Process Execution
182
225
 
183
226
  Native process execution — run commands, open files with default handler. msga only currently.
package/msgapi-plan.md CHANGED
@@ -45,6 +45,14 @@ Shared planning document for msgapi across implementations:
45
45
  | udp.listen() | ✅ | ✅ | ✅ | Background receive loop in all hosts |
46
46
  | udp.sendReceive() | ✅ | ✅ | ✅ | Send + wait with timeout |
47
47
  | udp.broadcast() | ✅ | ✅ | ✅ | 255.255.255.255 broadcast |
48
+ | **TCP** |
49
+ | tcp.connect() | ✅ | ✅ | ✅ | Node net/tls / Rust TcpStream+native-tls / C# TcpClient+SslStream |
50
+ | tcp.write() | ✅ | ✅ | ✅ | UTF-8 string data |
51
+ | tcp.onData() | ✅ | ✅ | ✅ | Persistent callback for incoming data |
52
+ | tcp.onClose() | ✅ | ✅ | ✅ | Connection closed notification |
53
+ | tcp.onError() | ✅ | ✅ | ✅ | Error notification |
54
+ | tcp.upgradeTLS() | ✅ | ✅ | ✅ | STARTTLS — plaintext to TLS upgrade |
55
+ | tcp.close() | ✅ | ✅ | ✅ | Close connection |
48
56
  | **HTTP** |
49
57
  | http.fetch() | ✅ | ✅ | ✅ | CORS/mixed-content bypass via native HTTP; returns real Response object |
50
58
  | **Configuration** |
@@ -244,6 +252,14 @@ interface MsgAPI {
244
252
  1. ✅ msger (Rust) — `std::net::UdpSocket` via NativeEvent + thread::spawn
245
253
  2. ✅ msgview (Electron) — Node.js `dgram` via ipcMain.handle + preload
246
254
 
255
+ ### Phase 2b: TCP in all three hosts ✅ Done
256
+ 1. ✅ TCP interface added to msgapidefs.ts (connect/write/onData/onClose/onError/upgradeTLS/close)
257
+ 2. ✅ msgview (Electron) — Node.js net/tls via ipcMain.handle, push events via webContents.send
258
+ 3. ✅ msger (Rust) — std::net::TcpStream + native-tls, thread-per-connection with cancel flags
259
+ 4. ✅ msga (MAUI) — TcpService.cs (ported from MailxApp TcpBridgeService), msgapi:// URL routing
260
+ 5. ✅ iflow bridge-transport updated: mailxapi.tcp → msgapi.tcp
261
+ 6. Used by: @bobfrankston/iflow-direct BridgeTransport for browser/WebView IMAP
262
+
247
263
  ### Phase 3: File System + Shell in msga ✅ Done
248
264
  1. ✅ fs.read with encoding options (utf8/base64/binary)
249
265
  2. ✅ fs.readAsDataUrl with MIME auto-detection
package/msgapidefs.ts CHANGED
@@ -121,6 +121,21 @@ export interface MsgAPI {
121
121
  broadcast(port: number, data: string | Uint8Array): Promise<void>; // Broadcast to local network
122
122
  };
123
123
 
124
+ // ── TCP Networking ──────────────────────────────────────────
125
+ // Native TCP/TLS — for IMAP, SMTP, and other stream protocols.
126
+ // Connections are long-lived; use stream IDs to manage multiple connections.
127
+ // TLS is handled natively — JS never sees raw TLS handshake.
128
+
129
+ tcp?: {
130
+ connect(host: string, port: number, tls: boolean): Promise<number>; // Connect to host:port (TLS if tls=true), returns streamId
131
+ write(streamId: number, data: string): Promise<void>; // Write UTF-8 data to stream
132
+ onData(streamId: number, callback: (data: string) => void): void; // Register handler for incoming data (persistent, fires multiple times)
133
+ onClose(streamId: number, callback: (hadError: boolean) => void): void; // Register handler for connection close
134
+ onError(streamId: number, callback: (message: string) => void): void; // Register handler for errors
135
+ upgradeTLS(streamId: number, servername: string): Promise<void>; // Upgrade plaintext connection to TLS (STARTTLS)
136
+ close(streamId: number): void; // Close connection
137
+ };
138
+
124
139
  // ── HTTP Fetch (CORS/mixed-content bypass) ──────────────────
125
140
  // Routes requests through the native host — no mixed-content or CORS restrictions
126
141
  // Returns a real Response object: .ok, .status, .json(), .text(), .headers, .clone()
package/package.json CHANGED
@@ -1,41 +1,41 @@
1
- {
2
- "name": "@bobfrankston/msgapidefs",
3
- "version": "0.1.32",
4
- "description": "TypeScript definitions for msgapi JavaScript API (msgview/msger)",
5
- "type": "module",
6
- "main": "./msgapidefs.js",
7
- "types": "./msgapidefs.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./msgapidefs.js",
11
- "types": "./msgapidefs.d.ts"
12
- }
13
- },
14
- "keywords": [
15
- "msgapi",
16
- "msgview",
17
- "msger",
18
- "typescript",
19
- "definitions",
20
- "types",
21
- "webview"
22
- ],
23
- "author": "Bob Frankston",
24
- "license": "ISC",
25
- "repository": {
26
- "type": "git",
27
- "url": "git+https://github.com/BobFrankston/msgapidefs.git"
28
- },
29
- "publishConfig": {
30
- "access": "public"
31
- },
32
- "scripts": {
33
- "prerelease:local": "git add -A && (git diff-index --quiet HEAD || git commit -m \"Pre-release commit\")",
34
- "preversion": "git add -A",
35
- "postversion": "git push && git push --tags",
36
- "release": "npm run prerelease:local && npm version patch && npm publish --quiet"
37
- },
38
- "devDependencies": {
39
- "@types/node": "^25.2.1"
40
- }
41
- }
1
+ {
2
+ "name": "@bobfrankston/msgapidefs",
3
+ "version": "0.1.34",
4
+ "description": "TypeScript definitions for msgapi JavaScript API (msgview/msger)",
5
+ "type": "module",
6
+ "main": "./msgapidefs.js",
7
+ "types": "./msgapidefs.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./msgapidefs.js",
11
+ "types": "./msgapidefs.d.ts"
12
+ }
13
+ },
14
+ "keywords": [
15
+ "msgapi",
16
+ "msgview",
17
+ "msger",
18
+ "typescript",
19
+ "definitions",
20
+ "types",
21
+ "webview"
22
+ ],
23
+ "author": "Bob Frankston",
24
+ "license": "ISC",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/BobFrankston/msgapidefs.git"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "prerelease:local": "git add -A && (git diff-index --quiet HEAD || git commit -m \"Pre-release commit\")",
34
+ "preversion": "git add -A",
35
+ "release": "npm run prerelease:local && npm version patch && npm publish --quiet",
36
+ "postversion": "git push && git push --tags"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^25.2.1"
40
+ }
41
+ }
@@ -1,14 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(tsc:*)",
5
- "Bash(npm init:*)",
6
- "Bash(npm install:*)",
7
- "Bash(node cli.js:*)",
8
- "Bash(node --version:*)",
9
- "Bash(cd:*)"
10
- ],
11
- "deny": [],
12
- "ask": []
13
- }
14
- }