opencode-mobile 1.0.11 → 1.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.
Files changed (99) hide show
  1. package/bin/audit +31 -0
  2. package/bin/qr +13 -0
  3. package/dist/index.d.ts +11 -3
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +545 -3
  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 +38 -1
  56. package/dist/src/tunnel/cloudflare.d.ts.map +1 -1
  57. package/dist/src/tunnel/cloudflare.js +148 -51
  58. package/dist/src/tunnel/cloudflare.js.map +1 -1
  59. package/dist/src/tunnel/localtunnel.d.ts +32 -1
  60. package/dist/src/tunnel/localtunnel.d.ts.map +1 -1
  61. package/dist/src/tunnel/localtunnel.js +75 -16
  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 +24 -1
  68. package/dist/src/tunnel/ngrok.d.ts.map +1 -1
  69. package/dist/src/tunnel/ngrok.js +381 -20
  70. package/dist/src/tunnel/ngrok.js.map +1 -1
  71. package/dist/src/tunnel/qrcode.d.ts +14 -2
  72. package/dist/src/tunnel/qrcode.d.ts.map +1 -1
  73. package/dist/src/tunnel/qrcode.js +96 -8
  74. package/dist/src/tunnel/qrcode.js.map +1 -1
  75. package/package.json +22 -4
  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 -29
  89. package/dist/src/tunnel/index.d.ts.map +0 -1
  90. package/dist/src/tunnel/index.js +0 -125
  91. package/dist/src/tunnel/index.js.map +0 -1
  92. package/dist/src/utils/port.d.ts +0 -12
  93. package/dist/src/utils/port.d.ts.map +0 -1
  94. package/dist/src/utils/port.js +0 -41
  95. package/dist/src/utils/port.js.map +0 -1
  96. package/dist/tunnel-manager.d.ts +0 -30
  97. package/dist/tunnel-manager.d.ts.map +0 -1
  98. package/dist/tunnel-manager.js +0 -641
  99. package/dist/tunnel-manager.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,4 +1,12 @@
1
- export { PushNotificationPlugin, default } from "./push-notifications";
2
- export * from "./src/tunnel";
3
- export { startProxy, stopProxy } from "./reverse-proxy";
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;
4
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,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;AA4dlD,eAAO,MAAM,sBAAsB,EAAE,MA2GpC,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,546 @@
1
- export { PushNotificationPlugin, default } from "./push-notifications";
2
- export * from "./src/tunnel";
3
- export { startProxy, stopProxy } from "./reverse-proxy";
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
+ const CONFIG_DIR = path.join(process.env.HOME || "", ".config/opencode");
28
+ // Server state
29
+ let httpServer = null;
30
+ let activeTunnel = null;
31
+ const cors = {
32
+ "Access-Control-Allow-Origin": "*",
33
+ "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
34
+ "Access-Control-Allow-Headers": "Content-Type",
35
+ };
36
+ const MOBILE_COMMAND = "mobile";
37
+ function formatMobileQrMessage(url, qr) {
38
+ if (!qr) {
39
+ return url;
40
+ }
41
+ return `${qr}\n${url}`;
42
+ }
43
+ function loadTunnelUrlFromPath(tunnelPath) {
44
+ try {
45
+ if (!fs.existsSync(tunnelPath)) {
46
+ return null;
47
+ }
48
+ const raw = fs.readFileSync(tunnelPath, "utf-8");
49
+ const data = JSON.parse(raw);
50
+ if (typeof data.url === "string" && data.url.startsWith("http")) {
51
+ return data.url;
52
+ }
53
+ }
54
+ catch (error) {
55
+ console.error("[PushPlugin] Failed to read tunnel path:", error);
56
+ }
57
+ return null;
58
+ }
59
+ const mobileTool = tool({
60
+ description: "Generate a mobile connection QR code",
61
+ args: {
62
+ url: tool.schema.string().optional().describe("Tunnel URL to render as QR"),
63
+ tunnelPath: tool.schema
64
+ .string()
65
+ .optional()
66
+ .describe("Path to tunnel.json containing a URL"),
67
+ },
68
+ async execute(args) {
69
+ const rawUrl = args.url?.trim();
70
+ const urlFromPath = args.tunnelPath ? loadTunnelUrlFromPath(args.tunnelPath) : null;
71
+ const metadataUrl = loadTunnelMetadata().url;
72
+ const url = rawUrl || urlFromPath || metadataUrl || "";
73
+ if (!url || !url.startsWith("http")) {
74
+ return "No tunnel URL found.";
75
+ }
76
+ const qr = await generateQRCodeAsciiPlain(url) || await generateQRCodeAscii(url);
77
+ return formatMobileQrMessage(url, qr);
78
+ },
79
+ });
80
+ async function publishReply(ctx, sessionID, message, messageID) {
81
+ try {
82
+ const rawCtx = ctx;
83
+ const client = rawCtx?.client ?? rawCtx?.sdk ?? rawCtx;
84
+ const directory = rawCtx?.directory ?? rawCtx?.worktree;
85
+ const sessionApi = client?.Session ?? client?.session;
86
+ const prompt = sessionApi?.prompt?.bind(sessionApi)
87
+ ?? sessionApi?.message?.bind(sessionApi)
88
+ ?? sessionApi?.create?.bind(sessionApi);
89
+ if (typeof prompt !== "function") {
90
+ debugLog("[PushPlugin] Reply client keys:", Object.keys(client || {}));
91
+ debugLog("[PushPlugin] Reply session keys:", Object.keys(sessionApi || {}));
92
+ throw new Error("Session prompt API unavailable");
93
+ }
94
+ const doPrompt = async () => {
95
+ await prompt({
96
+ path: { id: sessionID },
97
+ query: directory ? { directory } : undefined,
98
+ body: {
99
+ messageID,
100
+ noReply: true,
101
+ parts: [
102
+ {
103
+ type: "text",
104
+ text: message,
105
+ },
106
+ ],
107
+ },
108
+ });
109
+ };
110
+ let attempt = 0;
111
+ while (true) {
112
+ try {
113
+ if (!sessionID) {
114
+ console.log("[PushPlugin] No sessionID to send reply");
115
+ return;
116
+ }
117
+ await doPrompt();
118
+ break;
119
+ }
120
+ catch (error) {
121
+ const errorMessage = error?.message || "";
122
+ const isNotFound = error?.name === "NotFoundError" || errorMessage.includes("Resource not found");
123
+ attempt += 1;
124
+ if (!isNotFound || attempt >= 4) {
125
+ throw error;
126
+ }
127
+ await new Promise((resolve) => setTimeout(resolve, 150 * attempt));
128
+ }
129
+ }
130
+ }
131
+ catch (error) {
132
+ const errorMessage = error?.message || error;
133
+ console.error("[PushPlugin] Failed to publish reply:", errorMessage);
134
+ const rawCtx = ctx;
135
+ const client = rawCtx?.client ?? rawCtx?.sdk ?? rawCtx;
136
+ const tui = client?.tui ?? client?.Tui;
137
+ const showToast = tui?.showToast?.bind(tui);
138
+ const publish = tui?.publish?.bind(tui);
139
+ if (typeof showToast === "function" || typeof publish === "function") {
140
+ const urlMatch = typeof message === "string" ? message.match(/https?:\/\/\S+/) : null;
141
+ const toastMessage = urlMatch ? `QR ready: ${urlMatch[0]}` : "Reply failed. QR printed in terminal.";
142
+ const body = {
143
+ title: "OpenCode Mobile",
144
+ message: toastMessage,
145
+ variant: "warning",
146
+ duration: 8000,
147
+ };
148
+ try {
149
+ if (typeof showToast === "function") {
150
+ await showToast({ body });
151
+ }
152
+ else if (typeof publish === "function") {
153
+ await publish({ body: { type: "tui.toast.show", properties: body } });
154
+ }
155
+ }
156
+ catch (toastError) {
157
+ console.error("[PushPlugin] Failed to show toast:", toastError?.message || toastError);
158
+ }
159
+ }
160
+ }
161
+ }
162
+ async function publishToTui(ctx, text) {
163
+ try {
164
+ const rawCtx = ctx;
165
+ const client = rawCtx?.client ?? rawCtx?.sdk ?? rawCtx;
166
+ const tui = client?.tui ?? client?.Tui;
167
+ const publish = tui?.publish?.bind(tui);
168
+ if (typeof publish !== "function") {
169
+ return;
170
+ }
171
+ await publish({ body: { type: "tui.prompt.append", properties: { text } } });
172
+ }
173
+ catch (error) {
174
+ console.error("[PushPlugin] Failed to publish TUI prompt:", error?.message || error);
175
+ }
176
+ }
177
+ function registerPushToken(token) {
178
+ const trimmed = token.trim();
179
+ const tokens = loadTokens();
180
+ const existingIndex = tokens.findIndex((t) => t.token === trimmed || t.deviceId === trimmed);
181
+ const now = new Date().toISOString();
182
+ const newToken = {
183
+ token: trimmed,
184
+ platform: "ios",
185
+ deviceId: trimmed,
186
+ registeredAt: now,
187
+ };
188
+ if (existingIndex >= 0) {
189
+ tokens[existingIndex] = { ...tokens[existingIndex], ...newToken };
190
+ saveTokens(tokens);
191
+ return { added: false, total: tokens.length };
192
+ }
193
+ tokens.push(newToken);
194
+ saveTokens(tokens);
195
+ return { added: true, total: tokens.length };
196
+ }
197
+ async function handleMobileCommand(ctx, args, sessionID, messageID) {
198
+ const trimmed = args.trim();
199
+ if (!trimmed) {
200
+ const metadata = loadTunnelMetadata();
201
+ if (!metadata.url) {
202
+ debugLog("[Tunnel] No tunnel URL found in tunnel.json");
203
+ await publishReply(ctx, sessionID, "No tunnel URL found.", messageID);
204
+ return;
205
+ }
206
+ debugLog("[Tunnel] /mobile displaying QR for:", metadata.url);
207
+ await displayQRCode(metadata.url);
208
+ const qr = await generateQRCodeAsciiPlain(metadata.url) || await generateQRCodeAscii(metadata.url);
209
+ const message = formatMobileQrMessage(metadata.url, qr);
210
+ await publishToTui(ctx, message);
211
+ await publishReply(ctx, sessionID, message, messageID);
212
+ return;
213
+ }
214
+ const result = registerPushToken(trimmed);
215
+ const action = result.added ? "Registered" : "Updated";
216
+ debugLog(`[Push] ${action} token via /mobile (count=${result.total})`);
217
+ await publishReply(ctx, sessionID, `Push token ${action.toLowerCase()}.`, messageID);
218
+ }
219
+ /**
220
+ * Handle push-token requests (LAN only)
221
+ */
222
+ async function handlePushToken(req, res) {
223
+ let body = "";
224
+ req.on("data", (chunk) => { body += chunk; });
225
+ await new Promise((resolve) => req.on("end", resolve));
226
+ if (req.url === "/push-token" && req.method === "POST") {
227
+ try {
228
+ const data = JSON.parse(body);
229
+ const { token, platform, deviceId } = data;
230
+ if (!token || !deviceId) {
231
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
232
+ res.end(JSON.stringify({ error: "Missing fields" }));
233
+ return;
234
+ }
235
+ const validPlatform = (platform === "ios" || platform === "android") ? platform : "ios";
236
+ const tokens = loadTokens();
237
+ const idx = tokens.findIndex((t) => t.deviceId === deviceId);
238
+ const newToken = { token, platform: validPlatform, deviceId, registeredAt: new Date().toISOString() };
239
+ if (idx >= 0)
240
+ tokens[idx] = newToken;
241
+ else
242
+ tokens.push(newToken);
243
+ saveTokens(tokens);
244
+ console.log("[Push] Token registered:", deviceId);
245
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
246
+ res.end(JSON.stringify({ success: true }));
247
+ return;
248
+ }
249
+ catch {
250
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
251
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
252
+ return;
253
+ }
254
+ }
255
+ if (req.url === "/push-token" && req.method === "GET") {
256
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
257
+ res.end(JSON.stringify({ count: loadTokens().length }));
258
+ return;
259
+ }
260
+ if (req.url === "/push-token" && req.method === "DELETE") {
261
+ try {
262
+ const data = JSON.parse(body);
263
+ const { deviceId } = data;
264
+ if (!deviceId) {
265
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
266
+ res.end(JSON.stringify({ error: "Missing deviceId" }));
267
+ return;
268
+ }
269
+ saveTokens(loadTokens().filter((t) => t.deviceId !== deviceId));
270
+ console.log("[Push] Token removed:", deviceId);
271
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
272
+ res.end(JSON.stringify({ success: true }));
273
+ return;
274
+ }
275
+ catch {
276
+ res.writeHead(400, { ...cors, "Content-Type": "application/json" });
277
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
278
+ return;
279
+ }
280
+ }
281
+ // 404 for other push-token paths
282
+ res.writeHead(404, cors);
283
+ res.end("Not found");
284
+ }
285
+ /**
286
+ * Handle tunnel requests (LAN only)
287
+ */
288
+ async function handleTunnel(req, res, openCodePort) {
289
+ let body = "";
290
+ if (req.method === "POST") {
291
+ req.on("data", (chunk) => { body += chunk; });
292
+ await new Promise((resolve) => req.on("end", resolve));
293
+ }
294
+ if (req.url === "/tunnel" && req.method === "POST") {
295
+ try {
296
+ const data = JSON.parse(body);
297
+ const targetPort = data.port || openCodePort;
298
+ console.log("[Tunnel] Starting to port:", targetPort);
299
+ let tunnel;
300
+ try {
301
+ tunnel = await startNgrokTunnel({ port: targetPort });
302
+ console.log("[Tunnel] Ngrok started:", tunnel.url);
303
+ }
304
+ catch (ngrokError) {
305
+ console.log("[Tunnel] Ngrok failed, trying localtunnel...");
306
+ tunnel = await startLocaltunnel({ port: targetPort });
307
+ console.log("[Tunnel] Localtunnel started:", tunnel.url);
308
+ }
309
+ activeTunnel = tunnel;
310
+ await displayQRCode(tunnel.url);
311
+ // Save tunnel metadata to .config/opencode/tunnel.json
312
+ updateTunnelMetadata(tunnel.url, tunnel.tunnelId, tunnel.provider, tunnel.port, targetPort);
313
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
314
+ res.end(JSON.stringify({
315
+ success: true,
316
+ type: tunnel.provider,
317
+ url: tunnel.url,
318
+ tunnelId: tunnel.tunnelId,
319
+ port: tunnel.port,
320
+ targetPort: targetPort,
321
+ note: "Tunnel points directly to OpenCode server"
322
+ }));
323
+ return;
324
+ }
325
+ catch (error) {
326
+ console.error("[Tunnel] Failed:", error.message);
327
+ res.writeHead(500, { ...cors, "Content-Type": "application/json" });
328
+ res.end(JSON.stringify({ error: error.message }));
329
+ return;
330
+ }
331
+ }
332
+ if (req.url === "/tunnel" && req.method === "DELETE") {
333
+ try {
334
+ if (activeTunnel?.provider === "ngrok") {
335
+ await stopNgrokTunnel();
336
+ }
337
+ else {
338
+ await stopLocaltunnel();
339
+ }
340
+ activeTunnel = null;
341
+ // Clear tunnel metadata from .config/opencode/tunnel.json
342
+ clearTunnelMetadata();
343
+ console.log("[Tunnel] Stopped");
344
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
345
+ res.end(JSON.stringify({ success: true }));
346
+ return;
347
+ }
348
+ catch (error) {
349
+ res.writeHead(500, { ...cors, "Content-Type": "application/json" });
350
+ res.end(JSON.stringify({ error: error.message }));
351
+ return;
352
+ }
353
+ }
354
+ if (req.url === "/tunnel" && req.method === "GET") {
355
+ // Load stored metadata from .config/opencode/tunnel.json
356
+ const storedMetadata = loadTunnelMetadata();
357
+ if (activeTunnel) {
358
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
359
+ res.end(JSON.stringify({
360
+ type: activeTunnel.provider,
361
+ url: activeTunnel.url,
362
+ tunnelId: activeTunnel.tunnelId,
363
+ port: activeTunnel.port,
364
+ targetPort: openCodePort,
365
+ metadata: storedMetadata
366
+ }));
367
+ return;
368
+ }
369
+ const localtunnelUrl = getLocaltunnelUrl();
370
+ if (localtunnelUrl) {
371
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
372
+ res.end(JSON.stringify({
373
+ type: "localtunnel",
374
+ url: localtunnelUrl,
375
+ tunnelId: localtunnelUrl.split("://")[1].split(".")[0],
376
+ metadata: storedMetadata
377
+ }));
378
+ return;
379
+ }
380
+ res.writeHead(200, { ...cors, "Content-Type": "application/json" });
381
+ res.end(JSON.stringify({
382
+ type: "none",
383
+ url: null,
384
+ metadata: storedMetadata
385
+ }));
386
+ return;
387
+ }
388
+ // 404 for other tunnel paths
389
+ res.writeHead(404, cors);
390
+ res.end("Not found");
391
+ }
392
+ /**
393
+ * Start LAN-only HTTP server
394
+ * Returns true if server started successfully, false if port was in use
395
+ */
396
+ async function startServer(port, openCodePort) {
397
+ return new Promise((resolve) => {
398
+ httpServer = http.createServer((clientReq, clientRes) => {
399
+ // CORS preflight
400
+ if (clientReq.method === "OPTIONS") {
401
+ clientRes.writeHead(204, cors);
402
+ clientRes.end();
403
+ return;
404
+ }
405
+ const url = clientReq.url || "";
406
+ // Handle /push-token endpoints (LAN only)
407
+ if (url.startsWith("/push-token")) {
408
+ handlePushToken(clientReq, clientRes);
409
+ return;
410
+ }
411
+ // Handle /tunnel endpoints (LAN only)
412
+ if (url.startsWith("/tunnel")) {
413
+ handleTunnel(clientReq, clientRes, openCodePort);
414
+ return;
415
+ }
416
+ // Everything else: 404 (LAN only, no proxy)
417
+ clientRes.writeHead(404, cors);
418
+ clientRes.end("Not found - LAN-only server");
419
+ });
420
+ httpServer.on("error", (err) => {
421
+ if (err.code === "EADDRINUSE") {
422
+ debugLog("[Push] Port in use, skipping");
423
+ resolve(false);
424
+ }
425
+ else {
426
+ console.error("[Push] Failed:", err.message);
427
+ resolve(false);
428
+ }
429
+ });
430
+ // Listen on 127.0.0.1 only (LAN only, not exposed externally)
431
+ httpServer.listen(port, "127.0.0.1", () => {
432
+ console.log(`[Push] LAN-only server running on port ${port}`);
433
+ console.log(`[Push] /push-token/* → push token management`);
434
+ console.log(`[Push] /tunnel/* → tunnel management`);
435
+ console.log(`[Push] Tunnel target: OpenCode on port ${openCodePort}`);
436
+ resolve(true);
437
+ });
438
+ });
439
+ }
440
+ export const PushNotificationPlugin = async (ctx) => {
441
+ debugLog("[PushPlugin][Mobile] Initialized");
442
+ // Check if we're running in "serve" mode (subcommand, not option)
443
+ const isServeMode = process.argv.includes("serve");
444
+ debugLog("[PushPlugin] isServeMode:", isServeMode);
445
+ debugLog("[PushPlugin] process.argv:", process.argv.join(", "));
446
+ if (!isServeMode) {
447
+ debugLog("[PushPlugin] Not in serve mode, skipping plugin");
448
+ return {
449
+ tool: {
450
+ mobile: mobileTool,
451
+ },
452
+ event: async ({ event }) => {
453
+ if (event.type === "command.executed") {
454
+ debugLog("[PushPlugin] command.executed payload:", JSON.stringify(event.properties));
455
+ }
456
+ if (event.type === "command.executed" && event.properties.name === MOBILE_COMMAND) {
457
+ debugLog("[PushPlugin] Handling /mobile command");
458
+ await handleMobileCommand(ctx, event.properties.arguments || "", event.properties.sessionID, event.properties.messageID);
459
+ }
460
+ },
461
+ };
462
+ }
463
+ const openCodePort = Number(ctx.serverUrl?.port) || 4096;
464
+ const pluginPort = openCodePort + 1; // Plugin on next port
465
+ debugLog("[DEV] openCodePort:", openCodePort, "| pluginPort:", pluginPort);
466
+ // Start LAN-only server
467
+ const serverStarted = await startServer(pluginPort, openCodePort);
468
+ // Only start tunnel if server started successfully (port wasn't in use)
469
+ if (!serverStarted) {
470
+ debugLog("[PushPlugin] Server already running, skipping plugin initialization");
471
+ return {
472
+ tool: {
473
+ mobile: mobileTool,
474
+ },
475
+ event: async ({ event }) => {
476
+ // No-op when another instance is running
477
+ },
478
+ };
479
+ }
480
+ // Auto-start tunnel pointing to OpenCode DIRECTLY (not through plugin!)
481
+ debugLog("[DEV] Auto-starting tunnel...");
482
+ try {
483
+ const tunnel = await startNgrokTunnel({ port: openCodePort });
484
+ debugLog("[DEV] Tunnel started:", tunnel.url);
485
+ activeTunnel = tunnel;
486
+ await displayQRCode(tunnel.url);
487
+ // Save tunnel metadata to .config/opencode/tunnel.json
488
+ updateTunnelMetadata(tunnel.url, tunnel.tunnelId, tunnel.provider, tunnel.port, openCodePort);
489
+ }
490
+ catch (ngrokError) {
491
+ debugLog("[DEV] Ngrok failed, trying localtunnel...");
492
+ try {
493
+ const tunnel = await startLocaltunnel({ port: openCodePort });
494
+ debugLog("[DEV] Tunnel started:", tunnel.url);
495
+ activeTunnel = tunnel;
496
+ await displayQRCode(tunnel.url);
497
+ // Save tunnel metadata to .config/opencode/tunnel.json
498
+ updateTunnelMetadata(tunnel.url, tunnel.tunnelId, tunnel.provider, tunnel.port, openCodePort);
499
+ }
500
+ catch (localError) {
501
+ console.error("[DEV] All tunnels failed:", localError.message);
502
+ }
503
+ }
504
+ return {
505
+ tool: {
506
+ mobile: mobileTool,
507
+ },
508
+ event: async ({ event }) => {
509
+ if (event.type === "command.executed") {
510
+ debugLog("[PushPlugin] command.executed payload:", JSON.stringify(event.properties));
511
+ }
512
+ if (event.type === "command.executed" && event.properties.name === MOBILE_COMMAND) {
513
+ debugLog("[PushPlugin] Handling /mobile command");
514
+ await handleMobileCommand(ctx, event.properties.arguments || "", event.properties.sessionID, event.properties.messageID);
515
+ }
516
+ },
517
+ };
518
+ };
519
+ export default PushNotificationPlugin;
520
+ if (import.meta.main) {
521
+ const main = async () => {
522
+ const args = process.argv.slice(2);
523
+ if (args.length === 0) {
524
+ const metadata = loadTunnelMetadata();
525
+ if (!metadata.url) {
526
+ console.log("No tunnel URL found.");
527
+ process.exit(1);
528
+ }
529
+ const qr = await generateQRCodeAscii(metadata.url);
530
+ if (qr) {
531
+ console.log(`${qr}\n${metadata.url}`);
532
+ }
533
+ else {
534
+ console.log(metadata.url);
535
+ }
536
+ }
537
+ else {
538
+ const token = args.join(" ");
539
+ const result = registerPushToken(token);
540
+ const action = result.added ? "Registered" : "Updated";
541
+ console.log(`Push token ${action.toLowerCase()}.`);
542
+ }
543
+ };
544
+ main();
545
+ }
4
546
  //# 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,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}