opencode-mobile 1.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 (70) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +4 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/push-notifications.d.ts +4 -0
  6. package/dist/push-notifications.d.ts.map +1 -0
  7. package/dist/push-notifications.js +299 -0
  8. package/dist/push-notifications.js.map +1 -0
  9. package/dist/reverse-proxy.d.ts +9 -0
  10. package/dist/reverse-proxy.d.ts.map +1 -0
  11. package/dist/reverse-proxy.js +72 -0
  12. package/dist/reverse-proxy.js.map +1 -0
  13. package/dist/sdk-logger.d.ts +17 -0
  14. package/dist/sdk-logger.d.ts.map +1 -0
  15. package/dist/sdk-logger.js +94 -0
  16. package/dist/sdk-logger.js.map +1 -0
  17. package/dist/src/push/formatter.d.ts +25 -0
  18. package/dist/src/push/formatter.d.ts.map +1 -0
  19. package/dist/src/push/formatter.js +142 -0
  20. package/dist/src/push/formatter.js.map +1 -0
  21. package/dist/src/push/index.d.ts +8 -0
  22. package/dist/src/push/index.d.ts.map +1 -0
  23. package/dist/src/push/index.js +8 -0
  24. package/dist/src/push/index.js.map +1 -0
  25. package/dist/src/push/sender.d.ts +9 -0
  26. package/dist/src/push/sender.d.ts.map +1 -0
  27. package/dist/src/push/sender.js +75 -0
  28. package/dist/src/push/sender.js.map +1 -0
  29. package/dist/src/push/token-store.d.ts +17 -0
  30. package/dist/src/push/token-store.d.ts.map +1 -0
  31. package/dist/src/push/token-store.js +42 -0
  32. package/dist/src/push/token-store.js.map +1 -0
  33. package/dist/src/push/types.d.ts +51 -0
  34. package/dist/src/push/types.d.ts.map +1 -0
  35. package/dist/src/push/types.js +5 -0
  36. package/dist/src/push/types.js.map +1 -0
  37. package/dist/src/tunnel/cloudflare.d.ts +17 -0
  38. package/dist/src/tunnel/cloudflare.d.ts.map +1 -0
  39. package/dist/src/tunnel/cloudflare.js +74 -0
  40. package/dist/src/tunnel/cloudflare.js.map +1 -0
  41. package/dist/src/tunnel/index.d.ts +31 -0
  42. package/dist/src/tunnel/index.d.ts.map +1 -0
  43. package/dist/src/tunnel/index.js +83 -0
  44. package/dist/src/tunnel/index.js.map +1 -0
  45. package/dist/src/tunnel/localtunnel.d.ts +13 -0
  46. package/dist/src/tunnel/localtunnel.d.ts.map +1 -0
  47. package/dist/src/tunnel/localtunnel.js +31 -0
  48. package/dist/src/tunnel/localtunnel.js.map +1 -0
  49. package/dist/src/tunnel/ngrok.d.ts +21 -0
  50. package/dist/src/tunnel/ngrok.d.ts.map +1 -0
  51. package/dist/src/tunnel/ngrok.js +91 -0
  52. package/dist/src/tunnel/ngrok.js.map +1 -0
  53. package/dist/src/tunnel/qrcode.d.ts +12 -0
  54. package/dist/src/tunnel/qrcode.d.ts.map +1 -0
  55. package/dist/src/tunnel/qrcode.js +24 -0
  56. package/dist/src/tunnel/qrcode.js.map +1 -0
  57. package/dist/src/tunnel/types.d.ts +32 -0
  58. package/dist/src/tunnel/types.d.ts.map +1 -0
  59. package/dist/src/tunnel/types.js +5 -0
  60. package/dist/src/tunnel/types.js.map +1 -0
  61. package/dist/src/utils/port.d.ts +12 -0
  62. package/dist/src/utils/port.d.ts.map +1 -0
  63. package/dist/src/utils/port.js +41 -0
  64. package/dist/src/utils/port.js.map +1 -0
  65. package/dist/tunnel-manager.d.ts +30 -0
  66. package/dist/tunnel-manager.d.ts.map +1 -0
  67. package/dist/tunnel-manager.js +639 -0
  68. package/dist/tunnel-manager.js.map +1 -0
  69. package/package.json +60 -0
  70. package/push-notifications.ts +346 -0
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Notification formatting utilities
3
+ */
4
+ import { truncate } from "./token-store";
5
+ /**
6
+ * Extract project path from event
7
+ */
8
+ export function extractProjectPath(event, ctx) {
9
+ const properties = event.properties;
10
+ const { type } = event;
11
+ switch (type) {
12
+ case "session.updated":
13
+ return properties?.info?.directory || null;
14
+ case "message.updated":
15
+ return (properties?.info?.path?.cwd || properties?.info?.path?.root || null);
16
+ case "session.idle":
17
+ case "session.error":
18
+ case "permission.updated":
19
+ return ctx?.directory || ctx?.worktree || null;
20
+ default:
21
+ return (properties?.projectPath ||
22
+ properties?.directory ||
23
+ properties?.info?.directory ||
24
+ properties?.info?.path?.cwd ||
25
+ ctx?.directory ||
26
+ ctx?.worktree ||
27
+ null);
28
+ }
29
+ }
30
+ /**
31
+ * Extract session ID from event
32
+ */
33
+ export function extractSessionId(event) {
34
+ const properties = event.properties;
35
+ return (properties?.sessionId ||
36
+ properties?.sessionID ||
37
+ event?.sessionId ||
38
+ event?.sessionID ||
39
+ properties?.info?.sessionID ||
40
+ properties?.info?.id ||
41
+ null);
42
+ }
43
+ /**
44
+ * Check if event is a child session
45
+ */
46
+ export function isChildSession(event) {
47
+ const properties = event.properties;
48
+ return !!(properties?.parentSessionId ||
49
+ properties?.parentId ||
50
+ properties?.parentSessionID ||
51
+ event?.parentSessionId ||
52
+ event?.parentId ||
53
+ properties?.info?.parentSessionId ||
54
+ properties?.info?.parentId);
55
+ }
56
+ /**
57
+ * Extract last assistant message from event
58
+ */
59
+ export function extractLastAssistantMessage(event) {
60
+ const properties = event.properties;
61
+ if (properties?.messages && Array.isArray(properties.messages)) {
62
+ const assistantMessages = properties.messages.filter((m) => m.role === "assistant" || m.sender === "assistant");
63
+ if (assistantMessages.length > 0) {
64
+ const lastMessage = assistantMessages[assistantMessages.length - 1];
65
+ return lastMessage.content || lastMessage.text || "";
66
+ }
67
+ }
68
+ if (properties?.lastAssistantMessage) {
69
+ return properties.lastAssistantMessage;
70
+ }
71
+ if (properties?.conversation && Array.isArray(properties.conversation)) {
72
+ const assistantMessages = properties.conversation.filter((m) => m.role === "assistant" || m.sender === "assistant");
73
+ if (assistantMessages.length > 0) {
74
+ const lastMessage = assistantMessages[assistantMessages.length - 1];
75
+ return lastMessage.content || lastMessage.text || "";
76
+ }
77
+ }
78
+ return "";
79
+ }
80
+ /**
81
+ * Format a notification from an event
82
+ */
83
+ export function formatNotification(event, serverUrl, ctx) {
84
+ const properties = event.properties;
85
+ const { type } = event;
86
+ const projectPath = extractProjectPath(event, ctx);
87
+ const sessionId = extractSessionId(event);
88
+ const baseData = { type, serverUrl, projectPath, sessionId };
89
+ if (type === "session.idle") {
90
+ if (isChildSession(event)) {
91
+ return null;
92
+ }
93
+ }
94
+ switch (type) {
95
+ case "session.idle": {
96
+ const lastAssistantMessage = extractLastAssistantMessage(event);
97
+ console.log("[PushPlugin] Last assistant message:", lastAssistantMessage
98
+ ? lastAssistantMessage.substring(0, 100) + "..."
99
+ : "none");
100
+ const sessionTitle = properties?.title || properties?.sessionTitle || "Session";
101
+ const expandableContent = lastAssistantMessage || properties?.summary || "";
102
+ return {
103
+ title: "Session Complete",
104
+ body: sessionTitle,
105
+ data: {
106
+ ...baseData,
107
+ messageId: properties?.messageId,
108
+ lastAssistantMessage,
109
+ },
110
+ android: {
111
+ notification: {
112
+ channelId: "opencode-sessions",
113
+ style: {
114
+ type: "bigtext",
115
+ text: expandableContent,
116
+ title: sessionTitle,
117
+ },
118
+ },
119
+ },
120
+ ios: {
121
+ threadId: sessionId || undefined,
122
+ summaryArg: sessionTitle,
123
+ },
124
+ };
125
+ }
126
+ case "session.error":
127
+ return {
128
+ title: "Session Error",
129
+ body: truncate(properties?.error || properties?.message || "An error occurred", 100),
130
+ data: baseData,
131
+ };
132
+ case "permission.updated":
133
+ return {
134
+ title: "Permission Required",
135
+ body: `Approve ${properties?.tool || "action"} ${properties?.type || "execute"}?`,
136
+ data: { ...baseData, permissionId: properties?.permissionId },
137
+ };
138
+ default:
139
+ return null;
140
+ }
141
+ }
142
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../../src/push/formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Push notification module barrel export
3
+ */
4
+ export * from "./types";
5
+ export * from "./token-store";
6
+ export * from "./formatter";
7
+ export * from "./sender";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/push/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Push notification module barrel export
3
+ */
4
+ export * from "./types";
5
+ export * from "./token-store";
6
+ export * from "./formatter";
7
+ export * from "./sender";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/push/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Push notification sender
3
+ */
4
+ import type { Notification } from "./types";
5
+ /**
6
+ * Send push notification to all registered devices
7
+ */
8
+ export declare function sendPush(notification: Notification): Promise<void>;
9
+ //# sourceMappingURL=sender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../../src/push/sender.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAS5C;;GAEG;AACH,wBAAsB,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ExE"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Push notification sender
3
+ */
4
+ import { loadTokens, saveTokens } from "./token-store";
5
+ const EXPO_PUSH_URL = "https://exp.host/--/api/v2/push/send";
6
+ /**
7
+ * Send push notification to all registered devices
8
+ */
9
+ export async function sendPush(notification) {
10
+ const tokens = loadTokens();
11
+ if (tokens.length === 0) {
12
+ console.log("[PushPlugin] No push tokens registered, skipping notification");
13
+ return;
14
+ }
15
+ console.log(`[PushPlugin] Sending notification to ${tokens.length} device(s)`);
16
+ console.log("[PushPlugin] Notification details:", {
17
+ title: notification.title,
18
+ body: notification.body,
19
+ data: notification.data,
20
+ android: notification.android ? "configured" : "not configured",
21
+ ios: notification.ios ? "configured" : "not configured"
22
+ });
23
+ const messages = tokens.map(({ token }) => ({
24
+ to: token,
25
+ sound: "default",
26
+ title: notification.title,
27
+ body: notification.body,
28
+ data: notification.data,
29
+ priority: "high",
30
+ ...(notification.android && { android: notification.android }),
31
+ ...(notification.ios && { ios: notification.ios }),
32
+ }));
33
+ try {
34
+ const res = await fetch(EXPO_PUSH_URL, {
35
+ method: "POST",
36
+ headers: { "Content-Type": "application/json" },
37
+ body: JSON.stringify(messages),
38
+ });
39
+ if (!res.ok) {
40
+ console.error("[PushPlugin] Expo push API error:", res.status);
41
+ return;
42
+ }
43
+ const result = (await res.json());
44
+ console.log("[PushPlugin] Push send result:");
45
+ console.log(` Status: ${res.status}`);
46
+ console.log(` Messages sent: ${result.data?.length || 0}`);
47
+ // Log individual message results
48
+ result.data?.forEach((item, i) => {
49
+ if (item.status === "ok") {
50
+ console.log(` [${i + 1}] ✅ Delivered successfully`);
51
+ }
52
+ else if (item.status === "error") {
53
+ console.log(` [${i + 1}] ❌ Error: ${item.details?.error || "unknown"}`);
54
+ }
55
+ else {
56
+ console.log(` [${i + 1}] ℹ️ Status: ${item.status}`);
57
+ }
58
+ });
59
+ const invalidTokens = new Set();
60
+ result.data?.forEach((item, i) => {
61
+ if (item.status === "error" &&
62
+ ["DeviceNotRegistered", "InvalidCredentials"].includes(item.details?.error)) {
63
+ invalidTokens.add(tokens[i].token);
64
+ }
65
+ });
66
+ if (invalidTokens.size > 0) {
67
+ saveTokens(tokens.filter((t) => !invalidTokens.has(t.token)));
68
+ console.log(`[PushPlugin] Removed ${invalidTokens.size} invalid token(s)`);
69
+ }
70
+ }
71
+ catch (e) {
72
+ console.error("[PushPlugin] Send error:", e);
73
+ }
74
+ }
75
+ //# sourceMappingURL=sender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sender.js","sourceRoot":"","sources":["../../../src/push/sender.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Token storage for push notifications
3
+ */
4
+ import type { PushToken } from "./types";
5
+ /**
6
+ * Load stored push tokens from disk
7
+ */
8
+ export declare function loadTokens(): PushToken[];
9
+ /**
10
+ * Save push tokens to disk
11
+ */
12
+ export declare function saveTokens(tokens: PushToken[]): void;
13
+ /**
14
+ * Truncate text to a maximum length
15
+ */
16
+ export declare function truncate(text: string | undefined, max: number): string;
17
+ //# sourceMappingURL=token-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../../src/push/token-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAKzC;;GAEG;AACH,wBAAgB,UAAU,IAAI,SAAS,EAAE,CASxC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAIpD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMtE"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Token storage for push notifications
3
+ */
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ const CONFIG_DIR = path.join(process.env.HOME || "", ".config/opencode");
7
+ const TOKEN_FILE = path.join(CONFIG_DIR, "push-tokens.json");
8
+ /**
9
+ * Load stored push tokens from disk
10
+ */
11
+ export function loadTokens() {
12
+ try {
13
+ if (fs.existsSync(TOKEN_FILE)) {
14
+ return JSON.parse(fs.readFileSync(TOKEN_FILE, "utf-8"));
15
+ }
16
+ }
17
+ catch (e) {
18
+ console.error("[PushPlugin] Load error:", e);
19
+ }
20
+ return [];
21
+ }
22
+ /**
23
+ * Save push tokens to disk
24
+ */
25
+ export function saveTokens(tokens) {
26
+ const dir = path.dirname(TOKEN_FILE);
27
+ if (!fs.existsSync(dir))
28
+ fs.mkdirSync(dir, { recursive: true });
29
+ fs.writeFileSync(TOKEN_FILE, JSON.stringify(tokens, null, 2));
30
+ }
31
+ /**
32
+ * Truncate text to a maximum length
33
+ */
34
+ export function truncate(text, max) {
35
+ if (!text)
36
+ return "";
37
+ const cleaned = text.replace(/\n/g, " ").trim();
38
+ return cleaned.length <= max
39
+ ? cleaned
40
+ : cleaned.substring(0, max - 3) + "...";
41
+ }
42
+ //# sourceMappingURL=token-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../../src/push/token-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACzE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAwB,EAAE,GAAW;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,OAAO,OAAO,CAAC,MAAM,IAAI,GAAG;QAC1B,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Push notification types
3
+ */
4
+ export interface PushToken {
5
+ token: string;
6
+ platform: "ios" | "android";
7
+ deviceId: string;
8
+ registeredAt: string;
9
+ }
10
+ export interface Notification {
11
+ title: string;
12
+ body: string;
13
+ data: Record<string, unknown>;
14
+ android?: AndroidNotificationConfig;
15
+ ios?: iOSNotificationConfig;
16
+ }
17
+ export interface AndroidNotificationConfig {
18
+ notification?: {
19
+ channelId?: string;
20
+ style?: {
21
+ type: "bigtext" | "inbox";
22
+ text?: string;
23
+ title?: string;
24
+ lines?: string[];
25
+ };
26
+ };
27
+ }
28
+ export interface iOSNotificationConfig {
29
+ attachments?: Array<{
30
+ url: string;
31
+ hideThumbnail?: boolean;
32
+ }>;
33
+ summaryArg?: string;
34
+ threadId?: string;
35
+ }
36
+ export interface NotificationEvent {
37
+ type: string;
38
+ properties: Record<string, unknown>;
39
+ sessionId?: string;
40
+ sessionID?: string;
41
+ parentSessionId?: string;
42
+ parentId?: string;
43
+ }
44
+ export interface PluginContext {
45
+ directory?: string;
46
+ worktree?: string;
47
+ serverUrl?: {
48
+ port?: string | number;
49
+ };
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/push/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,yBAAyB,CAAC;IACpC,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE;YACN,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;YAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;SAClB,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,GAAG,EAAE,MAAM,CAAC;QACZ,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACxB,CAAC;CACH"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Push notification types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/push/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Cloudflare tunnel provider implementation
3
+ */
4
+ import type { TunnelConfig, TunnelInfo } from "./types";
5
+ /**
6
+ * Start a Cloudflare tunnel
7
+ */
8
+ export declare function startCloudflareTunnel(config: TunnelConfig): Promise<TunnelInfo>;
9
+ /**
10
+ * Stop the Cloudflare tunnel
11
+ */
12
+ export declare function stopCloudflareTunnel(): Promise<void>;
13
+ /**
14
+ * Check if cloudflared is installed
15
+ */
16
+ export declare function isCloudflareInstalled(): Promise<boolean>;
17
+ //# sourceMappingURL=cloudflare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKxD;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CA2CrF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAS9D"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Cloudflare tunnel provider implementation
3
+ */
4
+ import { spawn } from "child_process";
5
+ let cloudflareProcess = null;
6
+ let cloudflareUrl = null;
7
+ /**
8
+ * Start a Cloudflare tunnel
9
+ */
10
+ export async function startCloudflareTunnel(config) {
11
+ return new Promise((resolve, reject) => {
12
+ try {
13
+ const cloudflared = spawn("cloudflared", [
14
+ "tunnel",
15
+ "--url",
16
+ `http://127.0.0.1:${config.port}`,
17
+ ]);
18
+ cloudflareProcess = cloudflared;
19
+ let output = "";
20
+ cloudflared.stdout.on("data", (data) => {
21
+ output += data.toString();
22
+ const match = output.match(/https:\/\/[^\s]+\\.trycloudflare\\.com/);
23
+ if (match) {
24
+ cloudflareUrl = match[0];
25
+ resolve({
26
+ url: cloudflareUrl,
27
+ tunnelId: "cloudflare",
28
+ port: config.port,
29
+ provider: "cloudflare",
30
+ });
31
+ }
32
+ });
33
+ cloudflared.stderr.on("data", (data) => {
34
+ console.error("[Tunnel] Cloudflare stderr:", data.toString());
35
+ });
36
+ cloudflared.on("error", (err) => {
37
+ reject(new Error(`Cloudflare tunnel failed: ${err.message}`));
38
+ });
39
+ cloudflared.on("close", (code) => {
40
+ if (code !== 0 && !cloudflareUrl) {
41
+ reject(new Error(`Cloudflare tunnel exited with code ${code}`));
42
+ }
43
+ });
44
+ }
45
+ catch (error) {
46
+ reject(new Error(`Cloudflare tunnel failed: ${error.message}`));
47
+ }
48
+ });
49
+ }
50
+ /**
51
+ * Stop the Cloudflare tunnel
52
+ */
53
+ export async function stopCloudflareTunnel() {
54
+ if (cloudflareProcess) {
55
+ cloudflareProcess.kill();
56
+ cloudflareProcess = null;
57
+ cloudflareUrl = null;
58
+ }
59
+ }
60
+ /**
61
+ * Check if cloudflared is installed
62
+ */
63
+ export async function isCloudflareInstalled() {
64
+ try {
65
+ const { promisify } = await import("util");
66
+ const execAsync = promisify((await import("child_process")).exec);
67
+ await execAsync("which cloudflared");
68
+ return true;
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ }
74
+ //# sourceMappingURL=cloudflare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,IAAI,iBAAiB,GAAQ,IAAI,CAAC;AAClC,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAAoB;IAC9D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,EAAE;gBACvC,QAAQ;gBACR,OAAO;gBACP,oBAAoB,MAAM,CAAC,IAAI,EAAE;aAClC,CAAC,CAAC;YAEH,iBAAiB,GAAG,WAAW,CAAC;YAEhC,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC7C,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;gBACrE,IAAI,KAAK,EAAE,CAAC;oBACV,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBACzB,OAAO,CAAC;wBACN,GAAG,EAAE,aAAa;wBAClB,QAAQ,EAAE,YAAY;wBACtB,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,QAAQ,EAAE,YAAY;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC7C,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YAEH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBACrC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YAEH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE;gBACvC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,KAAK,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,iBAAiB,EAAE,CAAC;QACtB,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACzB,iBAAiB,GAAG,IAAI,CAAC;QACzB,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tunnel manager - unified interface for all tunnel providers
3
+ */
4
+ import type { TunnelConfig, TunnelInfo, TunnelDetails } from "./types";
5
+ import { displayQRCode } from "./qrcode";
6
+ /**
7
+ * Start a tunnel with the specified provider
8
+ */
9
+ export declare function startTunnel(config: TunnelConfig): Promise<TunnelInfo>;
10
+ /**
11
+ * Stop the current tunnel
12
+ */
13
+ export declare function stopTunnel(): Promise<void>;
14
+ /**
15
+ * Display QR code for tunnel URL
16
+ */
17
+ export declare function displayQR(tunnelInfo: TunnelInfo): void;
18
+ /**
19
+ * Get current tunnel details
20
+ */
21
+ export declare function getTunnelDetails(): TunnelDetails;
22
+ /**
23
+ * Get current tunnel info
24
+ */
25
+ export declare function getTunnelInfo(): TunnelInfo | null;
26
+ /**
27
+ * Get current server URL from tunnel
28
+ */
29
+ export declare function getServerUrl(): string;
30
+ export { displayQRCode };
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tunnel/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIvE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAkB3E;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAQhD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAEjD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Tunnel manager - unified interface for all tunnel providers
3
+ */
4
+ import { startNgrokTunnel, stopNgrokTunnel } from "./ngrok";
5
+ import { startLocaltunnel, stopLocaltunnel } from "./localtunnel";
6
+ import { startCloudflareTunnel, stopCloudflareTunnel } from "./cloudflare";
7
+ import { displayQRCode } from "./qrcode";
8
+ let currentTunnel = null;
9
+ /**
10
+ * Start a tunnel with the specified provider
11
+ */
12
+ export async function startTunnel(config) {
13
+ const provider = config.provider || "ngrok";
14
+ switch (provider) {
15
+ case "ngrok":
16
+ currentTunnel = await startNgrokTunnel(config);
17
+ break;
18
+ case "localtunnel":
19
+ currentTunnel = await startLocaltunnel(config);
20
+ break;
21
+ case "cloudflare":
22
+ currentTunnel = await startCloudflareTunnel(config);
23
+ break;
24
+ default:
25
+ throw new Error(`Unknown tunnel provider: ${provider}`);
26
+ }
27
+ return currentTunnel;
28
+ }
29
+ /**
30
+ * Stop the current tunnel
31
+ */
32
+ export async function stopTunnel() {
33
+ if (!currentTunnel) {
34
+ return;
35
+ }
36
+ switch (currentTunnel.provider) {
37
+ case "ngrok":
38
+ await stopNgrokTunnel();
39
+ break;
40
+ case "localtunnel":
41
+ await stopLocaltunnel();
42
+ break;
43
+ case "cloudflare":
44
+ await stopCloudflareTunnel();
45
+ break;
46
+ }
47
+ currentTunnel = null;
48
+ }
49
+ /**
50
+ * Display QR code for tunnel URL
51
+ */
52
+ export function displayQR(tunnelInfo) {
53
+ displayQRCode(tunnelInfo.url);
54
+ }
55
+ /**
56
+ * Get current tunnel details
57
+ */
58
+ export function getTunnelDetails() {
59
+ return {
60
+ type: currentTunnel?.provider || "none",
61
+ url: currentTunnel?.url || null,
62
+ loginStatus: "unknown",
63
+ loginId: null,
64
+ configPath: null,
65
+ };
66
+ }
67
+ /**
68
+ * Get current tunnel info
69
+ */
70
+ export function getTunnelInfo() {
71
+ return currentTunnel;
72
+ }
73
+ /**
74
+ * Get current server URL from tunnel
75
+ */
76
+ export function getServerUrl() {
77
+ if (!currentTunnel) {
78
+ throw new Error("No tunnel active");
79
+ }
80
+ return currentTunnel.url;
81
+ }
82
+ export { displayQRCode };
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tunnel/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAiB,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,aAAa,GAAsB,IAAI,CAAC;AAE5C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAoB;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC;IAE5C,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,aAAa,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM;QACR,KAAK,aAAa;YAChB,aAAa,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM;QACR,KAAK,YAAY;YACf,aAAa,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;YACpD,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IAED,QAAQ,aAAa,CAAC,QAAQ,EAAE,CAAC;QAC/B,KAAK,OAAO;YACV,MAAM,eAAe,EAAE,CAAC;YACxB,MAAM;QACR,KAAK,aAAa;YAChB,MAAM,eAAe,EAAE,CAAC;YACxB,MAAM;QACR,KAAK,YAAY;YACf,MAAM,oBAAoB,EAAE,CAAC;YAC7B,MAAM;IACV,CAAC;IAED,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,UAAsB;IAC9C,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,IAAI,EAAE,aAAa,EAAE,QAAQ,IAAI,MAAM;QACvC,GAAG,EAAE,aAAa,EAAE,GAAG,IAAI,IAAI;QAC/B,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,IAAI;KACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,aAAa,CAAC,GAAG,CAAC;AAC3B,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Localtunnel tunnel provider implementation
3
+ */
4
+ import type { TunnelConfig, TunnelInfo } from "./types";
5
+ /**
6
+ * Start a localtunnel
7
+ */
8
+ export declare function startLocaltunnel(config: TunnelConfig): Promise<TunnelInfo>;
9
+ /**
10
+ * Stop the localtunnel
11
+ */
12
+ export declare function stopLocaltunnel(): Promise<void>;
13
+ //# sourceMappingURL=localtunnel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localtunnel.d.ts","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIxD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAchF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD"}