opencode-mobile 1.1.0 → 1.2.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.
Files changed (99) hide show
  1. package/bin/audit +31 -0
  2. package/bin/qr +13 -0
  3. package/dist/index.d.ts +11 -4
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +482 -5
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/cli/endpoint-tester.d.ts +19 -0
  8. package/dist/src/cli/endpoint-tester.d.ts.map +1 -0
  9. package/dist/src/cli/endpoint-tester.js +233 -0
  10. package/dist/src/cli/endpoint-tester.js.map +1 -0
  11. package/dist/src/cli/index.d.ts +20 -0
  12. package/dist/src/cli/index.d.ts.map +1 -0
  13. package/dist/src/cli/index.js +166 -0
  14. package/dist/src/cli/index.js.map +1 -0
  15. package/dist/src/cli/push-tester.d.ts +16 -0
  16. package/dist/src/cli/push-tester.d.ts.map +1 -0
  17. package/dist/src/cli/push-tester.js +293 -0
  18. package/dist/src/cli/push-tester.js.map +1 -0
  19. package/dist/src/cli/qr.d.ts +5 -0
  20. package/dist/src/cli/qr.d.ts.map +1 -0
  21. package/dist/src/cli/qr.js +127 -0
  22. package/dist/src/cli/qr.js.map +1 -0
  23. package/dist/src/cli/report.d.ts +25 -0
  24. package/dist/src/cli/report.d.ts.map +1 -0
  25. package/dist/src/cli/report.js +215 -0
  26. package/dist/src/cli/report.js.map +1 -0
  27. package/dist/src/cli/server-manager.d.ts +28 -0
  28. package/dist/src/cli/server-manager.d.ts.map +1 -0
  29. package/dist/src/cli/server-manager.js +340 -0
  30. package/dist/src/cli/server-manager.js.map +1 -0
  31. package/dist/src/cli/test-runner.d.ts +16 -0
  32. package/dist/src/cli/test-runner.d.ts.map +1 -0
  33. package/dist/src/cli/test-runner.js +201 -0
  34. package/dist/src/cli/test-runner.js.map +1 -0
  35. package/dist/src/cli/tunnel-qr.d.ts +8 -0
  36. package/dist/src/cli/tunnel-qr.d.ts.map +1 -0
  37. package/dist/src/cli/tunnel-qr.js +163 -0
  38. package/dist/src/cli/tunnel-qr.js.map +1 -0
  39. package/dist/src/cli/tunnel-tester.d.ts +22 -0
  40. package/dist/src/cli/tunnel-tester.d.ts.map +1 -0
  41. package/dist/src/cli/tunnel-tester.js +360 -0
  42. package/dist/src/cli/tunnel-tester.js.map +1 -0
  43. package/dist/src/cli/types.d.ts +112 -0
  44. package/dist/src/cli/types.d.ts.map +1 -0
  45. package/dist/src/cli/types.js +5 -0
  46. package/dist/src/cli/types.js.map +1 -0
  47. package/dist/src/push/index.d.ts +1 -0
  48. package/dist/src/push/index.d.ts.map +1 -1
  49. package/dist/src/push/index.js +1 -0
  50. package/dist/src/push/index.js.map +1 -1
  51. package/dist/src/push/notification-handler.d.ts +58 -0
  52. package/dist/src/push/notification-handler.d.ts.map +1 -0
  53. package/dist/src/push/notification-handler.js +110 -0
  54. package/dist/src/push/notification-handler.js.map +1 -0
  55. package/dist/src/tunnel/cloudflare.d.ts +32 -3
  56. package/dist/src/tunnel/cloudflare.d.ts.map +1 -1
  57. package/dist/src/tunnel/cloudflare.js +102 -32
  58. package/dist/src/tunnel/cloudflare.js.map +1 -1
  59. package/dist/src/tunnel/localtunnel.d.ts +28 -1
  60. package/dist/src/tunnel/localtunnel.d.ts.map +1 -1
  61. package/dist/src/tunnel/localtunnel.js +53 -11
  62. package/dist/src/tunnel/localtunnel.js.map +1 -1
  63. package/dist/src/tunnel/metadata.d.ts +29 -0
  64. package/dist/src/tunnel/metadata.d.ts.map +1 -0
  65. package/dist/src/tunnel/metadata.js +83 -0
  66. package/dist/src/tunnel/metadata.js.map +1 -0
  67. package/dist/src/tunnel/ngrok.d.ts +12 -0
  68. package/dist/src/tunnel/ngrok.d.ts.map +1 -1
  69. package/dist/src/tunnel/ngrok.js +72 -29
  70. package/dist/src/tunnel/ngrok.js.map +1 -1
  71. package/dist/src/tunnel/qrcode.d.ts +8 -0
  72. package/dist/src/tunnel/qrcode.d.ts.map +1 -1
  73. package/dist/src/tunnel/qrcode.js +60 -9
  74. package/dist/src/tunnel/qrcode.js.map +1 -1
  75. package/package.json +21 -3
  76. package/dist/push-notifications.d.ts +0 -4
  77. package/dist/push-notifications.d.ts.map +0 -1
  78. package/dist/push-notifications.js +0 -260
  79. package/dist/push-notifications.js.map +0 -1
  80. package/dist/reverse-proxy.d.ts +0 -9
  81. package/dist/reverse-proxy.d.ts.map +0 -1
  82. package/dist/reverse-proxy.js +0 -78
  83. package/dist/reverse-proxy.js.map +0 -1
  84. package/dist/sdk-logger.d.ts +0 -19
  85. package/dist/sdk-logger.d.ts.map +0 -1
  86. package/dist/sdk-logger.js +0 -103
  87. package/dist/sdk-logger.js.map +0 -1
  88. package/dist/src/tunnel/index.d.ts +0 -35
  89. package/dist/src/tunnel/index.d.ts.map +0 -1
  90. package/dist/src/tunnel/index.js +0 -191
  91. package/dist/src/tunnel/index.js.map +0 -1
  92. package/dist/src/utils/index.d.ts +0 -5
  93. package/dist/src/utils/index.d.ts.map +0 -1
  94. package/dist/src/utils/index.js +0 -5
  95. package/dist/src/utils/index.js.map +0 -1
  96. package/dist/src/utils/port.d.ts +0 -12
  97. package/dist/src/utils/port.d.ts.map +0 -1
  98. package/dist/src/utils/port.js +0 -41
  99. package/dist/src/utils/port.js.map +0 -1
package/bin/audit ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * OpenCode Mobile Plugin - Endpoint Audit Utility
5
+ * Run with: npx opencode-mobile audit
6
+ */
7
+
8
+ import { main as auditMain } from "../dist/src/cli/index.js";
9
+ import { main as qrMain } from "../dist/src/cli/qr.js";
10
+
11
+ const args = process.argv.slice(2);
12
+ const subcommand = args[0];
13
+
14
+ const run = async () => {
15
+ if (subcommand === "qr") {
16
+ await qrMain(args.slice(1));
17
+ return;
18
+ }
19
+
20
+ if (subcommand === "audit") {
21
+ await auditMain(args.slice(1));
22
+ return;
23
+ }
24
+
25
+ await auditMain(args);
26
+ };
27
+
28
+ run().catch((error) => {
29
+ console.error("Fatal error:", error instanceof Error ? error.message : String(error));
30
+ process.exit(1);
31
+ });
package/bin/qr ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * OpenCode Mobile Plugin - Tunnel QR Utility
5
+ * Run with: npx opencode-mobile-qr /path/to/tunnels.json
6
+ */
7
+
8
+ import { main } from "../dist/src/cli/qr.js";
9
+
10
+ main().catch((error) => {
11
+ console.error("Fatal error:", error instanceof Error ? error.message : String(error));
12
+ process.exit(1);
13
+ });
package/dist/index.d.ts CHANGED
@@ -1,5 +1,12 @@
1
- export { PushNotificationPlugin, default } from "./push-notifications";
2
- export * from "./src/tunnel";
3
- export * from "./src/push";
4
- export * from "./src/utils";
1
+ /**
2
+ * opencode-mobile plugin - LAN-only push notification server
3
+ *
4
+ * Architecture:
5
+ * - Plugin server: LAN only (127.0.0.1) - handles /push-token and /tunnel endpoints
6
+ * - Tunnel: Points directly to OpenCode server (not through plugin)
7
+ * - Mobile connects: tunnel → OpenCode (SSE), or LAN → plugin (push tokens)
8
+ */
9
+ import type { Plugin } from "@opencode-ai/plugin";
10
+ export declare const PushNotificationPlugin: Plugin;
11
+ export default PushNotificationPlugin;
5
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAyZlD,eAAO,MAAM,sBAAsB,EAAE,MA4FpC,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,483 @@
1
- // Single entry point for opencode-mobile plugin
2
- export { PushNotificationPlugin, default } from "./push-notifications";
3
- export * from "./src/tunnel";
4
- export * from "./src/push";
5
- export * from "./src/utils";
1
+ /**
2
+ * opencode-mobile plugin - LAN-only push notification server
3
+ *
4
+ * Architecture:
5
+ * - Plugin server: LAN only (127.0.0.1) - handles /push-token and /tunnel endpoints
6
+ * - Tunnel: Points directly to OpenCode server (not through plugin)
7
+ * - Mobile connects: tunnel → OpenCode (SSE), or LAN → plugin (push tokens)
8
+ */
9
+ const DEBUG_ENABLED = process.env.OPENCODE_MOBILE_DEBUG === "1";
10
+ const debugLog = (...args) => {
11
+ if (DEBUG_ENABLED) {
12
+ console.log(...args);
13
+ }
14
+ };
15
+ debugLog("\n=== opencode-mobile DEV ===");
16
+ debugLog("LAN-only architecture: plugin handles push tokens, tunnel goes to OpenCode directly");
17
+ debugLog("[PushPlugin][Mobile] Entry loaded: index.ts");
18
+ import * as fs from "fs";
19
+ import * as path from "path";
20
+ import http from "http";
21
+ import { tool } from "@opencode-ai/plugin";
22
+ import { loadTokens, saveTokens } from "./src/push/token-store";
23
+ import { startLocaltunnel, stopLocaltunnel, getLocaltunnelUrl } from "./src/tunnel/localtunnel";
24
+ import { displayQRCode, generateQRCodeAscii, generateQRCodeAsciiPlain } from "./src/tunnel/qrcode";
25
+ import { startNgrokTunnel, stopNgrokTunnel } from "./src/tunnel/ngrok";
26
+ import { updateTunnelMetadata, clearTunnelMetadata, loadTunnelMetadata } from "./src/tunnel/metadata";
27
+ // Server state
28
+ let httpServer = null;
29
+ let activeTunnel = null;
30
+ const cors = {
31
+ "Access-Control-Allow-Origin": "*",
32
+ "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
33
+ "Access-Control-Allow-Headers": "Content-Type",
34
+ };
35
+ const MOBILE_COMMAND = "mobile";
36
+ function getMobileCommandMarkdown() {
37
+ return [
38
+ "---",
39
+ "description: OpenCode Mobile (QR + push token)",
40
+ "---",
41
+ "Call the `mobile` tool.",
42
+ "",
43
+ "Command arguments: $ARGUMENTS",
44
+ "",
45
+ "- If $ARGUMENTS is non-empty, call the tool with { token: \"$ARGUMENTS\" }.",
46
+ "- If $ARGUMENTS is empty, call the tool with no args to print the QR.",
47
+ "",
48
+ "Examples:",
49
+ "- `/mobile`",
50
+ "- `/mobile ExpoPushToken[xxxxxxxxxxxxxx]`",
51
+ ].join("\n");
52
+ }
53
+ async function ensureMobileCommandExists(ctx) {
54
+ const rawCtx = ctx;
55
+ const directory = rawCtx?.directory ?? rawCtx?.worktree;
56
+ if (!directory) {
57
+ return;
58
+ }
59
+ const client = rawCtx?.client ?? rawCtx?.sdk ?? rawCtx;
60
+ const commandApi = client?.Command ?? client?.command;
61
+ const listCommands = commandApi?.list?.bind(commandApi);
62
+ if (typeof listCommands === "function") {
63
+ try {
64
+ const result = await listCommands({
65
+ query: directory ? { directory } : undefined,
66
+ });
67
+ const commands = result?.data ?? result;
68
+ if (Array.isArray(commands) && commands.some((c) => c?.name === MOBILE_COMMAND)) {
69
+ return;
70
+ }
71
+ }
72
+ catch (error) {
73
+ debugLog("[PushPlugin] Failed to list commands:", error);
74
+ }
75
+ }
76
+ try {
77
+ const commandsDir = path.join(directory, ".opencode", "commands");
78
+ const commandPath = path.join(commandsDir, `${MOBILE_COMMAND}.md`);
79
+ if (fs.existsSync(commandPath)) {
80
+ return;
81
+ }
82
+ fs.mkdirSync(commandsDir, { recursive: true });
83
+ fs.writeFileSync(commandPath, getMobileCommandMarkdown(), "utf-8");
84
+ console.log(`[PushPlugin] Installed /${MOBILE_COMMAND} command at ${commandPath}`);
85
+ }
86
+ catch (error) {
87
+ console.error(`[PushPlugin] Failed to install /${MOBILE_COMMAND} command:`, error);
88
+ }
89
+ }
90
+ function formatMobileQrMessage(url, qr) {
91
+ if (!qr) {
92
+ return url;
93
+ }
94
+ return `${qr}\n${url}`;
95
+ }
96
+ function loadTunnelUrlFromPath(tunnelPath) {
97
+ try {
98
+ if (!fs.existsSync(tunnelPath)) {
99
+ return null;
100
+ }
101
+ const raw = fs.readFileSync(tunnelPath, "utf-8");
102
+ const data = JSON.parse(raw);
103
+ if (typeof data.url === "string" && data.url.startsWith("http")) {
104
+ return data.url;
105
+ }
106
+ }
107
+ catch (error) {
108
+ console.error("[PushPlugin] Failed to read tunnel path:", error);
109
+ }
110
+ return null;
111
+ }
112
+ const mobileTool = tool({
113
+ description: "Generate a mobile connection QR code",
114
+ args: {
115
+ url: tool.schema.string().optional().describe("Tunnel URL to render as QR"),
116
+ tunnelPath: tool.schema
117
+ .string()
118
+ .optional()
119
+ .describe("Path to tunnel.json containing a URL"),
120
+ token: tool.schema
121
+ .string()
122
+ .optional()
123
+ .describe("Push token to register/update for notifications"),
124
+ },
125
+ async execute(args) {
126
+ const rawToken = args.token?.trim();
127
+ if (rawToken) {
128
+ const result = registerPushToken(rawToken);
129
+ const action = result.added ? "Registered" : "Updated";
130
+ return `Push token ${action.toLowerCase()}.`;
131
+ }
132
+ const rawUrl = args.url?.trim();
133
+ const urlFromPath = args.tunnelPath ? loadTunnelUrlFromPath(args.tunnelPath) : null;
134
+ const metadataUrl = loadTunnelMetadata().url;
135
+ const url = rawUrl || urlFromPath || metadataUrl || "";
136
+ if (!url || !url.startsWith("http")) {
137
+ return "No tunnel URL found.";
138
+ }
139
+ const qr = await generateQRCodeAsciiPlain(url) || await generateQRCodeAscii(url);
140
+ return formatMobileQrMessage(url, qr);
141
+ },
142
+ });
143
+ function registerPushToken(token) {
144
+ const trimmed = token.trim();
145
+ const tokens = loadTokens();
146
+ const existingIndex = tokens.findIndex((t) => t.token === trimmed || t.deviceId === trimmed);
147
+ const now = new Date().toISOString();
148
+ const newToken = {
149
+ token: trimmed,
150
+ platform: "ios",
151
+ deviceId: trimmed,
152
+ registeredAt: now,
153
+ };
154
+ if (existingIndex >= 0) {
155
+ tokens[existingIndex] = { ...tokens[existingIndex], ...newToken };
156
+ saveTokens(tokens);
157
+ return { added: false, total: tokens.length };
158
+ }
159
+ tokens.push(newToken);
160
+ saveTokens(tokens);
161
+ return { added: true, total: tokens.length };
162
+ }
163
+ /**
164
+ * Handle push-token requests (LAN only)
165
+ */
166
+ async function handlePushToken(req, res) {
167
+ let body = "";
168
+ req.on("data", (chunk) => { body += chunk; });
169
+ await new Promise((resolve) => req.on("end", resolve));
170
+ if (req.url === "/push-token" && req.method === "POST") {
171
+ try {
172
+ const data = JSON.parse(body);
173
+ const { token, platform, deviceId } = data;
174
+ if (!token || !deviceId) {
175
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
176
+ res.end(JSON.stringify({ error: "Missing fields" }));
177
+ return;
178
+ }
179
+ const validPlatform = (platform === "ios" || platform === "android") ? platform : "ios";
180
+ const tokens = loadTokens();
181
+ const idx = tokens.findIndex((t) => t.deviceId === deviceId);
182
+ const newToken = { token, platform: validPlatform, deviceId, registeredAt: new Date().toISOString() };
183
+ if (idx >= 0)
184
+ tokens[idx] = newToken;
185
+ else
186
+ tokens.push(newToken);
187
+ saveTokens(tokens);
188
+ console.log("[Push] Token registered:", deviceId);
189
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
190
+ res.end(JSON.stringify({ success: true }));
191
+ return;
192
+ }
193
+ catch {
194
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
195
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
196
+ return;
197
+ }
198
+ }
199
+ if (req.url === "/push-token" && req.method === "GET") {
200
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
201
+ res.end(JSON.stringify({ count: loadTokens().length }));
202
+ return;
203
+ }
204
+ if (req.url === "/push-token" && req.method === "DELETE") {
205
+ try {
206
+ const data = JSON.parse(body);
207
+ const { deviceId } = data;
208
+ if (!deviceId) {
209
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
210
+ res.end(JSON.stringify({ error: "Missing deviceId" }));
211
+ return;
212
+ }
213
+ saveTokens(loadTokens().filter((t) => t.deviceId !== deviceId));
214
+ console.log("[Push] Token removed:", deviceId);
215
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
216
+ res.end(JSON.stringify({ success: true }));
217
+ return;
218
+ }
219
+ catch {
220
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
221
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
222
+ return;
223
+ }
224
+ }
225
+ // 404 for other push-token paths
226
+ res.writeHead(404, cors);
227
+ res.end("Not found");
228
+ }
229
+ /**
230
+ * Handle tunnel requests (LAN only)
231
+ */
232
+ async function handleTunnel(req, res, openCodePort) {
233
+ let body = "";
234
+ if (req.method === "POST") {
235
+ req.on("data", (chunk) => { body += chunk; });
236
+ await new Promise((resolve) => req.on("end", resolve));
237
+ }
238
+ if (req.url === "/tunnel" && req.method === "POST") {
239
+ try {
240
+ const data = JSON.parse(body);
241
+ const targetPort = data.port || openCodePort;
242
+ console.log("[Tunnel] Starting to port:", targetPort);
243
+ let tunnel;
244
+ try {
245
+ tunnel = await startNgrokTunnel({ port: targetPort });
246
+ console.log("[Tunnel] Ngrok started:", tunnel.url);
247
+ }
248
+ catch (ngrokError) {
249
+ console.log("[Tunnel] Ngrok failed, trying localtunnel...");
250
+ tunnel = await startLocaltunnel({ port: targetPort });
251
+ console.log("[Tunnel] Localtunnel started:", tunnel.url);
252
+ }
253
+ activeTunnel = tunnel;
254
+ await displayQRCode(tunnel.url);
255
+ // Save tunnel metadata to .config/opencode/tunnel.json
256
+ updateTunnelMetadata(tunnel.url, tunnel.tunnelId, tunnel.provider, tunnel.port, targetPort);
257
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
258
+ res.end(JSON.stringify({
259
+ success: true,
260
+ type: tunnel.provider,
261
+ url: tunnel.url,
262
+ tunnelId: tunnel.tunnelId,
263
+ port: tunnel.port,
264
+ targetPort: targetPort,
265
+ note: "Tunnel points directly to OpenCode server"
266
+ }));
267
+ return;
268
+ }
269
+ catch (error) {
270
+ console.error("[Tunnel] Failed:", error.message);
271
+ res.writeHead(500, { ...cors, "Content-Type": "application/json" });
272
+ res.end(JSON.stringify({ error: error.message }));
273
+ return;
274
+ }
275
+ }
276
+ if (req.url === "/tunnel" && req.method === "DELETE") {
277
+ try {
278
+ if (activeTunnel?.provider === "ngrok") {
279
+ await stopNgrokTunnel();
280
+ }
281
+ else {
282
+ await stopLocaltunnel();
283
+ }
284
+ activeTunnel = null;
285
+ // Clear tunnel metadata from .config/opencode/tunnel.json
286
+ clearTunnelMetadata();
287
+ console.log("[Tunnel] Stopped");
288
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
289
+ res.end(JSON.stringify({ success: true }));
290
+ return;
291
+ }
292
+ catch (error) {
293
+ res.writeHead(500, { ...cors, "Content-Type": "application/json" });
294
+ res.end(JSON.stringify({ error: error.message }));
295
+ return;
296
+ }
297
+ }
298
+ if (req.url === "/tunnel" && req.method === "GET") {
299
+ // Load stored metadata from .config/opencode/tunnel.json
300
+ const storedMetadata = loadTunnelMetadata();
301
+ if (activeTunnel) {
302
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
303
+ res.end(JSON.stringify({
304
+ type: activeTunnel.provider,
305
+ url: activeTunnel.url,
306
+ tunnelId: activeTunnel.tunnelId,
307
+ port: activeTunnel.port,
308
+ targetPort: openCodePort,
309
+ metadata: storedMetadata
310
+ }));
311
+ return;
312
+ }
313
+ const localtunnelUrl = getLocaltunnelUrl();
314
+ if (localtunnelUrl) {
315
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
316
+ res.end(JSON.stringify({
317
+ type: "localtunnel",
318
+ url: localtunnelUrl,
319
+ tunnelId: localtunnelUrl.split("://")[1].split(".")[0],
320
+ metadata: storedMetadata
321
+ }));
322
+ return;
323
+ }
324
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
325
+ res.end(JSON.stringify({
326
+ type: "none",
327
+ url: null,
328
+ metadata: storedMetadata
329
+ }));
330
+ return;
331
+ }
332
+ // 404 for other tunnel paths
333
+ res.writeHead(404, cors);
334
+ res.end("Not found");
335
+ }
336
+ /**
337
+ * Start LAN-only HTTP server
338
+ * Returns true if server started successfully, false if port was in use
339
+ */
340
+ async function startServer(port, openCodePort) {
341
+ return new Promise((resolve) => {
342
+ httpServer = http.createServer((clientReq, clientRes) => {
343
+ // CORS preflight
344
+ if (clientReq.method === "OPTIONS") {
345
+ clientRes.writeHead(204, cors);
346
+ clientRes.end();
347
+ return;
348
+ }
349
+ const url = clientReq.url || "";
350
+ // Handle /push-token endpoints (LAN only)
351
+ if (url.startsWith("/push-token")) {
352
+ handlePushToken(clientReq, clientRes);
353
+ return;
354
+ }
355
+ // Handle /tunnel endpoints (LAN only)
356
+ if (url.startsWith("/tunnel")) {
357
+ handleTunnel(clientReq, clientRes, openCodePort);
358
+ return;
359
+ }
360
+ // Everything else: 404 (LAN only, no proxy)
361
+ clientRes.writeHead(404, cors);
362
+ clientRes.end("Not found - LAN-only server");
363
+ });
364
+ httpServer.on("error", (err) => {
365
+ if (err.code === "EADDRINUSE") {
366
+ debugLog("[Push] Port in use, skipping");
367
+ resolve(false);
368
+ }
369
+ else {
370
+ console.error("[Push] Failed:", err.message);
371
+ resolve(false);
372
+ }
373
+ });
374
+ // Listen on 127.0.0.1 only (LAN only, not exposed externally)
375
+ httpServer.listen(port, "127.0.0.1", () => {
376
+ console.log(`[Push] LAN-only server running on port ${port}`);
377
+ console.log(`[Push] /push-token/* → push token management`);
378
+ console.log(`[Push] /tunnel/* → tunnel management`);
379
+ console.log(`[Push] Tunnel target: OpenCode on port ${openCodePort}`);
380
+ resolve(true);
381
+ });
382
+ });
383
+ }
384
+ export const PushNotificationPlugin = async (ctx) => {
385
+ debugLog("[PushPlugin][Mobile] Initialized");
386
+ await ensureMobileCommandExists(ctx);
387
+ // Check if we're running in "serve" mode (subcommand, not option)
388
+ const isServeMode = process.argv.includes("serve");
389
+ debugLog("[PushPlugin] isServeMode:", isServeMode);
390
+ debugLog("[PushPlugin] process.argv:", process.argv.join(", "));
391
+ if (!isServeMode) {
392
+ debugLog("[PushPlugin] Not in serve mode, skipping plugin");
393
+ return {
394
+ tool: {
395
+ mobile: mobileTool,
396
+ },
397
+ event: async ({ event }) => {
398
+ if (event.type === "command.executed") {
399
+ debugLog("[PushPlugin] command.executed payload:", JSON.stringify(event.properties));
400
+ }
401
+ },
402
+ };
403
+ }
404
+ const openCodePort = Number(ctx.serverUrl?.port) || 4096;
405
+ const pluginPort = openCodePort + 1; // Plugin on next port
406
+ debugLog("[DEV] openCodePort:", openCodePort, "| pluginPort:", pluginPort);
407
+ // Start LAN-only server
408
+ const serverStarted = await startServer(pluginPort, openCodePort);
409
+ // Only start tunnel if server started successfully (port wasn't in use)
410
+ if (!serverStarted) {
411
+ debugLog("[PushPlugin] Server already running, skipping plugin initialization");
412
+ return {
413
+ tool: {
414
+ mobile: mobileTool,
415
+ },
416
+ event: async () => {
417
+ // No-op when another instance is running
418
+ },
419
+ };
420
+ }
421
+ // Auto-start tunnel pointing to OpenCode DIRECTLY (not through plugin!)
422
+ debugLog("[DEV] Auto-starting tunnel...");
423
+ try {
424
+ const tunnel = await startNgrokTunnel({ port: openCodePort });
425
+ debugLog("[DEV] Tunnel started:", tunnel.url);
426
+ activeTunnel = tunnel;
427
+ await displayQRCode(tunnel.url);
428
+ // Save tunnel metadata to .config/opencode/tunnel.json
429
+ updateTunnelMetadata(tunnel.url, tunnel.tunnelId, tunnel.provider, tunnel.port, openCodePort);
430
+ }
431
+ catch (ngrokError) {
432
+ debugLog("[DEV] Ngrok failed, trying localtunnel...");
433
+ try {
434
+ const tunnel = await startLocaltunnel({ port: openCodePort });
435
+ debugLog("[DEV] Tunnel started:", tunnel.url);
436
+ activeTunnel = tunnel;
437
+ await displayQRCode(tunnel.url);
438
+ // Save tunnel metadata to .config/opencode/tunnel.json
439
+ updateTunnelMetadata(tunnel.url, tunnel.tunnelId, tunnel.provider, tunnel.port, openCodePort);
440
+ }
441
+ catch (localError) {
442
+ console.error("[DEV] All tunnels failed:", localError.message);
443
+ }
444
+ }
445
+ return {
446
+ tool: {
447
+ mobile: mobileTool,
448
+ },
449
+ event: async ({ event }) => {
450
+ if (event.type === "command.executed") {
451
+ debugLog("[PushPlugin] command.executed payload:", JSON.stringify(event.properties));
452
+ }
453
+ },
454
+ };
455
+ };
456
+ export default PushNotificationPlugin;
457
+ if (import.meta.main) {
458
+ const main = async () => {
459
+ const args = process.argv.slice(2);
460
+ if (args.length === 0) {
461
+ const metadata = loadTunnelMetadata();
462
+ if (!metadata.url) {
463
+ console.log("No tunnel URL found.");
464
+ process.exit(1);
465
+ }
466
+ const qr = await generateQRCodeAscii(metadata.url);
467
+ if (qr) {
468
+ console.log(`${qr}\n${metadata.url}`);
469
+ }
470
+ else {
471
+ console.log(metadata.url);
472
+ }
473
+ }
474
+ else {
475
+ const token = args.join(" ");
476
+ const result = registerPushToken(token);
477
+ const action = result.added ? "Registered" : "Updated";
478
+ console.log(`Push token ${action.toLowerCase()}.`);
479
+ }
480
+ };
481
+ main();
482
+ }
6
483
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Endpoint tester for push-token and tunnel endpoints
3
+ */
4
+ import type { AuditOptions, EndpointTest, TestResult } from "./types.js";
5
+ /**
6
+ * Test all endpoints
7
+ */
8
+ export declare function testEndpoints(port: number, options: AuditOptions): Promise<{
9
+ tests: EndpointTest[];
10
+ results: TestResult[];
11
+ }>;
12
+ /**
13
+ * Quick health check for endpoints
14
+ */
15
+ export declare function quickHealthCheck(port: number): Promise<{
16
+ healthy: boolean;
17
+ endpoints: string[];
18
+ }>;
19
+ //# sourceMappingURL=endpoint-tester.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint-tester.d.ts","sourceRoot":"","sources":["../../../src/cli/endpoint-tester.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,YAAY,CAAC;AAQpB;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC,CAyM3D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAwBpD"}