@myerscarpenter/quest-dev 1.4.0 → 2.0.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.
Files changed (151) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.github/workflows/docs.yml +45 -0
  3. package/.github/workflows/publish.yml +11 -1
  4. package/README.md +27 -0
  5. package/build/cast/decoder.d.ts +48 -0
  6. package/build/cast/decoder.d.ts.map +1 -0
  7. package/build/cast/decoder.js +152 -0
  8. package/build/cast/decoder.js.map +1 -0
  9. package/build/cast/session.d.ts +87 -0
  10. package/build/cast/session.d.ts.map +1 -0
  11. package/build/cast/session.js +565 -0
  12. package/build/cast/session.js.map +1 -0
  13. package/build/commands/logcat.d.ts.map +1 -1
  14. package/build/commands/logcat.js +7 -6
  15. package/build/commands/logcat.js.map +1 -1
  16. package/build/commands/open.d.ts.map +1 -1
  17. package/build/commands/open.js +9 -4
  18. package/build/commands/open.js.map +1 -1
  19. package/build/commands/screenshot.d.ts.map +1 -1
  20. package/build/commands/screenshot.js +17 -20
  21. package/build/commands/screenshot.js.map +1 -1
  22. package/build/commands/stay-awake.d.ts +2 -15
  23. package/build/commands/stay-awake.d.ts.map +1 -1
  24. package/build/commands/stay-awake.js +14 -77
  25. package/build/commands/stay-awake.js.map +1 -1
  26. package/build/daemon/cast-manager.d.ts +42 -0
  27. package/build/daemon/cast-manager.d.ts.map +1 -0
  28. package/build/daemon/cast-manager.js +243 -0
  29. package/build/daemon/cast-manager.js.map +1 -0
  30. package/build/daemon/client.d.ts +40 -0
  31. package/build/daemon/client.d.ts.map +1 -0
  32. package/build/daemon/client.js +133 -0
  33. package/build/daemon/client.js.map +1 -0
  34. package/build/daemon/daemon.d.ts +20 -0
  35. package/build/daemon/daemon.d.ts.map +1 -0
  36. package/build/daemon/daemon.js +130 -0
  37. package/build/daemon/daemon.js.map +1 -0
  38. package/build/daemon/deploy.d.ts +44 -0
  39. package/build/daemon/deploy.d.ts.map +1 -0
  40. package/build/daemon/deploy.js +230 -0
  41. package/build/daemon/deploy.js.map +1 -0
  42. package/build/daemon/logcat-manager.d.ts +39 -0
  43. package/build/daemon/logcat-manager.d.ts.map +1 -0
  44. package/build/daemon/logcat-manager.js +194 -0
  45. package/build/daemon/logcat-manager.js.map +1 -0
  46. package/build/daemon/server.d.ts +19 -0
  47. package/build/daemon/server.d.ts.map +1 -0
  48. package/build/daemon/server.js +482 -0
  49. package/build/daemon/server.js.map +1 -0
  50. package/build/daemon/stay-awake-manager.d.ts +22 -0
  51. package/build/daemon/stay-awake-manager.d.ts.map +1 -0
  52. package/build/daemon/stay-awake-manager.js +74 -0
  53. package/build/daemon/stay-awake-manager.js.map +1 -0
  54. package/build/index.js +285 -45
  55. package/build/index.js.map +1 -1
  56. package/build/public/dashboard.js +749 -0
  57. package/build/public/index.html +12 -0
  58. package/build/public/style.css +106 -0
  59. package/build/utils/adb.d.ts +12 -0
  60. package/build/utils/adb.d.ts.map +1 -1
  61. package/build/utils/adb.js +116 -51
  62. package/build/utils/adb.js.map +1 -1
  63. package/build/utils/casting-apk.d.ts +40 -0
  64. package/build/utils/casting-apk.d.ts.map +1 -0
  65. package/build/utils/casting-apk.js +252 -0
  66. package/build/utils/casting-apk.js.map +1 -0
  67. package/build/utils/config.d.ts +5 -3
  68. package/build/utils/config.d.ts.map +1 -1
  69. package/build/utils/config.js +18 -38
  70. package/build/utils/config.js.map +1 -1
  71. package/build/utils/exec.d.ts +5 -0
  72. package/build/utils/exec.d.ts.map +1 -1
  73. package/build/utils/exec.js +17 -0
  74. package/build/utils/exec.js.map +1 -1
  75. package/build/utils/filename.d.ts +7 -1
  76. package/build/utils/filename.d.ts.map +1 -1
  77. package/build/utils/filename.js +17 -2
  78. package/build/utils/filename.js.map +1 -1
  79. package/build/utils/filename.test.js +33 -1
  80. package/build/utils/filename.test.js.map +1 -1
  81. package/build/utils/jpeg-comment.d.ts +14 -0
  82. package/build/utils/jpeg-comment.d.ts.map +1 -0
  83. package/build/utils/jpeg-comment.js +28 -0
  84. package/build/utils/jpeg-comment.js.map +1 -0
  85. package/build/utils/test-properties.d.ts +34 -0
  86. package/build/utils/test-properties.d.ts.map +1 -0
  87. package/build/utils/test-properties.js +73 -0
  88. package/build/utils/test-properties.js.map +1 -0
  89. package/build/utils/verbose.d.ts +3 -0
  90. package/build/utils/verbose.d.ts.map +1 -0
  91. package/build/utils/verbose.js +13 -0
  92. package/build/utils/verbose.js.map +1 -0
  93. package/package.json +11 -5
  94. package/packages/cast2-protocol/README.md +86 -0
  95. package/packages/cast2-protocol/docs/_config.yml +4 -0
  96. package/packages/cast2-protocol/docs/feature-flags.md +102 -0
  97. package/packages/cast2-protocol/docs/index.md +24 -0
  98. package/packages/cast2-protocol/docs/open-investigations.md +149 -0
  99. package/packages/cast2-protocol/docs/protocol.md +602 -0
  100. package/packages/cast2-protocol/package.json +46 -0
  101. package/packages/cast2-protocol/src/constants.ts +65 -0
  102. package/packages/cast2-protocol/src/index.ts +7 -0
  103. package/packages/cast2-protocol/src/mgik.ts +69 -0
  104. package/packages/cast2-protocol/src/mud.ts +294 -0
  105. package/packages/cast2-protocol/src/pose.ts +99 -0
  106. package/packages/cast2-protocol/src/resolutions.ts +34 -0
  107. package/packages/cast2-protocol/src/types.ts +64 -0
  108. package/packages/cast2-protocol/src/xrsp.ts +73 -0
  109. package/packages/cast2-protocol/tests/mgik.test.ts +80 -0
  110. package/packages/cast2-protocol/tests/mud.test.ts +295 -0
  111. package/packages/cast2-protocol/tests/pose.test.ts +173 -0
  112. package/packages/cast2-protocol/tests/xrsp.test.ts +90 -0
  113. package/packages/cast2-protocol/tsconfig.json +20 -0
  114. package/pnpm-workspace.yaml +2 -0
  115. package/src/cast/decoder.ts +178 -0
  116. package/src/cast/session.ts +708 -0
  117. package/src/commands/logcat.ts +6 -5
  118. package/src/commands/open.ts +10 -3
  119. package/src/commands/screenshot.ts +19 -13
  120. package/src/commands/stay-awake.ts +22 -91
  121. package/src/daemon/adbkit-apkreader.d.ts +14 -0
  122. package/src/daemon/cast-manager.ts +282 -0
  123. package/src/daemon/client.ts +166 -0
  124. package/src/daemon/daemon.ts +169 -0
  125. package/src/daemon/deploy.ts +307 -0
  126. package/src/daemon/logcat-manager.ts +229 -0
  127. package/src/daemon/server.ts +595 -0
  128. package/src/daemon/stay-awake-manager.ts +83 -0
  129. package/src/index.ts +340 -56
  130. package/src/public/dashboard.js +288 -0
  131. package/src/public/index.html +12 -0
  132. package/src/public/style.css +106 -0
  133. package/src/utils/adb.ts +129 -42
  134. package/src/utils/casting-apk.ts +276 -0
  135. package/src/utils/config.ts +18 -36
  136. package/src/utils/exec.ts +20 -0
  137. package/src/utils/filename.test.ts +41 -1
  138. package/src/utils/filename.ts +18 -2
  139. package/src/utils/jpeg-comment.ts +30 -0
  140. package/src/utils/test-properties.ts +94 -0
  141. package/src/utils/verbose.ts +14 -0
  142. package/tests/cast/auto-layer.test.ts +87 -0
  143. package/tests/cast/decoder.test.ts +82 -0
  144. package/tests/cast/session-restart.test.ts +107 -0
  145. package/tests/config.test.ts +17 -22
  146. package/tests/daemon/api-status.test.ts +82 -0
  147. package/tests/daemon/cast-manager.test.ts +69 -0
  148. package/tests/daemon/mjpeg-stream.test.ts +144 -0
  149. package/tests/daemon/pose-endpoint.test.ts +63 -0
  150. package/tests/daemon/start-guard.test.ts +77 -0
  151. package/vitest.config.ts +10 -0
@@ -0,0 +1,243 @@
1
+ /**
2
+ * CastManager: lazy-loaded manager for cast sessions within the daemon.
3
+ * Wraps CastSession with start/stop lifecycle and SSE broadcasting.
4
+ * Server state is the single source of truth — pushed to clients via SSE.
5
+ */
6
+ import { EventEmitter } from "node:events";
7
+ import { checkADBPath, getAdbDevice } from "../utils/adb.js";
8
+ import { execCommand } from "../utils/exec.js";
9
+ import { verbose } from "../utils/verbose.js";
10
+ import { CastSession } from "../cast/session.js";
11
+ import { ensureCastingInstalled } from "../utils/casting-apk.js";
12
+ import { resolveResolution } from "@myerscarpenter/cast2-protocol";
13
+ function round4(n) {
14
+ return Math.round(n * 10000) / 10000;
15
+ }
16
+ function round1(n) {
17
+ return Math.round(n * 10) / 10;
18
+ }
19
+ function deg(rad) {
20
+ return (rad * 180) / Math.PI;
21
+ }
22
+ export class CastManager extends EventEmitter {
23
+ session = null;
24
+ sseClients = new Set();
25
+ questIp = null;
26
+ configuredDevice;
27
+ statsInterval = null;
28
+ starting = false;
29
+ constructor(device) {
30
+ super();
31
+ this.configuredDevice = device;
32
+ }
33
+ get isActive() {
34
+ return this.session !== null && this.session.connected;
35
+ }
36
+ getSession() {
37
+ return this.session;
38
+ }
39
+ /** Build full status snapshot from current session state. */
40
+ getStatus() {
41
+ const session = this.session;
42
+ if (!session) {
43
+ return { connected: false, running: false };
44
+ }
45
+ const p = session.pose;
46
+ return {
47
+ connected: session.connected,
48
+ running: session.running,
49
+ width: session.width,
50
+ height: session.height,
51
+ frame_count: session.frameCount,
52
+ bytes: session.byteCount,
53
+ fps: session.fps,
54
+ elapsed: session.elapsedSeconds,
55
+ has_frame: session.getScreenshot() !== null,
56
+ eye: session.eye === 0 ? "right" : session.eye === 2 ? "stereo" : "left",
57
+ pose_loop: session.poseLoopActive,
58
+ pose: {
59
+ x: round4(p.x),
60
+ y: round4(p.y),
61
+ z: round4(p.z),
62
+ yaw: round4(p.yaw),
63
+ pitch: round4(p.pitch),
64
+ yaw_deg: round1(deg(p.yaw)),
65
+ pitch_deg: round1(deg(p.pitch)),
66
+ },
67
+ };
68
+ }
69
+ async start(opts = {}) {
70
+ if (this.session?.connected) {
71
+ return; // Already active
72
+ }
73
+ if (this.starting) {
74
+ throw new Error("Cast start already in progress");
75
+ }
76
+ this.starting = true;
77
+ try {
78
+ // Stop any lingering session
79
+ if (this.session) {
80
+ await this.stopSession();
81
+ }
82
+ checkADBPath();
83
+ // Check for connected devices
84
+ const output = await execCommand("adb", ["devices"]);
85
+ const lines = output.trim().split("\n").slice(1);
86
+ const devices = lines.filter((line) => line.trim() && !line.includes("List of devices"));
87
+ if (devices.length === 0) {
88
+ throw new Error("No ADB devices connected");
89
+ }
90
+ // Get Quest IP
91
+ const questIp = await this.getQuestIp();
92
+ this.questIp = questIp;
93
+ // Ensure casting service APK is installed on Quest
94
+ // Use the ADB device serial (USB or configured), not the WiFi IP
95
+ const adbDevice = getAdbDevice() ?? await this.getAdbSerial() ?? `${questIp}:5555`;
96
+ await ensureCastingInstalled(adbDevice);
97
+ const listenPort = opts.listenPort ?? 4445;
98
+ const { width, height } = resolveResolution(opts.resolution, opts.width, opts.height);
99
+ // Create and start session
100
+ const session = new CastSession({ listenPort, width, height });
101
+ this.session = session;
102
+ // Wire session events → SSE broadcast
103
+ session.on("connected", () => this.broadcastStatus());
104
+ session.on("disconnected", () => this.broadcastStatus());
105
+ session.on("pose-loop", () => this.broadcastStatus());
106
+ // Complete all async setup before starting periodic work
107
+ await session.bind();
108
+ if (session.listenPort !== listenPort) {
109
+ verbose(`Port ${listenPort} in use, listening on ${session.listenPort}`);
110
+ }
111
+ await session.adbSetup(questIp);
112
+ await session.start(questIp);
113
+ // Stats interval created AFTER all async ops succeed
114
+ this.statsInterval = setInterval(() => {
115
+ if (session.connected) {
116
+ this.broadcastStatus();
117
+ }
118
+ }, 500);
119
+ verbose("Quest connected, casting active");
120
+ }
121
+ finally {
122
+ this.starting = false;
123
+ }
124
+ }
125
+ async stop() {
126
+ await this.stopSession();
127
+ this.broadcastStatus();
128
+ }
129
+ async restart() {
130
+ if (!this.session) {
131
+ await this.start();
132
+ return;
133
+ }
134
+ this.broadcastToast("Restarting cast\u2026");
135
+ await this.session.restart();
136
+ }
137
+ async stopSession() {
138
+ if (this.statsInterval) {
139
+ clearInterval(this.statsInterval);
140
+ this.statsInterval = null;
141
+ }
142
+ if (this.session) {
143
+ try {
144
+ await this.session.stop();
145
+ }
146
+ catch {
147
+ // Best effort
148
+ }
149
+ this.session = null;
150
+ }
151
+ }
152
+ /** Get the first connected ADB device serial (e.g. USB serial or IP:port) */
153
+ async getAdbSerial() {
154
+ const output = await execCommand("adb", ["devices"]);
155
+ const lines = output.trim().split("\n").slice(1);
156
+ const first = lines.find((l) => l.includes("device"));
157
+ if (!first)
158
+ return null;
159
+ return first.split("\t")[0].trim();
160
+ }
161
+ async getQuestIp() {
162
+ // If a device IP was configured, use it directly (strip :port if present)
163
+ if (this.configuredDevice) {
164
+ const ip = this.configuredDevice.split(":")[0];
165
+ verbose(`Using configured device: ${ip}`);
166
+ return ip;
167
+ }
168
+ const devOutput = await execCommand("adb", ["devices"]);
169
+ const devLines = devOutput.trim().split("\n").slice(1);
170
+ const firstDevice = devLines.find((l) => l.includes("device"));
171
+ if (!firstDevice) {
172
+ throw new Error("No authorized ADB device found");
173
+ }
174
+ const deviceId = firstDevice.split("\t")[0].trim();
175
+ try {
176
+ const ip = await execCommand("adb", [
177
+ "-s",
178
+ deviceId,
179
+ "shell",
180
+ "ip addr show wlan0 | grep 'inet ' | tr -s ' ' | cut -f3 -d' ' | cut -f1 -d/",
181
+ ]);
182
+ const trimmed = ip.trim();
183
+ if (trimmed && !trimmed.includes("error")) {
184
+ return trimmed;
185
+ }
186
+ }
187
+ catch {
188
+ // Fallback
189
+ }
190
+ return deviceId.split(":")[0];
191
+ }
192
+ // --- SSE ---
193
+ broadcast(event, data) {
194
+ const msg = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
195
+ for (const res of this.sseClients) {
196
+ try {
197
+ res.write(msg);
198
+ }
199
+ catch {
200
+ this.sseClients.delete(res);
201
+ }
202
+ }
203
+ }
204
+ /** Broadcast full status snapshot as SSE "status" event. */
205
+ broadcastStatus() {
206
+ this.broadcast("status", this.getStatus());
207
+ }
208
+ broadcastToast(msg) {
209
+ this.broadcast("toast", { message: msg });
210
+ }
211
+ addSSEClient(res) {
212
+ this.sseClients.add(res);
213
+ }
214
+ removeSSEClient(res) {
215
+ this.sseClients.delete(res);
216
+ }
217
+ // --- Cleanup ---
218
+ cleanup() {
219
+ if (this.statsInterval) {
220
+ clearInterval(this.statsInterval);
221
+ this.statsInterval = null;
222
+ }
223
+ if (this.session) {
224
+ try {
225
+ this.session.stop();
226
+ }
227
+ catch {
228
+ // Best effort sync cleanup
229
+ }
230
+ this.session = null;
231
+ }
232
+ for (const res of this.sseClients) {
233
+ try {
234
+ res.end();
235
+ }
236
+ catch {
237
+ // Ignore
238
+ }
239
+ }
240
+ this.sseClients.clear();
241
+ }
242
+ }
243
+ //# sourceMappingURL=cast-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cast-manager.js","sourceRoot":"","sources":["../../src/daemon/cast-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Daemon discovery + HTTP client for CLI commands.
3
+ * Auto-starts daemon if needed, then calls HTTP endpoints.
4
+ */
5
+ import { type DaemonInfo } from "./daemon.js";
6
+ /** Read daemon.json and verify PID is alive */
7
+ export declare function discoverDaemon(): DaemonInfo | null;
8
+ export interface SpawnDaemonOptions {
9
+ port: number;
10
+ device?: string;
11
+ host?: string;
12
+ idleTimeout?: number;
13
+ lowBattery?: number;
14
+ }
15
+ /** Resolve daemon port from CLI flag → config → default */
16
+ export declare function resolvePort(cliPort?: number): number;
17
+ /** Resolve device from CLI flag → config */
18
+ export declare function resolveDevice(cliDevice?: string): string | undefined;
19
+ /** Resolve host from CLI flag → config → default */
20
+ export declare function resolveHost(cliHost?: string): string;
21
+ export interface EnsureDaemonOptions {
22
+ port?: number;
23
+ device?: string;
24
+ host?: string;
25
+ idleTimeout?: number;
26
+ lowBattery?: number;
27
+ }
28
+ /** Ensure daemon is running, starting it if needed. Returns connection info. */
29
+ export declare function ensureDaemon(opts?: EnsureDaemonOptions): Promise<DaemonInfo>;
30
+ /** Make an HTTP request to the daemon */
31
+ export declare function daemonFetch(info: DaemonInfo, path: string, options?: {
32
+ method?: string;
33
+ body?: unknown;
34
+ }): Promise<unknown>;
35
+ /** Convenience: ensure daemon + fetch */
36
+ export declare function daemonRequest(path: string, options?: {
37
+ method?: string;
38
+ body?: unknown;
39
+ }): Promise<unknown>;
40
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/daemon/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAgB3D,+CAA+C;AAC/C,wBAAgB,cAAc,IAAI,UAAU,GAAG,IAAI,CAmBlD;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmCD,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAIpD;AAMD,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIpE;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gFAAgF;AAChF,wBAAsB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,CAetF;AAED,yCAAyC;AACzC,wBAAsB,WAAW,CAC/B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5C,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,yCAAyC;AACzC,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5C,OAAO,CAAC,OAAO,CAAC,CAGlB"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Daemon discovery + HTTP client for CLI commands.
3
+ * Auto-starts daemon if needed, then calls HTTP endpoints.
4
+ */
5
+ import { readFileSync, existsSync, unlinkSync } from "node:fs";
6
+ import { spawn } from "node:child_process";
7
+ import { DAEMON_JSON } from "./daemon.js";
8
+ import { loadConfig } from "../utils/config.js";
9
+ import { verbose } from "../utils/verbose.js";
10
+ const DEFAULT_PORT = 19872;
11
+ /** Check if a PID is alive */
12
+ function isPidAlive(pid) {
13
+ try {
14
+ process.kill(pid, 0);
15
+ return true;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ }
21
+ /** Read daemon.json and verify PID is alive */
22
+ export function discoverDaemon() {
23
+ if (!existsSync(DAEMON_JSON)) {
24
+ return null;
25
+ }
26
+ try {
27
+ const info = JSON.parse(readFileSync(DAEMON_JSON, "utf-8"));
28
+ if (isPidAlive(info.pid)) {
29
+ return info;
30
+ }
31
+ verbose(`Stale daemon.json (PID ${info.pid} is dead), cleaning up`);
32
+ try {
33
+ unlinkSync(DAEMON_JSON);
34
+ }
35
+ catch {
36
+ // Best effort
37
+ }
38
+ }
39
+ catch {
40
+ // Corrupt file
41
+ }
42
+ return null;
43
+ }
44
+ /** Spawn daemon as a detached background process */
45
+ async function spawnDaemon(opts) {
46
+ const args = [process.argv[1], "daemon", "--port", String(opts.port)];
47
+ if (opts.device) {
48
+ args.push("--device", opts.device);
49
+ }
50
+ if (opts.host) {
51
+ args.push("--host", opts.host);
52
+ }
53
+ if (opts.idleTimeout !== undefined) {
54
+ args.push("--idle-timeout", String(opts.idleTimeout));
55
+ }
56
+ if (opts.lowBattery !== undefined) {
57
+ args.push("--low-battery", String(opts.lowBattery));
58
+ }
59
+ const child = spawn(process.execPath, args, {
60
+ detached: true,
61
+ stdio: "ignore",
62
+ });
63
+ child.unref();
64
+ // Wait for daemon.json to appear (up to 5s)
65
+ for (let i = 0; i < 50; i++) {
66
+ await new Promise((r) => setTimeout(r, 100));
67
+ const info = discoverDaemon();
68
+ if (info) {
69
+ return info;
70
+ }
71
+ }
72
+ throw new Error("Daemon failed to start (timed out waiting for daemon.json)");
73
+ }
74
+ /** Resolve daemon port from CLI flag → config → default */
75
+ export function resolvePort(cliPort) {
76
+ if (cliPort)
77
+ return cliPort;
78
+ const config = loadConfig();
79
+ return config.port ?? DEFAULT_PORT;
80
+ }
81
+ function printDaemonUrl(port, host = "127.0.0.1") {
82
+ console.log(`Daemon: http://${host}:${port} (API: /help)`);
83
+ }
84
+ /** Resolve device from CLI flag → config */
85
+ export function resolveDevice(cliDevice) {
86
+ if (cliDevice)
87
+ return cliDevice;
88
+ const config = loadConfig();
89
+ return config.device;
90
+ }
91
+ /** Resolve host from CLI flag → config → default */
92
+ export function resolveHost(cliHost) {
93
+ if (cliHost)
94
+ return cliHost;
95
+ const config = loadConfig();
96
+ return config.host ?? "127.0.0.1";
97
+ }
98
+ /** Ensure daemon is running, starting it if needed. Returns connection info. */
99
+ export async function ensureDaemon(opts = {}) {
100
+ const existing = discoverDaemon();
101
+ if (existing) {
102
+ verbose(`Daemon already running (PID: ${existing.pid}, port: ${existing.port})`);
103
+ printDaemonUrl(existing.port);
104
+ return existing;
105
+ }
106
+ const port = resolvePort(opts.port);
107
+ const device = resolveDevice(opts.device);
108
+ const host = resolveHost(opts.host);
109
+ console.log("Starting quest-dev daemon...");
110
+ const info = await spawnDaemon({ port, device, host, idleTimeout: opts.idleTimeout, lowBattery: opts.lowBattery });
111
+ printDaemonUrl(info.port, host);
112
+ return info;
113
+ }
114
+ /** Make an HTTP request to the daemon */
115
+ export async function daemonFetch(info, path, options) {
116
+ const url = `http://127.0.0.1:${info.port}${path}`;
117
+ const fetchOptions = {
118
+ method: options?.method ?? "GET",
119
+ };
120
+ if (options?.body !== undefined) {
121
+ fetchOptions.method = "POST";
122
+ fetchOptions.headers = { "Content-Type": "application/json" };
123
+ fetchOptions.body = JSON.stringify(options.body);
124
+ }
125
+ const response = await fetch(url, fetchOptions);
126
+ return response.json();
127
+ }
128
+ /** Convenience: ensure daemon + fetch */
129
+ export async function daemonRequest(path, options) {
130
+ const info = await ensureDaemon();
131
+ return daemonFetch(info, path, options);
132
+ }
133
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/daemon/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Daemon process entry point.
3
+ * Starts the unified HTTP server, manages lifecycle, writes daemon.json.
4
+ */
5
+ export declare const DAEMON_DIR: string;
6
+ export declare const DAEMON_JSON: string;
7
+ export interface DaemonInfo {
8
+ pid: number;
9
+ port: number;
10
+ startedAt: string;
11
+ }
12
+ export interface StartDaemonOptions {
13
+ port: number;
14
+ device?: string;
15
+ host?: string;
16
+ idleTimeout?: number;
17
+ lowBattery?: number;
18
+ }
19
+ export declare function startDaemon(opts: StartDaemonOptions): Promise<void>;
20
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/daemon/daemon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,eAAO,MAAM,UAAU,QAAkD,CAAC;AAC1E,eAAO,MAAM,WAAW,QAAkC,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuIzE"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Daemon process entry point.
3
+ * Starts the unified HTTP server, manages lifecycle, writes daemon.json.
4
+ */
5
+ import { writeFileSync, unlinkSync, mkdirSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { homedir } from "node:os";
8
+ import { getBatteryInfo, setAdbDevice } from "../utils/adb.js";
9
+ import { loadConfig } from "../utils/config.js";
10
+ import { verbose } from "../utils/verbose.js";
11
+ import { StayAwakeManager } from "./stay-awake-manager.js";
12
+ import { LogcatManager } from "./logcat-manager.js";
13
+ import { CastManager } from "./cast-manager.js";
14
+ import { createDaemonServer } from "./server.js";
15
+ export const DAEMON_DIR = join(homedir(), ".local", "share", "quest-dev");
16
+ export const DAEMON_JSON = join(DAEMON_DIR, "daemon.json");
17
+ export async function startDaemon(opts) {
18
+ const { port } = opts;
19
+ const config = loadConfig();
20
+ const idleTimeout = opts.idleTimeout ?? config.idleTimeout ?? 300000;
21
+ const lowBattery = opts.lowBattery ?? config.lowBattery ?? 10;
22
+ const device = opts.device ?? config.device;
23
+ const host = opts.host ?? config.host ?? "127.0.0.1";
24
+ if (device) {
25
+ setAdbDevice(device);
26
+ }
27
+ const stayAwake = new StayAwakeManager();
28
+ const logcat = new LogcatManager();
29
+ const castManager = new CastManager(device);
30
+ // Idle timer
31
+ let idleHandle = null;
32
+ const resetIdleTimer = () => {
33
+ if (idleHandle)
34
+ clearTimeout(idleHandle);
35
+ idleHandle = setTimeout(() => {
36
+ console.log("Idle timeout reached, shutting down daemon...");
37
+ shutdown();
38
+ }, idleTimeout);
39
+ };
40
+ // Battery monitor
41
+ let batteryInterval = null;
42
+ let lastReportedBucket = -1;
43
+ const startBatteryMonitor = () => {
44
+ batteryInterval = setInterval(async () => {
45
+ try {
46
+ const battery = await getBatteryInfo();
47
+ const currentBucket = Math.floor(battery.level / 5) * 5;
48
+ if (currentBucket !== lastReportedBucket) {
49
+ verbose(`Battery: ${battery.level}% ${battery.state}`);
50
+ lastReportedBucket = currentBucket;
51
+ }
52
+ if (battery.level <= lowBattery && battery.state === "not charging") {
53
+ console.log(`Battery critically low (${battery.level}%), shutting down daemon...`);
54
+ shutdown();
55
+ }
56
+ }
57
+ catch {
58
+ // Device might be unavailable
59
+ }
60
+ }, 60000);
61
+ };
62
+ // Cleanup + shutdown
63
+ let shutdownInProgress = false;
64
+ const shutdown = async () => {
65
+ if (shutdownInProgress)
66
+ return;
67
+ shutdownInProgress = true;
68
+ console.log("Daemon shutting down...");
69
+ if (idleHandle)
70
+ clearTimeout(idleHandle);
71
+ if (batteryInterval)
72
+ clearInterval(batteryInterval);
73
+ // Stop cast
74
+ castManager.cleanup();
75
+ // Restore stay-awake
76
+ stayAwake.cleanupSync();
77
+ // Stop logcat
78
+ logcat.cleanup();
79
+ // Remove daemon.json
80
+ try {
81
+ unlinkSync(DAEMON_JSON);
82
+ }
83
+ catch {
84
+ // Might already be gone
85
+ }
86
+ console.log("Daemon stopped.");
87
+ process.exit(0);
88
+ };
89
+ // Signal handlers
90
+ process.on("SIGINT", shutdown);
91
+ process.on("SIGTERM", shutdown);
92
+ process.on("SIGHUP", shutdown);
93
+ // SIGUSR1 resets idle timer (used by Claude Code hooks)
94
+ process.on("SIGUSR1", () => {
95
+ const now = new Date().toLocaleTimeString();
96
+ console.log(`[${now}] Activity detected, resetting idle timer`);
97
+ resetIdleTimer();
98
+ });
99
+ // Start server
100
+ const server = await createDaemonServer({
101
+ port,
102
+ host,
103
+ stayAwake,
104
+ logcat,
105
+ castManager,
106
+ onActivity: resetIdleTimer,
107
+ onShutdown: () => shutdown(),
108
+ });
109
+ // Get the actual port (Fastify resolves it)
110
+ const address = server.server.address();
111
+ const actualPort = typeof address === "object" && address ? address.port : port;
112
+ // Write daemon.json
113
+ mkdirSync(DAEMON_DIR, { recursive: true });
114
+ const info = {
115
+ pid: process.pid,
116
+ port: actualPort,
117
+ startedAt: new Date().toISOString(),
118
+ };
119
+ writeFileSync(DAEMON_JSON, JSON.stringify(info, null, 2) + "\n");
120
+ console.log(`quest-dev daemon started (PID: ${process.pid}, port: ${actualPort})`);
121
+ console.log(`Idle timeout: ${Math.round(idleTimeout / 1000)}s, low battery: ${lowBattery}%`);
122
+ // Start idle timer + battery monitor
123
+ resetIdleTimer();
124
+ startBatteryMonitor();
125
+ // Keep process alive
126
+ await new Promise((resolve) => {
127
+ process.on("exit", () => resolve());
128
+ });
129
+ }
130
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/daemon/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Deploy handler for the daemon.
3
+ * Extracts package name from APK, installs, launches, checks for crashes.
4
+ */
5
+ import type { StayAwakeManager } from "./stay-awake-manager.js";
6
+ import type { LogcatManager } from "./logcat-manager.js";
7
+ export interface DeployOptions {
8
+ apkPath: string;
9
+ crashWaitMs?: number;
10
+ pin?: string;
11
+ }
12
+ export interface InstallInfo {
13
+ incremental: boolean;
14
+ blocksTransferred?: number;
15
+ totalBlocks?: number;
16
+ bytesTransferred?: number;
17
+ installSecs: number;
18
+ apkSizeMB: number;
19
+ }
20
+ export type DeployResult = {
21
+ ok: true;
22
+ package: string;
23
+ crashed: false;
24
+ logcatFile: string;
25
+ install?: InstallInfo;
26
+ } | {
27
+ ok: false;
28
+ package: string;
29
+ crashed: true;
30
+ logcatFile: string;
31
+ logcatLines?: string[];
32
+ error?: string;
33
+ } | {
34
+ ok: false;
35
+ package: string;
36
+ crashed: false;
37
+ error: string;
38
+ logcatFile?: string;
39
+ };
40
+ /**
41
+ * Run the full deploy sequence.
42
+ */
43
+ export declare function deploy(options: DeployOptions, stayAwake: StayAwakeManager, logcat: LogcatManager): Promise<DeployResult>;
44
+ //# sourceMappingURL=deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/daemon/deploy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAAE,GACzF;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1G;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAwGvF;;GAEG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,gBAAgB,EAC3B,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,CAAC,CAkKvB"}