remobi 0.1.0 → 0.2.0
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/CHANGELOG.md +37 -0
- package/README.md +4 -0
- package/dist/build.mjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/{node-compat-BzXgbTV9.mjs → node-compat-CqwRIRV_.mjs} +32 -7
- package/dist/node-compat-CqwRIRV_.mjs.map +1 -0
- package/package.json +101 -87
- package/src/pwa/icons/icon-180.png +0 -0
- package/src/pwa/icons/icon-192.png +0 -0
- package/src/pwa/icons/icon-512.png +0 -0
- package/dist/node-compat-BzXgbTV9.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
# [0.2.0](https://github.com/connorads/remobi/compare/v0.1.0...v0.2.0) (2026-03-15)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **ci:** add npm to mise.toml for OIDC trusted publishing ([44bb745](https://github.com/connorads/remobi/commit/44bb7452d0d9e3496bacc4aaf5a63f2236a8f80f))
|
|
7
|
+
* exclude package.json from Biome formatter ([044183f](https://github.com/connorads/remobi/commit/044183fd636fe56eb17f1cd650338c85be46ce5e))
|
|
8
|
+
* remove leading ./ from bin path for npm 11 compatibility ([33ba38d](https://github.com/connorads/remobi/commit/33ba38daab05224fc6eeb28402bb9860c36873d2))
|
|
9
|
+
* remove redundant checks from prepublishOnly ([efdb742](https://github.com/connorads/remobi/commit/efdb742087842ba131ed704e3e29676aa672ab87))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* add pixel R> logo and integrate across project ([44b238a](https://github.com/connorads/remobi/commit/44b238aa7909cec2c408acb5bde32f9f2c645e26))
|
|
15
|
+
|
|
16
|
+
## [0.2.2](https://github.com/connorads/remobi/compare/v0.2.1...v0.2.2) (2026-03-15)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* **ci:** add npm to mise.toml for OIDC trusted publishing ([44bb745](https://github.com/connorads/remobi/commit/44bb7452d0d9e3496bacc4aaf5a63f2236a8f80f))
|
|
22
|
+
|
|
23
|
+
## [0.2.1](https://github.com/connorads/remobi/compare/v0.2.0...v0.2.1) (2026-03-15)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* exclude package.json from Biome formatter ([044183f](https://github.com/connorads/remobi/commit/044183fd636fe56eb17f1cd650338c85be46ce5e))
|
|
29
|
+
* remove redundant checks from prepublishOnly ([efdb742](https://github.com/connorads/remobi/commit/efdb742087842ba131ed704e3e29676aa672ab87))
|
|
30
|
+
|
|
31
|
+
# [0.2.0](https://github.com/connorads/remobi/compare/v0.1.0...v0.2.0) (2026-03-15)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Features
|
|
35
|
+
|
|
36
|
+
* add pixel R> logo and integrate across project ([44b238a](https://github.com/connorads/remobi/commit/44b238aa7909cec2c408acb5bde32f9f2c645e26))
|
|
37
|
+
|
|
1
38
|
# Changelog
|
|
2
39
|
|
|
3
40
|
## 0.1.0 — 2026-03-15
|
package/README.md
CHANGED
package/dist/build.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as generatePwaHtml, n as sleep, r as spawnProcess, t as readStdin } from "./node-compat-
|
|
1
|
+
import { i as generatePwaHtml, n as sleep, r as spawnProcess, t as readStdin } from "./node-compat-CqwRIRV_.mjs";
|
|
2
2
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, resolve } from "node:path";
|
|
4
4
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as sleep, r as spawnProcess, t as readStdin } from "./node-compat-
|
|
2
|
+
import { n as sleep, r as spawnProcess, t as readStdin } from "./node-compat-CqwRIRV_.mjs";
|
|
3
3
|
import { build, bundleOverlay, injectFromStdin, injectOverlay } from "./build.mjs";
|
|
4
4
|
import { defaultConfig, defineConfig, mergeConfig, serialiseThemeForTtyd } from "./src/config.mjs";
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -3,14 +3,39 @@ import { spawn } from "node:child_process";
|
|
|
3
3
|
//#region src/pwa/icon.ts
|
|
4
4
|
/**
|
|
5
5
|
* SVG icon for remobi PWA.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Pixel-art R> on catppuccin mocha base (#1e1e2e).
|
|
7
|
+
* Green R (#a6e3a1), blue chevron (#89b4fa).
|
|
8
|
+
* Uses <rect> elements — renders identically on all platforms.
|
|
9
9
|
*/
|
|
10
10
|
const ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
11
|
-
<rect width="512" height="512" rx="80"
|
|
12
|
-
<
|
|
13
|
-
|
|
11
|
+
<rect width="512" height="512" rx="80" fill="#1e1e2e"/>
|
|
12
|
+
<g fill="#a6e3a1">
|
|
13
|
+
<rect x="76" y="130" width="28" height="28" rx="4"/>
|
|
14
|
+
<rect x="112" y="130" width="28" height="28" rx="4"/>
|
|
15
|
+
<rect x="148" y="130" width="28" height="28" rx="4"/>
|
|
16
|
+
<rect x="184" y="130" width="28" height="28" rx="4"/>
|
|
17
|
+
<rect x="76" y="166" width="28" height="28" rx="4"/>
|
|
18
|
+
<rect x="220" y="166" width="28" height="28" rx="4"/>
|
|
19
|
+
<rect x="76" y="202" width="28" height="28" rx="4"/>
|
|
20
|
+
<rect x="220" y="202" width="28" height="28" rx="4"/>
|
|
21
|
+
<rect x="76" y="238" width="28" height="28" rx="4"/>
|
|
22
|
+
<rect x="112" y="238" width="28" height="28" rx="4"/>
|
|
23
|
+
<rect x="148" y="238" width="28" height="28" rx="4"/>
|
|
24
|
+
<rect x="184" y="238" width="28" height="28" rx="4"/>
|
|
25
|
+
<rect x="76" y="274" width="28" height="28" rx="4"/>
|
|
26
|
+
<rect x="148" y="274" width="28" height="28" rx="4"/>
|
|
27
|
+
<rect x="76" y="310" width="28" height="28" rx="4"/>
|
|
28
|
+
<rect x="184" y="310" width="28" height="28" rx="4"/>
|
|
29
|
+
<rect x="76" y="346" width="28" height="28" rx="4"/>
|
|
30
|
+
<rect x="220" y="346" width="28" height="28" rx="4"/>
|
|
31
|
+
</g>
|
|
32
|
+
<g fill="#89b4fa">
|
|
33
|
+
<rect x="328" y="166" width="28" height="28" rx="4"/>
|
|
34
|
+
<rect x="364" y="202" width="28" height="28" rx="4"/>
|
|
35
|
+
<rect x="400" y="238" width="28" height="28" rx="4"/>
|
|
36
|
+
<rect x="364" y="274" width="28" height="28" rx="4"/>
|
|
37
|
+
<rect x="328" y="310" width="28" height="28" rx="4"/>
|
|
38
|
+
</g>
|
|
14
39
|
</svg>`;
|
|
15
40
|
/** Convert SVG string to a data URI */
|
|
16
41
|
function svgToDataUri(svg) {
|
|
@@ -80,4 +105,4 @@ function spawnProcess(cmd, opts) {
|
|
|
80
105
|
|
|
81
106
|
//#endregion
|
|
82
107
|
export { generatePwaHtml as i, sleep as n, spawnProcess as r, readStdin as t };
|
|
83
|
-
//# sourceMappingURL=node-compat-
|
|
108
|
+
//# sourceMappingURL=node-compat-CqwRIRV_.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-compat-CqwRIRV_.mjs","names":["nodeSpawn"],"sources":["../src/pwa/icon.ts","../src/pwa/meta-tags.ts","../src/util/node-compat.ts"],"sourcesContent":["/**\n * SVG icon for remobi PWA.\n * Pixel-art R> on catppuccin mocha base (#1e1e2e).\n * Green R (#a6e3a1), blue chevron (#89b4fa).\n * Uses <rect> elements — renders identically on all platforms.\n */\nexport const ICON_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <rect width=\"512\" height=\"512\" rx=\"80\" fill=\"#1e1e2e\"/>\n <g fill=\"#a6e3a1\">\n <rect x=\"76\" y=\"130\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"112\" y=\"130\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"148\" y=\"130\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"184\" y=\"130\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"76\" y=\"166\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"220\" y=\"166\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"76\" y=\"202\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"220\" y=\"202\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"76\" y=\"238\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"112\" y=\"238\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"148\" y=\"238\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"184\" y=\"238\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"76\" y=\"274\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"148\" y=\"274\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"76\" y=\"310\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"184\" y=\"310\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"76\" y=\"346\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"220\" y=\"346\" width=\"28\" height=\"28\" rx=\"4\"/>\n </g>\n <g fill=\"#89b4fa\">\n <rect x=\"328\" y=\"166\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"364\" y=\"202\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"400\" y=\"238\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"364\" y=\"274\" width=\"28\" height=\"28\" rx=\"4\"/>\n <rect x=\"328\" y=\"310\" width=\"28\" height=\"28\" rx=\"4\"/>\n </g>\n</svg>`\n\n/** Convert SVG string to a data URI */\nexport function svgToDataUri(svg: string): string {\n\treturn `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`\n}\n","import type { PwaConfig } from '../types'\nimport { ICON_SVG, svgToDataUri } from './icon'\n\n/** Escape a string for safe use in HTML attribute values */\nexport function escapeAttr(value: string): string {\n\treturn value\n\t\t.replace(/&/g, '&')\n\t\t.replace(/\"/g, '"')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n}\n\n/** Generate PWA HTML to inject into </head> */\nexport function generatePwaHtml(name: string, pwa: PwaConfig): string {\n\tconst svgDataUri = svgToDataUri(ICON_SVG)\n\treturn [\n\t\t`<link rel=\"manifest\" href=\"/manifest.json\">`,\n\t\t`<meta name=\"theme-color\" content=\"${escapeAttr(pwa.themeColor)}\">`,\n\t\t`<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">`,\n\t\t`<meta name=\"apple-mobile-web-app-title\" content=\"${escapeAttr(name)}\">`,\n\t\t`<link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\">`,\n\t\t`<link rel=\"icon\" type=\"image/svg+xml\" href=\"${svgDataUri}\">`,\n\t].join('\\n')\n}\n","import { spawn as nodeSpawn } from 'node:child_process'\nimport type { Readable } from 'node:stream'\n\nexport const sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms))\n\nexport async function readStdin(): Promise<string> {\n\tconst chunks: Buffer[] = []\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(Buffer.from(chunk))\n\t}\n\treturn Buffer.concat(chunks).toString('utf-8')\n}\n\nexport interface SpawnedProcess {\n\treadonly pid: number | undefined\n\treadonly stdout: Readable | null\n\treadonly stderr: Readable | null\n\treadonly stdin: NodeJS.WritableStream | null\n\tkill(signal?: NodeJS.Signals): boolean\n\treadonly exited: Promise<number>\n}\n\nexport function spawnProcess(\n\tcmd: readonly string[],\n\topts?: {\n\t\tcwd?: string\n\t\tstdin?: 'ignore' | 'pipe'\n\t\tstdout?: 'ignore' | 'pipe'\n\t\tstderr?: 'ignore' | 'pipe'\n\t},\n): SpawnedProcess {\n\tconst [command, ...args] = cmd\n\tif (!command) throw new Error('spawnProcess requires at least one argument')\n\n\tconst proc = nodeSpawn(command, args, {\n\t\tcwd: opts?.cwd,\n\t\tstdio: [opts?.stdin ?? 'ignore', opts?.stdout ?? 'ignore', opts?.stderr ?? 'ignore'],\n\t})\n\n\tconst exited = new Promise<number>((resolve, reject) => {\n\t\tproc.on('close', (code) => resolve(code ?? 1))\n\t\tproc.on('error', reject)\n\t})\n\n\treturn {\n\t\tget pid() {\n\t\t\treturn proc.pid\n\t\t},\n\t\tget stdout() {\n\t\t\treturn proc.stdout\n\t\t},\n\t\tget stderr() {\n\t\t\treturn proc.stderr\n\t\t},\n\t\tget stdin() {\n\t\t\treturn proc.stdin\n\t\t},\n\t\tkill(signal?: NodeJS.Signals) {\n\t\t\treturn proc.kill(signal)\n\t\t},\n\t\texited,\n\t}\n}\n\nexport async function collectStream(stream: Readable | null): Promise<string> {\n\tif (!stream) return ''\n\tconst chunks: Buffer[] = []\n\tfor await (const chunk of stream) {\n\t\tchunks.push(Buffer.from(chunk))\n\t}\n\treturn Buffer.concat(chunks).toString('utf-8')\n}\n"],"mappings":";;;;;;;;;AAMA,MAAa,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCxB,SAAgB,aAAa,KAAqB;AACjD,QAAO,6BAA6B,OAAO,KAAK,IAAI,CAAC,SAAS,SAAS;;;;;;ACnCxE,SAAgB,WAAW,OAAuB;AACjD,QAAO,MACL,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,SAAS,CACvB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OAAO;;;AAIxB,SAAgB,gBAAgB,MAAc,KAAwB;CACrE,MAAM,aAAa,aAAa,SAAS;AACzC,QAAO;EACN;EACA,qCAAqC,WAAW,IAAI,WAAW,CAAC;EAChE;EACA,oDAAoD,WAAW,KAAK,CAAC;EACrE;EACA,+CAA+C,WAAW;EAC1D,CAAC,KAAK,KAAK;;;;;ACnBb,MAAa,SAAS,OAA8B,IAAI,SAAS,MAAM,WAAW,GAAG,GAAG,CAAC;AAEzF,eAAsB,YAA6B;CAClD,MAAM,SAAmB,EAAE;AAC3B,YAAW,MAAM,SAAS,QAAQ,MACjC,QAAO,KAAK,OAAO,KAAK,MAAM,CAAC;AAEhC,QAAO,OAAO,OAAO,OAAO,CAAC,SAAS,QAAQ;;AAY/C,SAAgB,aACf,KACA,MAMiB;CACjB,MAAM,CAAC,SAAS,GAAG,QAAQ;AAC3B,KAAI,CAAC,QAAS,OAAM,IAAI,MAAM,8CAA8C;CAE5E,MAAM,OAAOA,MAAU,SAAS,MAAM;EACrC,KAAK,MAAM;EACX,OAAO;GAAC,MAAM,SAAS;GAAU,MAAM,UAAU;GAAU,MAAM,UAAU;GAAS;EACpF,CAAC;AAOF,QAAO;EACN,IAAI,MAAM;AACT,UAAO,KAAK;;EAEb,IAAI,SAAS;AACZ,UAAO,KAAK;;EAEb,IAAI,SAAS;AACZ,UAAO,KAAK;;EAEb,IAAI,QAAQ;AACX,UAAO,KAAK;;EAEb,KAAK,QAAyB;AAC7B,UAAO,KAAK,KAAK,OAAO;;EAEzB,QArBc,IAAI,SAAiB,SAAS,WAAW;AACvD,QAAK,GAAG,UAAU,SAAS,QAAQ,QAAQ,EAAE,CAAC;AAC9C,QAAK,GAAG,SAAS,OAAO;IACvB;EAmBD"}
|
package/package.json
CHANGED
|
@@ -1,88 +1,102 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
2
|
+
"name": "remobi",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Monitor and control your coding agents from your phone. Touch controls for tmux over the web.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"remobi": "dist/cli.mjs"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/src/index.d.mts",
|
|
12
|
+
"default": "./dist/src/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"./config": {
|
|
15
|
+
"types": "./dist/src/config.d.mts",
|
|
16
|
+
"default": "./dist/src/config.mjs"
|
|
17
|
+
},
|
|
18
|
+
"./types": {
|
|
19
|
+
"types": "./dist/src/types.d.mts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/",
|
|
24
|
+
"styles/",
|
|
25
|
+
"src/pwa/icons/",
|
|
26
|
+
"README.md",
|
|
27
|
+
"CHANGELOG.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"provenance": true
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=22.0.0"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/connorads/remobi.git"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/connorads/remobi",
|
|
41
|
+
"bugs": "https://github.com/connorads/remobi/issues",
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build:overlay": "tsx scripts/build-overlay.ts",
|
|
44
|
+
"build:dist": "tsdown && pnpm run build:overlay",
|
|
45
|
+
"build": "tsx cli.ts build",
|
|
46
|
+
"check": "biome check .",
|
|
47
|
+
"check:fix": "biome check --fix .",
|
|
48
|
+
"lint:knip": "knip",
|
|
49
|
+
"lint:ox": "oxlint --import-plugin --promise-plugin",
|
|
50
|
+
"lint:publint": "publint",
|
|
51
|
+
"lint:typos": "typos",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:coverage": "vitest run --coverage",
|
|
54
|
+
"release": "semantic-release",
|
|
55
|
+
"prepublishOnly": "pnpm run lint:ox && pnpm run lint:knip && pnpm run build:dist && pnpm run lint:publint"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@biomejs/biome": "^1.9.0",
|
|
59
|
+
"@happy-dom/global-registrator": "^20.6.1",
|
|
60
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
61
|
+
"@semantic-release/git": "^10.0.1",
|
|
62
|
+
"@types/node": "^22.0.0",
|
|
63
|
+
"@types/ws": "^8.18.0",
|
|
64
|
+
"esbuild": "^0.25.0",
|
|
65
|
+
"knip": "^5.85.0",
|
|
66
|
+
"oxlint": "^1.50.0",
|
|
67
|
+
"publint": "^0.3.17",
|
|
68
|
+
"semantic-release": "^25.0.3",
|
|
69
|
+
"tsdown": "^0.20.0",
|
|
70
|
+
"tsx": "^4.19.0",
|
|
71
|
+
"typescript": "^5.9.3",
|
|
72
|
+
"vitest": "^3.0.0"
|
|
73
|
+
},
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"author": "Connor",
|
|
76
|
+
"keywords": [
|
|
77
|
+
"ttyd",
|
|
78
|
+
"tmux",
|
|
79
|
+
"terminal",
|
|
80
|
+
"mobile",
|
|
81
|
+
"overlay",
|
|
82
|
+
"touch",
|
|
83
|
+
"node",
|
|
84
|
+
"agents",
|
|
85
|
+
"claude",
|
|
86
|
+
"remote",
|
|
87
|
+
"pwa"
|
|
88
|
+
],
|
|
89
|
+
"dependencies": {
|
|
90
|
+
"@hono/node-server": "^1.14.0",
|
|
91
|
+
"@hono/node-ws": "^1.1.0",
|
|
92
|
+
"hono": "^4.7.0",
|
|
93
|
+
"valibot": "^1.2.0",
|
|
94
|
+
"ws": "^8.18.0"
|
|
95
|
+
},
|
|
96
|
+
"pnpm": {
|
|
97
|
+
"onlyBuiltDependencies": [
|
|
98
|
+
"@biomejs/biome",
|
|
99
|
+
"esbuild"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node-compat-BzXgbTV9.mjs","names":["nodeSpawn"],"sources":["../src/pwa/icon.ts","../src/pwa/meta-tags.ts","../src/util/node-compat.ts"],"sourcesContent":["/**\n * SVG icon for remobi PWA.\n * Dark rounded-rect background (#1e1e2e catppuccin mocha base),\n * green chevron (›) in #a6e3a1 (catppuccin green),\n * underscore cursor in #89b4fa (catppuccin blue).\n */\nexport const ICON_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <rect width=\"512\" height=\"512\" rx=\"80\" ry=\"80\" fill=\"#1e1e2e\"/>\n <text x=\"100\" y=\"330\" font-family=\"monospace\" font-size=\"260\" font-weight=\"bold\" fill=\"#a6e3a1\">›</text>\n <text x=\"195\" y=\"400\" font-family=\"monospace\" font-size=\"140\" font-weight=\"bold\" fill=\"#89b4fa\">_</text>\n</svg>`\n\n/** Convert SVG string to a data URI */\nexport function svgToDataUri(svg: string): string {\n\treturn `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`\n}\n","import type { PwaConfig } from '../types'\nimport { ICON_SVG, svgToDataUri } from './icon'\n\n/** Escape a string for safe use in HTML attribute values */\nexport function escapeAttr(value: string): string {\n\treturn value\n\t\t.replace(/&/g, '&')\n\t\t.replace(/\"/g, '"')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n}\n\n/** Generate PWA HTML to inject into </head> */\nexport function generatePwaHtml(name: string, pwa: PwaConfig): string {\n\tconst svgDataUri = svgToDataUri(ICON_SVG)\n\treturn [\n\t\t`<link rel=\"manifest\" href=\"/manifest.json\">`,\n\t\t`<meta name=\"theme-color\" content=\"${escapeAttr(pwa.themeColor)}\">`,\n\t\t`<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">`,\n\t\t`<meta name=\"apple-mobile-web-app-title\" content=\"${escapeAttr(name)}\">`,\n\t\t`<link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\">`,\n\t\t`<link rel=\"icon\" type=\"image/svg+xml\" href=\"${svgDataUri}\">`,\n\t].join('\\n')\n}\n","import { spawn as nodeSpawn } from 'node:child_process'\nimport type { Readable } from 'node:stream'\n\nexport const sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms))\n\nexport async function readStdin(): Promise<string> {\n\tconst chunks: Buffer[] = []\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(Buffer.from(chunk))\n\t}\n\treturn Buffer.concat(chunks).toString('utf-8')\n}\n\nexport interface SpawnedProcess {\n\treadonly pid: number | undefined\n\treadonly stdout: Readable | null\n\treadonly stderr: Readable | null\n\treadonly stdin: NodeJS.WritableStream | null\n\tkill(signal?: NodeJS.Signals): boolean\n\treadonly exited: Promise<number>\n}\n\nexport function spawnProcess(\n\tcmd: readonly string[],\n\topts?: {\n\t\tcwd?: string\n\t\tstdin?: 'ignore' | 'pipe'\n\t\tstdout?: 'ignore' | 'pipe'\n\t\tstderr?: 'ignore' | 'pipe'\n\t},\n): SpawnedProcess {\n\tconst [command, ...args] = cmd\n\tif (!command) throw new Error('spawnProcess requires at least one argument')\n\n\tconst proc = nodeSpawn(command, args, {\n\t\tcwd: opts?.cwd,\n\t\tstdio: [opts?.stdin ?? 'ignore', opts?.stdout ?? 'ignore', opts?.stderr ?? 'ignore'],\n\t})\n\n\tconst exited = new Promise<number>((resolve, reject) => {\n\t\tproc.on('close', (code) => resolve(code ?? 1))\n\t\tproc.on('error', reject)\n\t})\n\n\treturn {\n\t\tget pid() {\n\t\t\treturn proc.pid\n\t\t},\n\t\tget stdout() {\n\t\t\treturn proc.stdout\n\t\t},\n\t\tget stderr() {\n\t\t\treturn proc.stderr\n\t\t},\n\t\tget stdin() {\n\t\t\treturn proc.stdin\n\t\t},\n\t\tkill(signal?: NodeJS.Signals) {\n\t\t\treturn proc.kill(signal)\n\t\t},\n\t\texited,\n\t}\n}\n\nexport async function collectStream(stream: Readable | null): Promise<string> {\n\tif (!stream) return ''\n\tconst chunks: Buffer[] = []\n\tfor await (const chunk of stream) {\n\t\tchunks.push(Buffer.from(chunk))\n\t}\n\treturn Buffer.concat(chunks).toString('utf-8')\n}\n"],"mappings":";;;;;;;;;AAMA,MAAa,WAAW;;;;;;AAOxB,SAAgB,aAAa,KAAqB;AACjD,QAAO,6BAA6B,OAAO,KAAK,IAAI,CAAC,SAAS,SAAS;;;;;;ACVxE,SAAgB,WAAW,OAAuB;AACjD,QAAO,MACL,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,SAAS,CACvB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OAAO;;;AAIxB,SAAgB,gBAAgB,MAAc,KAAwB;CACrE,MAAM,aAAa,aAAa,SAAS;AACzC,QAAO;EACN;EACA,qCAAqC,WAAW,IAAI,WAAW,CAAC;EAChE;EACA,oDAAoD,WAAW,KAAK,CAAC;EACrE;EACA,+CAA+C,WAAW;EAC1D,CAAC,KAAK,KAAK;;;;;ACnBb,MAAa,SAAS,OAA8B,IAAI,SAAS,MAAM,WAAW,GAAG,GAAG,CAAC;AAEzF,eAAsB,YAA6B;CAClD,MAAM,SAAmB,EAAE;AAC3B,YAAW,MAAM,SAAS,QAAQ,MACjC,QAAO,KAAK,OAAO,KAAK,MAAM,CAAC;AAEhC,QAAO,OAAO,OAAO,OAAO,CAAC,SAAS,QAAQ;;AAY/C,SAAgB,aACf,KACA,MAMiB;CACjB,MAAM,CAAC,SAAS,GAAG,QAAQ;AAC3B,KAAI,CAAC,QAAS,OAAM,IAAI,MAAM,8CAA8C;CAE5E,MAAM,OAAOA,MAAU,SAAS,MAAM;EACrC,KAAK,MAAM;EACX,OAAO;GAAC,MAAM,SAAS;GAAU,MAAM,UAAU;GAAU,MAAM,UAAU;GAAS;EACpF,CAAC;AAOF,QAAO;EACN,IAAI,MAAM;AACT,UAAO,KAAK;;EAEb,IAAI,SAAS;AACZ,UAAO,KAAK;;EAEb,IAAI,SAAS;AACZ,UAAO,KAAK;;EAEb,IAAI,QAAQ;AACX,UAAO,KAAK;;EAEb,KAAK,QAAyB;AAC7B,UAAO,KAAK,KAAK,OAAO;;EAEzB,QArBc,IAAI,SAAiB,SAAS,WAAW;AACvD,QAAK,GAAG,UAAU,SAAS,QAAQ,QAAQ,EAAE,CAAC;AAC9C,QAAK,GAAG,SAAS,OAAO;IACvB;EAmBD"}
|