opencode-mobile 1.1.0 → 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.
- package/bin/audit +31 -0
- package/bin/qr +13 -0
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +545 -5
- package/dist/index.js.map +1 -1
- package/dist/src/cli/endpoint-tester.d.ts +19 -0
- package/dist/src/cli/endpoint-tester.d.ts.map +1 -0
- package/dist/src/cli/endpoint-tester.js +233 -0
- package/dist/src/cli/endpoint-tester.js.map +1 -0
- package/dist/src/cli/index.d.ts +20 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +166 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/push-tester.d.ts +16 -0
- package/dist/src/cli/push-tester.d.ts.map +1 -0
- package/dist/src/cli/push-tester.js +293 -0
- package/dist/src/cli/push-tester.js.map +1 -0
- package/dist/src/cli/qr.d.ts +5 -0
- package/dist/src/cli/qr.d.ts.map +1 -0
- package/dist/src/cli/qr.js +127 -0
- package/dist/src/cli/qr.js.map +1 -0
- package/dist/src/cli/report.d.ts +25 -0
- package/dist/src/cli/report.d.ts.map +1 -0
- package/dist/src/cli/report.js +215 -0
- package/dist/src/cli/report.js.map +1 -0
- package/dist/src/cli/server-manager.d.ts +28 -0
- package/dist/src/cli/server-manager.d.ts.map +1 -0
- package/dist/src/cli/server-manager.js +340 -0
- package/dist/src/cli/server-manager.js.map +1 -0
- package/dist/src/cli/test-runner.d.ts +16 -0
- package/dist/src/cli/test-runner.d.ts.map +1 -0
- package/dist/src/cli/test-runner.js +201 -0
- package/dist/src/cli/test-runner.js.map +1 -0
- package/dist/src/cli/tunnel-qr.d.ts +8 -0
- package/dist/src/cli/tunnel-qr.d.ts.map +1 -0
- package/dist/src/cli/tunnel-qr.js +163 -0
- package/dist/src/cli/tunnel-qr.js.map +1 -0
- package/dist/src/cli/tunnel-tester.d.ts +22 -0
- package/dist/src/cli/tunnel-tester.d.ts.map +1 -0
- package/dist/src/cli/tunnel-tester.js +360 -0
- package/dist/src/cli/tunnel-tester.js.map +1 -0
- package/dist/src/cli/types.d.ts +112 -0
- package/dist/src/cli/types.d.ts.map +1 -0
- package/dist/src/cli/types.js +5 -0
- package/dist/src/cli/types.js.map +1 -0
- package/dist/src/push/index.d.ts +1 -0
- package/dist/src/push/index.d.ts.map +1 -1
- package/dist/src/push/index.js +1 -0
- package/dist/src/push/index.js.map +1 -1
- package/dist/src/push/notification-handler.d.ts +58 -0
- package/dist/src/push/notification-handler.d.ts.map +1 -0
- package/dist/src/push/notification-handler.js +110 -0
- package/dist/src/push/notification-handler.js.map +1 -0
- package/dist/src/tunnel/cloudflare.d.ts +32 -3
- package/dist/src/tunnel/cloudflare.d.ts.map +1 -1
- package/dist/src/tunnel/cloudflare.js +102 -32
- package/dist/src/tunnel/cloudflare.js.map +1 -1
- package/dist/src/tunnel/localtunnel.d.ts +28 -1
- package/dist/src/tunnel/localtunnel.d.ts.map +1 -1
- package/dist/src/tunnel/localtunnel.js +53 -11
- package/dist/src/tunnel/localtunnel.js.map +1 -1
- package/dist/src/tunnel/metadata.d.ts +29 -0
- package/dist/src/tunnel/metadata.d.ts.map +1 -0
- package/dist/src/tunnel/metadata.js +83 -0
- package/dist/src/tunnel/metadata.js.map +1 -0
- package/dist/src/tunnel/ngrok.d.ts +12 -0
- package/dist/src/tunnel/ngrok.d.ts.map +1 -1
- package/dist/src/tunnel/ngrok.js +72 -29
- package/dist/src/tunnel/ngrok.js.map +1 -1
- package/dist/src/tunnel/qrcode.d.ts +8 -0
- package/dist/src/tunnel/qrcode.d.ts.map +1 -1
- package/dist/src/tunnel/qrcode.js +60 -9
- package/dist/src/tunnel/qrcode.js.map +1 -1
- package/package.json +21 -3
- package/dist/push-notifications.d.ts +0 -4
- package/dist/push-notifications.d.ts.map +0 -1
- package/dist/push-notifications.js +0 -260
- package/dist/push-notifications.js.map +0 -1
- package/dist/reverse-proxy.d.ts +0 -9
- package/dist/reverse-proxy.d.ts.map +0 -1
- package/dist/reverse-proxy.js +0 -78
- package/dist/reverse-proxy.js.map +0 -1
- package/dist/sdk-logger.d.ts +0 -19
- package/dist/sdk-logger.d.ts.map +0 -1
- package/dist/sdk-logger.js +0 -103
- package/dist/sdk-logger.js.map +0 -1
- package/dist/src/tunnel/index.d.ts +0 -35
- package/dist/src/tunnel/index.d.ts.map +0 -1
- package/dist/src/tunnel/index.js +0 -191
- package/dist/src/tunnel/index.js.map +0 -1
- package/dist/src/utils/index.d.ts +0 -5
- package/dist/src/utils/index.d.ts.map +0 -1
- package/dist/src/utils/index.js +0 -5
- package/dist/src/utils/index.js.map +0 -1
- package/dist/src/utils/port.d.ts +0 -12
- package/dist/src/utils/port.d.ts.map +0 -1
- package/dist/src/utils/port.js +0 -41
- package/dist/src/utils/port.js.map +0 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session notification handler
|
|
3
|
+
*
|
|
4
|
+
* Fetches the last assistant message from a session to form push notifications.
|
|
5
|
+
*
|
|
6
|
+
* USAGE: Uncomment and integrate into main plugin when ready.
|
|
7
|
+
*
|
|
8
|
+
* Integration example:
|
|
9
|
+
*
|
|
10
|
+
* import { handleSessionNotification } from "./notification-handler";
|
|
11
|
+
*
|
|
12
|
+
* export const PushNotificationPlugin: Plugin = async (ctx) => {
|
|
13
|
+
* return {
|
|
14
|
+
* event: async ({ event }) => {
|
|
15
|
+
* if (event.type === "chat.message") {
|
|
16
|
+
* await handleSessionNotification(ctx, event);
|
|
17
|
+
* }
|
|
18
|
+
* },
|
|
19
|
+
* };
|
|
20
|
+
* };
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Handle session notification - fetch last assistant message for context
|
|
24
|
+
*
|
|
25
|
+
* This enables push notifications that include the assistant's response content,
|
|
26
|
+
* allowing users to see what the AI said without opening the app.
|
|
27
|
+
*/
|
|
28
|
+
export async function handleSessionNotification(ctx, event) {
|
|
29
|
+
// UNCOMMENT WHEN READY:
|
|
30
|
+
// const client = (ctx as any).client;
|
|
31
|
+
// if (!client) {
|
|
32
|
+
// logger.warn("No client available for session notification");
|
|
33
|
+
// return null;
|
|
34
|
+
// }
|
|
35
|
+
//
|
|
36
|
+
// try {
|
|
37
|
+
// const response = await client.Session.messages({
|
|
38
|
+
// path: { id: event.sessionID },
|
|
39
|
+
// query: { limit: 50 }
|
|
40
|
+
// });
|
|
41
|
+
//
|
|
42
|
+
// if (!response.data || response.data.length === 0) {
|
|
43
|
+
// logger.warn("No messages found in session");
|
|
44
|
+
// return null;
|
|
45
|
+
// }
|
|
46
|
+
//
|
|
47
|
+
// // Filter for assistant messages and get the last one
|
|
48
|
+
// const assistantMessages = response.data.filter(
|
|
49
|
+
// (msg: any) => msg.info.role === "assistant"
|
|
50
|
+
// );
|
|
51
|
+
//
|
|
52
|
+
// if (assistantMessages.length === 0) {
|
|
53
|
+
// logger.warn("No assistant messages found in session");
|
|
54
|
+
// return null;
|
|
55
|
+
// }
|
|
56
|
+
//
|
|
57
|
+
// const lastAssistant = assistantMessages[assistantMessages.length - 1];
|
|
58
|
+
// const info = lastAssistant.info as any;
|
|
59
|
+
//
|
|
60
|
+
// // Extract text content from parts
|
|
61
|
+
// const textContent = lastAssistant.parts
|
|
62
|
+
// .filter((part: any) => part.type === "text")
|
|
63
|
+
// .map((part: any) => part.text)
|
|
64
|
+
// .join("\n");
|
|
65
|
+
//
|
|
66
|
+
// const result: AssistantMessageInfo = {
|
|
67
|
+
// id: info.id,
|
|
68
|
+
// content: textContent.slice(0, 200) + (textContent.length > 200 ? "..." : ""),
|
|
69
|
+
// model: `${info.providerID}/${info.modelID}`,
|
|
70
|
+
// provider: info.providerID,
|
|
71
|
+
// created: new Date(info.time.created).toISOString(),
|
|
72
|
+
// tokens: info.tokens || { input: 0, output: 0, reasoning: 0 },
|
|
73
|
+
// cost: info.cost || 0,
|
|
74
|
+
// };
|
|
75
|
+
//
|
|
76
|
+
// logger.info("Retrieved last assistant message for notification", {
|
|
77
|
+
// messageID: result.id,
|
|
78
|
+
// model: result.model,
|
|
79
|
+
// contentPreview: result.content.slice(0, 50)
|
|
80
|
+
// });
|
|
81
|
+
//
|
|
82
|
+
// return result;
|
|
83
|
+
//
|
|
84
|
+
// } catch (error) {
|
|
85
|
+
// logger.error("Failed to fetch assistant message for notification", error);
|
|
86
|
+
// return null;
|
|
87
|
+
// }
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Format assistant message for push notification
|
|
92
|
+
*
|
|
93
|
+
* Creates a notification payload from the assistant message info.
|
|
94
|
+
*/
|
|
95
|
+
export function formatAssistantNotification(assistant, sessionName) {
|
|
96
|
+
const title = sessionName ? `Assistant (${sessionName})` : "Assistant Response";
|
|
97
|
+
const body = `Model: ${assistant.model}\n${assistant.content}`;
|
|
98
|
+
return {
|
|
99
|
+
title,
|
|
100
|
+
body: body.slice(0, 150) + (body.length > 150 ? "..." : ""),
|
|
101
|
+
data: {
|
|
102
|
+
type: "assistant_message",
|
|
103
|
+
messageID: assistant.id,
|
|
104
|
+
sessionID: assistant.id,
|
|
105
|
+
model: assistant.model,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export default handleSessionNotification;
|
|
110
|
+
//# sourceMappingURL=notification-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-handler.js","sourceRoot":"","sources":["../../../src/push/notification-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAqBH;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,GAAgB,EAChB,KAA8D;IAE9D,wBAAwB;IACxB,sCAAsC;IACtC,iBAAiB;IACjB,iEAAiE;IACjE,iBAAiB;IACjB,IAAI;IACJ,GAAG;IACH,QAAQ;IACR,qDAAqD;IACrD,qCAAqC;IACrC,2BAA2B;IAC3B,QAAQ;IACR,GAAG;IACH,wDAAwD;IACxD,mDAAmD;IACnD,mBAAmB;IACnB,MAAM;IACN,GAAG;IACH,0DAA0D;IAC1D,oDAAoD;IACpD,kDAAkD;IAClD,OAAO;IACP,GAAG;IACH,0CAA0C;IAC1C,6DAA6D;IAC7D,mBAAmB;IACnB,MAAM;IACN,GAAG;IACH,2EAA2E;IAC3E,4CAA4C;IAC5C,GAAG;IACH,uCAAuC;IACvC,4CAA4C;IAC5C,mDAAmD;IACnD,qCAAqC;IACrC,mBAAmB;IACnB,GAAG;IACH,2CAA2C;IAC3C,mBAAmB;IACnB,oFAAoF;IACpF,mDAAmD;IACnD,iCAAiC;IACjC,0DAA0D;IAC1D,oEAAoE;IACpE,4BAA4B;IAC5B,OAAO;IACP,GAAG;IACH,uEAAuE;IACvE,4BAA4B;IAC5B,2BAA2B;IAC3B,kDAAkD;IAClD,QAAQ;IACR,GAAG;IACH,mBAAmB;IACnB,GAAG;IACH,oBAAoB;IACpB,+EAA+E;IAC/E,iBAAiB;IACjB,IAAI;IAEJ,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,SAA+B,EAC/B,WAAoB;IAEpB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,WAAW,GAAG,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAChF,MAAM,IAAI,GAAG,UAAU,SAAS,CAAC,KAAK,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;IAE/D,OAAO;QACL,KAAK;QACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,IAAI,EAAE;YACJ,IAAI,EAAE,mBAAmB;YACzB,SAAS,EAAE,SAAS,CAAC,EAAE;YACvB,SAAS,EAAE,SAAS,CAAC,EAAE;YACvB,KAAK,EAAE,SAAS,CAAC,KAAK;SACvB;KACF,CAAC;AACJ,CAAC;AAED,eAAe,yBAAyB,CAAC"}
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare tunnel provider implementation
|
|
3
|
+
*
|
|
4
|
+
* Refactored for testability:
|
|
5
|
+
* - Optional spawn function for dependency injection
|
|
6
|
+
* - Optional fs.existsSync for testing
|
|
7
|
+
* - Port validation
|
|
8
|
+
* - Clean separation of concerns
|
|
3
9
|
*/
|
|
10
|
+
import { spawn, ChildProcess } from "child_process";
|
|
4
11
|
import type { TunnelConfig, TunnelInfo } from "./types";
|
|
12
|
+
export type { TunnelConfig, TunnelInfo };
|
|
5
13
|
/**
|
|
6
|
-
* Find cloudflared binary
|
|
14
|
+
* Find cloudflared binary (extracted for testability)
|
|
7
15
|
*/
|
|
8
|
-
export declare function findCloudflared(): string | null;
|
|
16
|
+
export declare function findCloudflared(paths?: string[], existsSync?: (path: string) => boolean): string | null;
|
|
9
17
|
/**
|
|
10
|
-
*
|
|
18
|
+
* Create a cloudflare tunnel instance
|
|
19
|
+
* This function is testable - accepts external spawn and existsSync
|
|
20
|
+
*/
|
|
21
|
+
export declare function createCloudflareTunnel(config: TunnelConfig, spawnFn?: typeof spawn, existsSyncFn?: (path: string) => boolean, onUrl?: (url: string) => void): Promise<TunnelInfo>;
|
|
22
|
+
/**
|
|
23
|
+
* Start a Cloudflare tunnel (legacy function - uses module state)
|
|
11
24
|
*/
|
|
12
25
|
export declare function startCloudflareTunnel(config: TunnelConfig): Promise<TunnelInfo>;
|
|
13
26
|
/**
|
|
@@ -22,4 +35,20 @@ export declare function isCloudflareInstalled(): Promise<boolean>;
|
|
|
22
35
|
* Get the current Cloudflare tunnel URL
|
|
23
36
|
*/
|
|
24
37
|
export declare function getCloudflareUrl(): string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Get current process (for testing)
|
|
40
|
+
*/
|
|
41
|
+
export declare function getProcess(): ChildProcess | null;
|
|
42
|
+
/**
|
|
43
|
+
* Set process (for testing)
|
|
44
|
+
*/
|
|
45
|
+
export declare function setProcess(process: ChildProcess | null): void;
|
|
46
|
+
/**
|
|
47
|
+
* Set URL (for testing)
|
|
48
|
+
*/
|
|
49
|
+
export declare function setUrl(url: string | null): void;
|
|
50
|
+
/**
|
|
51
|
+
* Clear state (for testing)
|
|
52
|
+
*/
|
|
53
|
+
export declare function clearState(): void;
|
|
25
54
|
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGxD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AAczC;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACrC,MAAM,GAAG,IAAI,CAUf;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,OAAO,KAAK,EACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,EACxC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,UAAU,CAAC,CAgFrB;AAgBD;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAErF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,YAAY,GAAG,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAGjC"}
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare tunnel provider implementation
|
|
3
|
+
*
|
|
4
|
+
* Refactored for testability:
|
|
5
|
+
* - Optional spawn function for dependency injection
|
|
6
|
+
* - Optional fs.existsSync for testing
|
|
7
|
+
* - Port validation
|
|
8
|
+
* - Clean separation of concerns
|
|
3
9
|
*/
|
|
4
10
|
import { spawn } from "child_process";
|
|
5
|
-
|
|
6
|
-
let
|
|
11
|
+
// Module-level state (for backward compatibility)
|
|
12
|
+
let _process = null;
|
|
13
|
+
let _url = null;
|
|
14
|
+
// Default paths for cloudflared
|
|
15
|
+
const CLOUDFLARED_PATHS = [
|
|
16
|
+
"/usr/local/bin/cloudflared",
|
|
17
|
+
"/usr/bin/cloudflared",
|
|
18
|
+
`${process.env.HOME || ""}/.cloudflared/cloudflared`,
|
|
19
|
+
"/opt/homebrew/bin/cloudflared",
|
|
20
|
+
];
|
|
7
21
|
/**
|
|
8
|
-
* Find cloudflared binary
|
|
22
|
+
* Find cloudflared binary (extracted for testability)
|
|
9
23
|
*/
|
|
10
|
-
export function findCloudflared() {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
`${process.env.HOME}/.cloudflared/cloudflared`,
|
|
15
|
-
"/opt/homebrew/bin/cloudflared",
|
|
16
|
-
];
|
|
17
|
-
for (const p of paths) {
|
|
24
|
+
export function findCloudflared(paths, existsSync) {
|
|
25
|
+
const searchPaths = paths || CLOUDFLARED_PATHS;
|
|
26
|
+
const checkExists = existsSync || ((p) => require("fs").existsSync(p));
|
|
27
|
+
for (const p of searchPaths) {
|
|
18
28
|
try {
|
|
19
|
-
if (
|
|
29
|
+
if (checkExists(p))
|
|
20
30
|
return p;
|
|
21
31
|
}
|
|
22
32
|
catch { }
|
|
@@ -24,30 +34,45 @@ export function findCloudflared() {
|
|
|
24
34
|
return null;
|
|
25
35
|
}
|
|
26
36
|
/**
|
|
27
|
-
*
|
|
37
|
+
* Create a cloudflare tunnel instance
|
|
38
|
+
* This function is testable - accepts external spawn and existsSync
|
|
28
39
|
*/
|
|
29
|
-
export
|
|
30
|
-
|
|
31
|
-
if (!
|
|
32
|
-
|
|
40
|
+
export function createCloudflareTunnel(config, spawnFn, existsSyncFn, onUrl) {
|
|
41
|
+
// Validate port
|
|
42
|
+
if (!config.port || typeof config.port !== "number") {
|
|
43
|
+
return Promise.reject(new Error("Invalid port: must be a number"));
|
|
44
|
+
}
|
|
45
|
+
// Find cloudflared
|
|
46
|
+
const cloudflaredPath = findCloudflareD(CLOUDFLARED_PATHS, existsSyncFn);
|
|
47
|
+
if (!cloudflaredPath) {
|
|
48
|
+
return Promise.reject(new Error("cloudflared not found. Install from https://github.com/cloudflare/cloudflared"));
|
|
49
|
+
}
|
|
50
|
+
const spawnModule = spawnFn || spawn;
|
|
33
51
|
return new Promise((resolve, reject) => {
|
|
34
52
|
const timeout = setTimeout(() => reject(new Error("Timeout waiting for cloudflared URL (60s)")), 60000);
|
|
35
|
-
|
|
53
|
+
const process = spawnModule(cloudflaredPath, [
|
|
36
54
|
"tunnel",
|
|
37
55
|
"--url",
|
|
38
56
|
`http://127.0.0.1:${config.port}`,
|
|
39
57
|
], { stdio: ["ignore", "pipe", "pipe"] });
|
|
58
|
+
_process = process;
|
|
59
|
+
_url = null;
|
|
40
60
|
const onData = (data) => {
|
|
41
61
|
const line = data.toString().trim();
|
|
42
62
|
const urlMatch = line.match(/https:\/\/[a-zA-Z0-9-]+\.trycloudflare\.com/);
|
|
43
63
|
if (urlMatch) {
|
|
44
64
|
const url = urlMatch[0];
|
|
45
|
-
|
|
65
|
+
_url = url;
|
|
66
|
+
if (onUrl) {
|
|
67
|
+
onUrl(url);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
console.log("[Cloudflared] URL:", url);
|
|
71
|
+
}
|
|
46
72
|
clearTimeout(timeout);
|
|
47
|
-
cloudflareUrl = url;
|
|
48
73
|
resolve({
|
|
49
|
-
url:
|
|
50
|
-
tunnelId:
|
|
74
|
+
url: _url,
|
|
75
|
+
tunnelId: _url.split("://")[1].split(".")[0],
|
|
51
76
|
port: config.port,
|
|
52
77
|
provider: "cloudflare",
|
|
53
78
|
});
|
|
@@ -56,35 +81,55 @@ export async function startCloudflareTunnel(config) {
|
|
|
56
81
|
console.log("[Cloudflared]", line);
|
|
57
82
|
}
|
|
58
83
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
84
|
+
process.stdout?.on("data", onData);
|
|
85
|
+
process.stderr?.on("data", onData);
|
|
86
|
+
process.on("error", (err) => {
|
|
62
87
|
clearTimeout(timeout);
|
|
88
|
+
_process = null;
|
|
63
89
|
reject(err);
|
|
64
90
|
});
|
|
65
|
-
|
|
91
|
+
process.on("exit", (code) => {
|
|
66
92
|
// If no URL was captured, treat as failure even on clean exit
|
|
67
|
-
if (!
|
|
93
|
+
if (!_url) {
|
|
68
94
|
clearTimeout(timeout);
|
|
95
|
+
_process = null;
|
|
69
96
|
reject(new Error("cloudflared exited without providing a tunnel URL"));
|
|
70
97
|
return;
|
|
71
98
|
}
|
|
72
99
|
if (code !== 0 && code !== null) {
|
|
73
100
|
clearTimeout(timeout);
|
|
101
|
+
_process = null;
|
|
74
102
|
reject(new Error(`cloudflared exited with code ${code}`));
|
|
75
103
|
}
|
|
76
104
|
});
|
|
77
105
|
});
|
|
78
106
|
}
|
|
107
|
+
function findCloudflareD(paths, existsSync) {
|
|
108
|
+
const checkExists = existsSync || ((p) => require("fs").existsSync(p));
|
|
109
|
+
for (const p of paths) {
|
|
110
|
+
try {
|
|
111
|
+
if (checkExists(p))
|
|
112
|
+
return p;
|
|
113
|
+
}
|
|
114
|
+
catch { }
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Start a Cloudflare tunnel (legacy function - uses module state)
|
|
120
|
+
*/
|
|
121
|
+
export async function startCloudflareTunnel(config) {
|
|
122
|
+
return createCloudflareTunnel(config);
|
|
123
|
+
}
|
|
79
124
|
/**
|
|
80
125
|
* Stop the Cloudflare tunnel
|
|
81
126
|
*/
|
|
82
127
|
export async function stopCloudflareTunnel() {
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
|
|
128
|
+
if (_process) {
|
|
129
|
+
_process.kill("SIGTERM");
|
|
130
|
+
_process = null;
|
|
86
131
|
}
|
|
87
|
-
|
|
132
|
+
_url = null;
|
|
88
133
|
}
|
|
89
134
|
/**
|
|
90
135
|
* Check if cloudflared is installed
|
|
@@ -96,6 +141,31 @@ export async function isCloudflareInstalled() {
|
|
|
96
141
|
* Get the current Cloudflare tunnel URL
|
|
97
142
|
*/
|
|
98
143
|
export function getCloudflareUrl() {
|
|
99
|
-
return
|
|
144
|
+
return _url;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get current process (for testing)
|
|
148
|
+
*/
|
|
149
|
+
export function getProcess() {
|
|
150
|
+
return _process;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Set process (for testing)
|
|
154
|
+
*/
|
|
155
|
+
export function setProcess(process) {
|
|
156
|
+
_process = process;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Set URL (for testing)
|
|
160
|
+
*/
|
|
161
|
+
export function setUrl(url) {
|
|
162
|
+
_url = url;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Clear state (for testing)
|
|
166
|
+
*/
|
|
167
|
+
export function clearState() {
|
|
168
|
+
_process = null;
|
|
169
|
+
_url = null;
|
|
100
170
|
}
|
|
101
171
|
//# sourceMappingURL=cloudflare.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Localtunnel tunnel provider implementation
|
|
3
|
+
*
|
|
4
|
+
* Refactored for testability:
|
|
5
|
+
* - Optional instance parameter for dependency injection
|
|
6
|
+
* - Port validation
|
|
7
|
+
* - Clean separation of concerns
|
|
3
8
|
*/
|
|
9
|
+
import localtunnel from "localtunnel";
|
|
4
10
|
import type { TunnelConfig, TunnelInfo } from "./types";
|
|
11
|
+
export type { TunnelConfig, TunnelInfo };
|
|
5
12
|
/**
|
|
6
|
-
*
|
|
13
|
+
* Create a localtunnel instance
|
|
14
|
+
* This function is testable - accepts external localtunnel for mocking
|
|
15
|
+
*/
|
|
16
|
+
export declare function createLocaltunnel(config: TunnelConfig, options?: {
|
|
17
|
+
localtunnelModule?: typeof localtunnel;
|
|
18
|
+
onUrl?: (url: string) => void;
|
|
19
|
+
}): Promise<TunnelInfo>;
|
|
20
|
+
/**
|
|
21
|
+
* Start a localtunnel (legacy function - uses module state)
|
|
7
22
|
*/
|
|
8
23
|
export declare function startLocaltunnel(config: TunnelConfig): Promise<TunnelInfo>;
|
|
9
24
|
/**
|
|
@@ -14,4 +29,16 @@ export declare function stopLocaltunnel(): Promise<void>;
|
|
|
14
29
|
* Get the current localtunnel URL
|
|
15
30
|
*/
|
|
16
31
|
export declare function getLocaltunnelUrl(): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* Get current instance (for testing)
|
|
34
|
+
*/
|
|
35
|
+
export declare function getInstance(): any;
|
|
36
|
+
/**
|
|
37
|
+
* Set instance (for testing)
|
|
38
|
+
*/
|
|
39
|
+
export declare function setInstance(instance: any): void;
|
|
40
|
+
/**
|
|
41
|
+
* Clear instance (for testing)
|
|
42
|
+
*/
|
|
43
|
+
export declare function clearInstance(): void;
|
|
17
44
|
//# sourceMappingURL=localtunnel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localtunnel.d.ts","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"localtunnel.d.ts","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,WAAW,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGxD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AAMzC;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE;IACP,iBAAiB,CAAC,EAAE,OAAO,WAAW,CAAC;IACvC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1B,GACL,OAAO,CAAC,UAAU,CAAC,CA6CrB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAEhF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,GAAG,CAEjC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
|
|
@@ -1,25 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Localtunnel tunnel provider implementation
|
|
3
|
+
*
|
|
4
|
+
* Refactored for testability:
|
|
5
|
+
* - Optional instance parameter for dependency injection
|
|
6
|
+
* - Port validation
|
|
7
|
+
* - Clean separation of concerns
|
|
3
8
|
*/
|
|
4
9
|
import localtunnel from "localtunnel";
|
|
5
|
-
|
|
10
|
+
// Module-level state (for backward compatibility)
|
|
11
|
+
// Use the factory functions for testable code
|
|
12
|
+
let _instance = null;
|
|
6
13
|
/**
|
|
7
|
-
*
|
|
14
|
+
* Create a localtunnel instance
|
|
15
|
+
* This function is testable - accepts external localtunnel for mocking
|
|
8
16
|
*/
|
|
9
|
-
export
|
|
17
|
+
export function createLocaltunnel(config, options = {}) {
|
|
18
|
+
const { localtunnelModule = localtunnel, onUrl } = options;
|
|
19
|
+
// Validate port
|
|
20
|
+
if (!config.port || typeof config.port !== "number") {
|
|
21
|
+
return Promise.reject(new Error("Invalid port: must be a number"));
|
|
22
|
+
}
|
|
10
23
|
return new Promise((resolve, reject) => {
|
|
11
24
|
const timeout = setTimeout(() => reject(new Error("Timeout waiting for localtunnel URL (30s)")), 30000);
|
|
12
|
-
|
|
25
|
+
localtunnelModule({ port: config.port, subdomain: config.subdomain }, (err, tunnel) => {
|
|
13
26
|
if (err) {
|
|
14
27
|
clearTimeout(timeout);
|
|
15
28
|
reject(new Error(`Localtunnel failed: ${err.message}`));
|
|
16
29
|
return;
|
|
17
30
|
}
|
|
18
31
|
clearTimeout(timeout);
|
|
19
|
-
|
|
20
|
-
|
|
32
|
+
_instance = tunnel;
|
|
33
|
+
if (onUrl) {
|
|
34
|
+
onUrl(tunnel.url);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log("[Tunnel] URL:", tunnel.url);
|
|
38
|
+
}
|
|
21
39
|
tunnel.on("close", () => {
|
|
22
|
-
|
|
40
|
+
_instance = null;
|
|
23
41
|
});
|
|
24
42
|
resolve({
|
|
25
43
|
url: tunnel.url,
|
|
@@ -30,19 +48,43 @@ export async function startLocaltunnel(config) {
|
|
|
30
48
|
});
|
|
31
49
|
});
|
|
32
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Start a localtunnel (legacy function - uses module state)
|
|
53
|
+
*/
|
|
54
|
+
export async function startLocaltunnel(config) {
|
|
55
|
+
return createLocaltunnel(config);
|
|
56
|
+
}
|
|
33
57
|
/**
|
|
34
58
|
* Stop the localtunnel
|
|
35
59
|
*/
|
|
36
60
|
export async function stopLocaltunnel() {
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
61
|
+
if (_instance) {
|
|
62
|
+
_instance.close();
|
|
63
|
+
_instance = null;
|
|
40
64
|
}
|
|
41
65
|
}
|
|
42
66
|
/**
|
|
43
67
|
* Get the current localtunnel URL
|
|
44
68
|
*/
|
|
45
69
|
export function getLocaltunnelUrl() {
|
|
46
|
-
return
|
|
70
|
+
return _instance?.url || null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get current instance (for testing)
|
|
74
|
+
*/
|
|
75
|
+
export function getInstance() {
|
|
76
|
+
return _instance;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Set instance (for testing)
|
|
80
|
+
*/
|
|
81
|
+
export function setInstance(instance) {
|
|
82
|
+
_instance = instance;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Clear instance (for testing)
|
|
86
|
+
*/
|
|
87
|
+
export function clearInstance() {
|
|
88
|
+
_instance = null;
|
|
47
89
|
}
|
|
48
90
|
//# sourceMappingURL=localtunnel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localtunnel.js","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"localtunnel.js","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,WAAW,MAAM,aAAa,CAAC;AAMtC,kDAAkD;AAClD,8CAA8C;AAC9C,IAAI,SAAS,GAAQ,IAAI,CAAC;AAE1B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAoB,EACpB,UAGI,EAAE;IAEN,MAAM,EAAE,iBAAiB,GAAG,WAAW,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE3D,gBAAgB;IAChB,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,UAAU,CACxB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC,EACpE,KAAK,CACN,CAAC;QAEF,iBAAiB,CACf,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EAClD,CAAC,GAAQ,EAAE,MAAW,EAAE,EAAE;YACxB,IAAI,GAAG,EAAE,CAAC;gBACR,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACxD,OAAO;YACT,CAAC;YAED,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,SAAS,GAAG,MAAM,CAAC;YAEnB,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3C,CAAC;YAED,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACtB,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC;gBACN,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAClD,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,aAAa;aACxB,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAoB;IACzD,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,KAAK,EAAE,CAAC;QAClB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,SAAS,EAAE,GAAG,IAAI,IAAI,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAAa;IACvC,SAAS,GAAG,QAAQ,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunnel metadata storage for .config/opencode/tunnel.json
|
|
3
|
+
*/
|
|
4
|
+
export interface TunnelMetadata {
|
|
5
|
+
url: string | null;
|
|
6
|
+
tunnelId: string | null;
|
|
7
|
+
provider: string | null;
|
|
8
|
+
port: number | null;
|
|
9
|
+
targetPort: number | null;
|
|
10
|
+
startedAt: string | null;
|
|
11
|
+
lastUpdated: string | null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Load tunnel metadata from disk
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadTunnelMetadata(): TunnelMetadata;
|
|
17
|
+
/**
|
|
18
|
+
* Save tunnel metadata to disk
|
|
19
|
+
*/
|
|
20
|
+
export declare function saveTunnelMetadata(metadata: TunnelMetadata): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Update tunnel metadata when a tunnel starts
|
|
23
|
+
*/
|
|
24
|
+
export declare function updateTunnelMetadata(url: string, tunnelId: string, provider: string, port: number, targetPort: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Clear tunnel metadata when tunnel stops
|
|
27
|
+
*/
|
|
28
|
+
export declare function clearTunnelMetadata(): void;
|
|
29
|
+
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../../src/tunnel/metadata.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CAkBnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAapE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,IAAI,CAaN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAa1C"}
|