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,4 @@
1
+ export { PushNotificationPlugin, default } from "./push-notifications";
2
+ export * from "./src/tunnel";
3
+ export { startProxy, stopProxy } from "./reverse-proxy";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { PushNotificationPlugin, default } from "./push-notifications";
2
+ export * from "./src/tunnel";
3
+ export { startProxy, stopProxy } from "./reverse-proxy";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ export declare const PushNotificationPlugin: Plugin;
3
+ export default PushNotificationPlugin;
4
+ //# sourceMappingURL=push-notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-notifications.d.ts","sourceRoot":"","sources":["../push-notifications.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAiKlD,eAAO,MAAM,sBAAsB,EAAE,MAsKpC,CAAC;AAYF,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,299 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { startTunnel, stopTunnel, displayQRCode as displayQR, getTunnelDetails } from "./src/tunnel";
4
+ import { getNextAvailablePort } from "./src/utils/port";
5
+ import { loadTokens, saveTokens } from "./src/push/token-store";
6
+ import { formatNotification } from "./src/push/formatter";
7
+ import { sendPush } from "./src/push/sender";
8
+ import { createLogger } from "./sdk-logger";
9
+ const CONFIG_DIR = path.join(process.env.HOME || "", ".config/opencode");
10
+ // Simple console logging (no client.log dependency)
11
+ const logger = createLogger("PushPlugin");
12
+ const TOKEN_FILE = path.join(CONFIG_DIR, "push-tokens.json");
13
+ let tokenServerStarted = false;
14
+ let pluginInitialized = false;
15
+ let bunServer = null;
16
+ let bunServerPort = null;
17
+ async function startTokenServer(openCodeUrl, port) {
18
+ if (tokenServerStarted)
19
+ return;
20
+ const cors = {
21
+ "Access-Control-Allow-Origin": "*",
22
+ "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
23
+ "Access-Control-Allow-Headers": "Content-Type, x-opencode-directory",
24
+ };
25
+ bunServer = Bun.serve({
26
+ port: port,
27
+ hostname: "0.0.0.0",
28
+ idleTimeout: 0, // Disable timeout for SSE connections
29
+ async fetch(req) {
30
+ const url = new URL(req.url);
31
+ if (req.method === "OPTIONS")
32
+ return new Response(null, { status: 204, headers: cors });
33
+ if (url.pathname === "/push-token" && req.method === "POST") {
34
+ const body = (await req.json());
35
+ const { token, platform, deviceId } = body;
36
+ if (!token || !deviceId)
37
+ return new Response(JSON.stringify({ error: "Missing fields" }), {
38
+ status: 400,
39
+ headers: cors,
40
+ });
41
+ // Validate platform field
42
+ const validPlatform = (platform && (platform === "ios" || platform === "android"))
43
+ ? platform
44
+ : "ios";
45
+ const tokens = loadTokens();
46
+ const idx = tokens.findIndex((t) => t.deviceId === deviceId);
47
+ const newToken = {
48
+ token,
49
+ platform: validPlatform,
50
+ deviceId,
51
+ registeredAt: new Date().toISOString(),
52
+ };
53
+ if (idx >= 0)
54
+ tokens[idx] = newToken;
55
+ else
56
+ tokens.push(newToken);
57
+ saveTokens(tokens);
58
+ return new Response(JSON.stringify({ success: true }), {
59
+ status: 200,
60
+ headers: cors,
61
+ });
62
+ }
63
+ if (url.pathname === "/push-token" && req.method === "DELETE") {
64
+ const body = (await req.json());
65
+ const { deviceId } = body;
66
+ saveTokens(loadTokens().filter((t) => t.deviceId !== deviceId));
67
+ return new Response(JSON.stringify({ success: true }), {
68
+ status: 200,
69
+ headers: cors,
70
+ });
71
+ }
72
+ if (url.pathname === "/push-token" && req.method === "GET") {
73
+ return new Response(JSON.stringify({ count: loadTokens().length }), {
74
+ status: 200,
75
+ headers: cors,
76
+ });
77
+ }
78
+ if (url.pathname === "/push-token/test" && req.method === "POST") {
79
+ await sendPush({
80
+ title: "Test",
81
+ body: "Push notifications working!",
82
+ data: { type: "test", serverUrl: openCodeUrl },
83
+ });
84
+ return new Response(JSON.stringify({ success: true }), {
85
+ status: 200,
86
+ headers: cors,
87
+ });
88
+ }
89
+ // Return tunnel information
90
+ if (url.pathname === "/tunnel" && req.method === "GET") {
91
+ const details = getTunnelDetails();
92
+ return new Response(JSON.stringify(details, null, 2), {
93
+ status: 200,
94
+ headers: { ...cors, "Content-Type": "application/json" },
95
+ });
96
+ }
97
+ // Proxy everything else directly to OpenCode server (transparent)
98
+ const pathname = url.pathname + url.search;
99
+ try {
100
+ const controller = new AbortController();
101
+ const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
102
+ const proxyReq = new Request(`${openCodeUrl}${pathname}`, {
103
+ method: req.method,
104
+ headers: req.headers,
105
+ body: req.body,
106
+ redirect: "follow",
107
+ signal: controller.signal,
108
+ });
109
+ try {
110
+ return await fetch(proxyReq);
111
+ }
112
+ catch (e) {
113
+ if (e.name === 'AbortError') {
114
+ return new Response("Gateway timeout", { status: 504, headers: cors });
115
+ }
116
+ throw e;
117
+ }
118
+ finally {
119
+ clearTimeout(timeoutId);
120
+ }
121
+ }
122
+ catch (e) {
123
+ logger.error("Proxy error:", e);
124
+ return new Response("Proxy error", { status: 502, headers: cors });
125
+ }
126
+ },
127
+ });
128
+ tokenServerStarted = true;
129
+ }
130
+ function stopAll() {
131
+ logger.info("Shutting down...");
132
+ stopTunnel();
133
+ if (bunServer) {
134
+ logger.info("Stopping Bun server...");
135
+ bunServer.stop();
136
+ bunServer = null;
137
+ }
138
+ tokenServerStarted = false;
139
+ logger.info("Shutdown complete");
140
+ }
141
+ export const PushNotificationPlugin = async (ctx) => {
142
+ if (pluginInitialized) {
143
+ return { event: async ({ event }) => { } };
144
+ }
145
+ pluginInitialized = true;
146
+ // Skip tunnel setup in server mode (no --serve flag)
147
+ const processArgs = process.argv.slice(2).join(' ');
148
+ const hasServeFlag = processArgs.includes('--serve') || processArgs.includes('serve');
149
+ if (!hasServeFlag) {
150
+ return {
151
+ event: async ({ event }) => { },
152
+ };
153
+ }
154
+ const serverPort = parseInt(String(ctx.serverUrl?.port || 4096), 10);
155
+ logger.info(`App started. Creating tunnel with ngrok to port ${serverPort}`);
156
+ // Test logging with different levels
157
+ logger.debug("Detailed development info - appears only with --log-level DEBUG");
158
+ logger.info("Standard operational message - appears with --log-level INFO, WARN, ERROR");
159
+ logger.warn("Non-critical issue warning - appears with --log-level WARN, ERROR");
160
+ logger.error("Critical failure message - appears only with --log-level ERROR");
161
+ // Get server port from ctx, find next available for push-token
162
+ const pushTokenPort = await getNextAvailablePort(serverPort + 1);
163
+ bunServerPort = pushTokenPort;
164
+ const openCodeUrl = `http://127.0.0.1:${serverPort}`;
165
+ logger.info(`Token API: http://127.0.0.1:${pushTokenPort} → ${openCodeUrl}`);
166
+ try {
167
+ await startTokenServer(openCodeUrl, pushTokenPort);
168
+ let tunnelInfo;
169
+ let ngrokFailed = false;
170
+ try {
171
+ // Create tunnel directly to OpenCode server (transparent proxy)
172
+ tunnelInfo = await startTunnel({ port: serverPort, provider: "ngrok" });
173
+ }
174
+ catch (ngrokError) {
175
+ const errorMsg = ngrokError.message.toLowerCase();
176
+ const isAuthIssue = errorMsg.includes("invalid tunnel configuration") ||
177
+ errorMsg.includes("authtoken") ||
178
+ errorMsg.includes("authentication") ||
179
+ errorMsg.includes("auth token") ||
180
+ errorMsg.includes("session failed") ||
181
+ errorMsg.includes("connect to api.ngrok.com");
182
+ if (isAuthIssue) {
183
+ logger.info("Ngrok needs authtoken (ERR_NGROK_4018)");
184
+ const readline = await import("readline");
185
+ const rl = readline.createInterface({
186
+ input: process.stdin,
187
+ output: process.stdout,
188
+ });
189
+ const newToken = await new Promise((resolve) => {
190
+ rl.question("[?] Enter ngrok authtoken (or Enter to skip): ", async (token) => {
191
+ rl.close();
192
+ resolve(token && token.trim().length > 25 ? token.trim() : null);
193
+ });
194
+ });
195
+ if (newToken) {
196
+ logger.info("Writing ngrok config...");
197
+ // Basic validation - ngrok authtokens are typically 50+ characters
198
+ if (!newToken || newToken.length < 25) {
199
+ logger.error("Invalid authtoken format");
200
+ ngrokFailed = true;
201
+ }
202
+ else {
203
+ try {
204
+ const { writeFileSync, existsSync, mkdirSync } = fs;
205
+ const configPath = `${process.env.HOME}/Library/Application Support/ngrok/ngrok.yml`;
206
+ const configDir = `${process.env.HOME}/Library/Application Support/ngrok`;
207
+ if (!existsSync(configDir)) {
208
+ mkdirSync(configDir, { recursive: true });
209
+ }
210
+ // Escape any special characters that could break YAML
211
+ const escapedToken = newToken.replace(/[:\[\]{}|>&*?!@]/g, '\\$&');
212
+ const v3Config = `version: "3"
213
+
214
+ agent:
215
+ authtoken: ${escapedToken}
216
+ `;
217
+ writeFileSync(configPath, v3Config, { mode: 0o600 });
218
+ logger.info(`Config: ${configPath}`);
219
+ // Retry with new authtoken (pass it directly to ngrok.connect)
220
+ tunnelInfo = await startTunnel({
221
+ port: serverPort,
222
+ provider: "ngrok",
223
+ authToken: newToken
224
+ });
225
+ logger.info("Ngrok tunnel active!");
226
+ }
227
+ catch (retryError) {
228
+ logger.error(`Retry failed: ${retryError.message}`);
229
+ ngrokFailed = true;
230
+ }
231
+ }
232
+ }
233
+ else {
234
+ ngrokFailed = true;
235
+ }
236
+ }
237
+ else {
238
+ ngrokFailed = true;
239
+ }
240
+ if (ngrokFailed) {
241
+ logger.info("Trying localtunnel...");
242
+ try {
243
+ tunnelInfo = await startTunnel({ port: serverPort, provider: "localtunnel" });
244
+ }
245
+ catch (localtunnelError) {
246
+ logger.error("Localtunnel failed:", localtunnelError.message);
247
+ throw new Error("All tunnel providers failed");
248
+ }
249
+ }
250
+ }
251
+ if (!tunnelInfo) {
252
+ throw new Error("Failed to establish tunnel");
253
+ }
254
+ await displayQR(tunnelInfo.url);
255
+ return {
256
+ event: async ({ event }) => {
257
+ // Format notification from event
258
+ const notification = formatNotification(event, tunnelInfo.url, ctx);
259
+ if (!notification) {
260
+ // No notification needed for this event type
261
+ return;
262
+ }
263
+ // Log the raw event that triggered this push
264
+ const eventAny = event;
265
+ logger.info("Raw event received", {
266
+ type: event.type,
267
+ sessionID: eventAny.sessionID || eventAny.sessionId,
268
+ timestamp: eventAny.timestamp,
269
+ properties: event.properties
270
+ });
271
+ // Log the formatted notification
272
+ logger.info("Sending push notification", {
273
+ title: notification.title,
274
+ body: notification.body,
275
+ sessionId: notification.data?.sessionId,
276
+ type: notification.data?.type
277
+ });
278
+ // Send the push notification
279
+ await sendPush(notification);
280
+ logger.debug("Push notification sent successfully");
281
+ },
282
+ };
283
+ }
284
+ catch (error) {
285
+ logger.error("Failed:", error.message);
286
+ return { event: async ({ event }) => { } };
287
+ }
288
+ };
289
+ process.on("SIGTERM", () => {
290
+ stopAll();
291
+ });
292
+ process.on("SIGINT", () => {
293
+ stopAll();
294
+ });
295
+ process.on("SIGHUP", () => {
296
+ stopAll();
297
+ });
298
+ export default PushNotificationPlugin;
299
+ //# sourceMappingURL=push-notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-notifications.js","sourceRoot":"","sources":["../push-notifications.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAM7B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,IAAI,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAY,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAmB,MAAM,cAAc,CAAC;AAE7D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAEzE,oDAAoD;AACpD,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;AAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAE7D,IAAI,kBAAkB,GAAG,KAAK,CAAC;AAC/B,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAC9B,IAAI,SAAS,GAAQ,IAAI,CAAC;AAC1B,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC,KAAK,UAAU,gBAAgB,CAC7B,WAAmB,EACnB,IAAY;IAEZ,IAAI,kBAAkB;QAAE,OAAO;IAE/B,MAAM,IAAI,GAAG;QACX,6BAA6B,EAAE,GAAG;QAClC,8BAA8B,EAAE,4BAA4B;QAC5D,8BAA8B,EAAE,oCAAoC;KACrE,CAAC;IAEF,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC;QACpB,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,CAAC,EAAE,sCAAsC;QACtD,KAAK,CAAC,KAAK,CAAC,GAAY;YACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;gBAC1B,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAE5D,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC5D,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAI7B,CAAC;gBACF,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;gBAC3C,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ;oBACrB,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,EAAE;wBAC/D,MAAM,EAAE,GAAG;wBACX,OAAO,EAAE,IAAI;qBACd,CAAC,CAAC;gBAEL,0BAA0B;gBAC1B,MAAM,aAAa,GAAG,CAAC,QAAQ,IAAI,CAAC,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC;oBAChF,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,KAAK,CAAC;gBAEV,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;gBAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;gBAC7D,MAAM,QAAQ,GAAc;oBAC1B,KAAK;oBACL,QAAQ,EAAE,aAAa;oBACvB,QAAQ;oBACR,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACvC,CAAC;gBACF,IAAI,GAAG,IAAI,CAAC;oBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;;oBAChC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC3B,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE;oBACrD,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,IAAI;iBACd,CAAC,CAAC;YACL,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC9D,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAC;gBACzD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;gBAC1B,UAAU,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC;gBAChE,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE;oBACrD,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,IAAI;iBACd,CAAC,CAAC;YACL,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBAC3D,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE;oBAClE,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,IAAI;iBACd,CAAC,CAAC;YACL,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,kBAAkB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBACjE,MAAM,QAAQ,CAAC;oBACb,KAAK,EAAE,MAAM;oBACb,IAAI,EAAE,6BAA6B;oBACnC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE;iBAC/C,CAAC,CAAC;gBACH,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE;oBACrD,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,IAAI;iBACd,CAAC,CAAC;YACL,CAAC;YAED,4BAA4B;YAC5B,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBACvD,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;gBACnC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;oBACpD,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,cAAc,EAAE,kBAAkB,EAAE;iBACzD,CAAC,CAAC;YACL,CAAC;YAED,kEAAkE;YAClE,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;gBACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,oBAAoB;gBACnF,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,GAAG,WAAW,GAAG,QAAQ,EAAE,EAAE;oBACxD,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,QAAQ,EAAE,QAAQ;oBAClB,MAAM,EAAE,UAAU,CAAC,MAAM;iBAC1B,CAAC,CAAC;gBACH,IAAI,CAAC;oBACH,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC/B,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;wBAC5B,OAAO,IAAI,QAAQ,CAAC,iBAAiB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;oBACzE,CAAC;oBACD,MAAM,CAAC,CAAC;gBACV,CAAC;wBAAS,CAAC;oBACT,YAAY,CAAC,SAAS,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;gBAChC,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,kBAAkB,GAAG,IAAI,CAAC;AAC5B,CAAC;AAGD,SAAS,OAAO;IACd,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAEhC,UAAU,EAAE,CAAC;IACb,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACtC,SAAS,CAAC,IAAI,EAAE,CAAC;QACjB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,kBAAkB,GAAG,KAAK,CAAC;IAC3B,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAW,KAAK,EAAE,GAAG,EAAE,EAAE;IAC1D,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IACD,iBAAiB,GAAG,IAAI,CAAC;IAEzB,qDAAqD;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEtF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;YACL,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAE,CAAC;SAC/B,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAE,GAAW,CAAC,SAAS,EAAE,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,CAAC,IAAI,CAAC,mDAAmD,UAAU,EAAE,CAAC,CAAC;IAE7E,qCAAqC;IACrC,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;IAChF,MAAM,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACzF,MAAM,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;IACjF,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;IAE/E,+DAA+D;IAC/D,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACjE,aAAa,GAAG,aAAa,CAAC;IAC9B,MAAM,WAAW,GAAG,oBAAoB,UAAU,EAAE,CAAC;IAErD,MAAM,CAAC,IAAI,CAAC,+BAA+B,aAAa,MAAM,WAAW,EAAE,CAAC,CAAC;IAE7E,IAAI,CAAC;QACH,MAAM,gBAAgB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAEnD,IAAI,UAAe,CAAC;QACpB,IAAI,WAAW,GAAG,KAAK,CAAC;QAExB,IAAI,CAAC;YACH,gEAAgE;YAChE,UAAU,GAAG,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,UAAe,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAClD,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,CAAC;gBACjD,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC9B,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBACnC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAC/B,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBACnC,QAAQ,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;YAElE,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;gBAEtD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;oBAClC,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC,CAAC;gBAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,EAAE;oBAC5D,EAAE,CAAC,QAAQ,CAAC,gDAAgD,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;wBAC5E,EAAE,CAAC,KAAK,EAAE,CAAC;wBACX,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACnE,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBAEH,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;oBAEvC,mEAAmE;oBACnE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;wBACtC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;wBACzC,WAAW,GAAG,IAAI,CAAC;oBACrB,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC;4BACH,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;4BACpD,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,8CAA8C,CAAC;4BACrF,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,oCAAoC,CAAC;4BAE1E,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gCAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;4BAC5C,CAAC;4BAED,sDAAsD;4BACtD,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;4BACnE,MAAM,QAAQ,GAAG;;;eAGhB,YAAY;CAC1B,CAAC;4BACY,aAAa,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;4BACrD,MAAM,CAAC,IAAI,CAAC,WAAW,UAAU,EAAE,CAAC,CAAC;4BAErC,+DAA+D;4BAC/D,UAAU,GAAG,MAAM,WAAW,CAAC;gCAC7B,IAAI,EAAE,UAAU;gCAChB,QAAQ,EAAE,OAAO;gCACjB,SAAS,EAAE,QAAQ;6BACpB,CAAC,CAAC;4BACH,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;wBACtC,CAAC;wBAAC,OAAO,UAAe,EAAE,CAAC;4BACzB,MAAM,CAAC,KAAK,CAAC,iBAAiB,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;4BACpD,WAAW,GAAG,IAAI,CAAC;wBACrB,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,WAAW,GAAG,IAAI,CAAC;gBACrB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YAED,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBACrC,IAAI,CAAC;oBACH,UAAU,GAAG,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;gBAChF,CAAC;gBAAC,OAAO,gBAAqB,EAAE,CAAC;oBAC/B,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;oBAC9D,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAEhC,OAAO;YACL,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;gBACzB,iCAAiC;gBACjC,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAEpE,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,6CAA6C;oBAC7C,OAAO;gBACT,CAAC;gBAED,6CAA6C;gBAC7C,MAAM,QAAQ,GAAG,KAAY,CAAC;gBAC9B,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;oBAChC,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS;oBACnD,SAAS,EAAE,QAAQ,CAAC,SAAS;oBAC7B,UAAU,EAAE,KAAK,CAAC,UAAU;iBAC7B,CAAC,CAAC;gBAEH,iCAAiC;gBACjC,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;oBACvC,KAAK,EAAE,YAAY,CAAC,KAAK;oBACzB,IAAI,EAAE,YAAY,CAAC,IAAI;oBACvB,SAAS,EAAE,YAAY,CAAC,IAAI,EAAE,SAAS;oBACvC,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI;iBAC9B,CAAC,CAAC;gBAEH,6BAA6B;gBAC7B,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;gBAE7B,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACtD,CAAC;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC,CAAC;AAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC;AAEH,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface ProxyConfig {
2
+ proxyPort: number;
3
+ serverPort: number;
4
+ tokenApiPort: number;
5
+ }
6
+ export declare function startProxy(config: ProxyConfig): Promise<void>;
7
+ export declare function stopProxy(): void;
8
+ export declare function isProxyRunning(): boolean;
9
+ //# sourceMappingURL=reverse-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse-proxy.d.ts","sourceRoot":"","sources":["../reverse-proxy.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D7D;AAED,wBAAgB,SAAS,IAAI,IAAI,CAQhC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC"}
@@ -0,0 +1,72 @@
1
+ import http, { request as httpRequest } from "http";
2
+ let serverStarted = false;
3
+ let server = null;
4
+ export function startProxy(config) {
5
+ return new Promise((resolve, reject) => {
6
+ if (serverStarted) {
7
+ console.log("[Proxy] Proxy already running");
8
+ resolve();
9
+ return;
10
+ }
11
+ server = http.createServer((clientReq, clientRes) => {
12
+ const url = clientReq.url || "";
13
+ const targetPort = url.startsWith("/push-token")
14
+ ? config.tokenApiPort
15
+ : config.serverPort;
16
+ const options = {
17
+ hostname: "127.0.0.1",
18
+ port: targetPort,
19
+ path: url,
20
+ method: clientReq.method,
21
+ headers: {
22
+ ...clientReq.headers,
23
+ "x-forwarded-for": clientReq.socket.remoteAddress,
24
+ "x-forwarded-host": clientReq.headers.host,
25
+ },
26
+ };
27
+ const proxyReq = httpRequest(options, (proxyRes) => {
28
+ clientRes.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
29
+ proxyRes.pipe(clientRes);
30
+ });
31
+ proxyReq.on("error", (err) => {
32
+ console.error("[Proxy] Error forwarding request:", err.message);
33
+ if (!clientRes.headersSent) {
34
+ clientRes.writeHead(502, { "Content-Type": "text/plain" });
35
+ clientRes.end("Bad Gateway");
36
+ }
37
+ });
38
+ clientReq.pipe(proxyReq);
39
+ });
40
+ server.on("error", (err) => {
41
+ if (err.code === "EADDRINUSE") {
42
+ console.log("[Proxy] Port already in use - proxy likely already running");
43
+ serverStarted = true;
44
+ resolve();
45
+ }
46
+ else {
47
+ console.error("[Proxy] Failed to start:", err.message);
48
+ reject(err);
49
+ }
50
+ });
51
+ server.listen(config.proxyPort, () => {
52
+ serverStarted = true;
53
+ console.log(`[Proxy] Running on port ${config.proxyPort}`);
54
+ console.log(`[Proxy] /push-token/* → Port ${config.tokenApiPort}`);
55
+ console.log(`[Proxy] /* → Port ${config.serverPort}`);
56
+ resolve();
57
+ });
58
+ });
59
+ }
60
+ export function stopProxy() {
61
+ if (server) {
62
+ server.close(() => {
63
+ console.log("[Proxy] Server stopped");
64
+ });
65
+ server = null;
66
+ serverStarted = false;
67
+ }
68
+ }
69
+ export function isProxyRunning() {
70
+ return serverStarted;
71
+ }
72
+ //# sourceMappingURL=reverse-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse-proxy.js","sourceRoot":"","sources":["../reverse-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ interface LoggerConfig {
3
+ level: LogLevel;
4
+ prefix: string;
5
+ showTimestamp: boolean;
6
+ }
7
+ export declare function configureLogger(config: Partial<LoggerConfig>): void;
8
+ export declare function createLogger(service: string): {
9
+ debug: (message: string, data?: Record<string, unknown>) => void;
10
+ info: (message: string, data?: Record<string, unknown>) => void;
11
+ warn: (message: string, data?: Record<string, unknown>) => void;
12
+ error: (message: string, extra?: Record<string, unknown> | Error | unknown) => void;
13
+ log: (level: LogLevel, message: string, data?: Record<string, unknown>) => void;
14
+ };
15
+ export declare function log(level: LogLevel, service: string, message: string, data?: Record<string, unknown>): void;
16
+ export default createLogger;
17
+ //# sourceMappingURL=sdk-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-logger.d.ts","sourceRoot":"","sources":["../sdk-logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,UAAU,YAAY;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;CACxB;AAUD,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAEnE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAC7C,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACjE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC;IACpF,GAAG,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACjF,CAyEA;AAGD,wBAAgB,GAAG,CACjB,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,IAAI,CAGN;AAGD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,94 @@
1
+ const defaultConfig = {
2
+ level: process.env.LOG_LEVEL || "debug",
3
+ prefix: "App",
4
+ showTimestamp: true,
5
+ };
6
+ let globalConfig = { ...defaultConfig };
7
+ export function configureLogger(config) {
8
+ globalConfig = { ...globalConfig, ...config };
9
+ }
10
+ export function createLogger(service) {
11
+ const shouldLog = (level) => {
12
+ const levels = ["debug", "info", "warn", "error"];
13
+ return levels.indexOf(level) >= levels.indexOf(globalConfig.level);
14
+ };
15
+ const formatMessage = (level, message) => {
16
+ const timestamp = globalConfig.showTimestamp
17
+ ? new Date().toISOString().split("T")[1].slice(0, -1) + "Z"
18
+ : "";
19
+ const levelIcon = {
20
+ debug: "🔍",
21
+ info: "ℹ️",
22
+ warn: "⚠️",
23
+ error: "❌",
24
+ }[level];
25
+ const parts = [
26
+ timestamp,
27
+ `[${globalConfig.prefix}]`,
28
+ `[${service}]`,
29
+ levelIcon,
30
+ message,
31
+ ].filter(Boolean);
32
+ return parts.join(" ");
33
+ };
34
+ return {
35
+ debug: (message, data) => {
36
+ if (!shouldLog("debug"))
37
+ return;
38
+ console.log(formatMessage("debug", message));
39
+ if (data)
40
+ console.debug("[DEBUG-DATA]", JSON.stringify(data, null, 2));
41
+ },
42
+ info: (message, data) => {
43
+ if (!shouldLog("info"))
44
+ return;
45
+ console.log(formatMessage("info", message));
46
+ if (data)
47
+ console.debug("[INFO-DATA]", JSON.stringify(data, null, 2));
48
+ },
49
+ warn: (message, data) => {
50
+ if (!shouldLog("warn"))
51
+ return;
52
+ console.warn(formatMessage("warn", message));
53
+ if (data)
54
+ console.debug("[WARN-DATA]", JSON.stringify(data, null, 2));
55
+ },
56
+ error: (message, extra) => {
57
+ if (!shouldLog("error"))
58
+ return;
59
+ console.error(formatMessage("error", message));
60
+ if (extra) {
61
+ // If it's an Error object or has a stack property, treat as error
62
+ if (extra instanceof Error || extra?.stack) {
63
+ console.error("[ERROR]", extra);
64
+ if (extra instanceof Error) {
65
+ console.error("[ERROR-STACK]", extra.stack);
66
+ }
67
+ }
68
+ else if (typeof extra === "object" && extra !== null) {
69
+ // Treat as structured extra data
70
+ console.error("[ERROR-EXTRA]", JSON.stringify(extra, null, 2));
71
+ }
72
+ else {
73
+ // Primitive value or unknown type
74
+ console.error("[ERROR-DETAILS]", extra);
75
+ }
76
+ }
77
+ },
78
+ log: (level, message, data) => {
79
+ if (!shouldLog(level))
80
+ return;
81
+ console.log(formatMessage(level, message));
82
+ if (data)
83
+ console.debug(`[${level.toUpperCase()}-DATA]`, JSON.stringify(data, null, 2));
84
+ },
85
+ };
86
+ }
87
+ // Convenience function for quick logging
88
+ export function log(level, service, message, data) {
89
+ const logger = createLogger(service);
90
+ logger.log(level, message, data);
91
+ }
92
+ // Export for use in plugins
93
+ export default createLogger;
94
+ //# sourceMappingURL=sdk-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-logger.js","sourceRoot":"","sources":["../sdk-logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Notification formatting utilities
3
+ */
4
+ import type { Notification, NotificationEvent, PluginContext } from "./types";
5
+ /**
6
+ * Extract project path from event
7
+ */
8
+ export declare function extractProjectPath(event: NotificationEvent, ctx?: PluginContext): string | null;
9
+ /**
10
+ * Extract session ID from event
11
+ */
12
+ export declare function extractSessionId(event: NotificationEvent): string | null;
13
+ /**
14
+ * Check if event is a child session
15
+ */
16
+ export declare function isChildSession(event: NotificationEvent): boolean;
17
+ /**
18
+ * Extract last assistant message from event
19
+ */
20
+ export declare function extractLastAssistantMessage(event: NotificationEvent): string;
21
+ /**
22
+ * Format a notification from an event
23
+ */
24
+ export declare function formatNotification(event: NotificationEvent, serverUrl: string, ctx?: PluginContext): Notification | null;
25
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../../src/push/formatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAsC9E;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAyB/F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAWxE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAWhE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CA4B5E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,MAAM,EACjB,GAAG,CAAC,EAAE,aAAa,GAClB,YAAY,GAAG,IAAI,CAwErB"}