@synergenius/flow-weaver 0.10.10 → 0.10.12
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/dist/cli/commands/tunnel.d.ts +19 -0
- package/dist/cli/commands/tunnel.js +119 -0
- package/dist/cli/flow-weaver.mjs +58840 -50902
- package/dist/cli/index.js +17 -0
- package/dist/cli/tunnel/dispatch.d.ts +18 -0
- package/dist/cli/tunnel/dispatch.js +36 -0
- package/dist/cli/tunnel/file-lock.d.ts +9 -0
- package/dist/cli/tunnel/file-lock.js +36 -0
- package/dist/cli/tunnel/handlers/ast-ops.d.ts +10 -0
- package/dist/cli/tunnel/handlers/ast-ops.js +252 -0
- package/dist/cli/tunnel/handlers/execution.d.ts +7 -0
- package/dist/cli/tunnel/handlers/execution.js +89 -0
- package/dist/cli/tunnel/handlers/file-ops.d.ts +7 -0
- package/dist/cli/tunnel/handlers/file-ops.js +204 -0
- package/dist/cli/tunnel/handlers/mutations.d.ts +7 -0
- package/dist/cli/tunnel/handlers/mutations.js +285 -0
- package/dist/cli/tunnel/handlers/stubs.d.ts +7 -0
- package/dist/cli/tunnel/handlers/stubs.js +141 -0
- package/dist/cli/tunnel/handlers/templates.d.ts +7 -0
- package/dist/cli/tunnel/handlers/templates.js +123 -0
- package/dist/cli/tunnel/path-resolver.d.ts +17 -0
- package/dist/cli/tunnel/path-resolver.js +52 -0
- package/package.json +3 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tunnel command — Self-contained tunnel for cloud Studio.
|
|
3
|
+
*
|
|
4
|
+
* Handles all RPC methods locally using Node.js fs and the
|
|
5
|
+
* @synergenius/flow-weaver AST API. No local server required.
|
|
6
|
+
*
|
|
7
|
+
* 1. Opens a WebSocket to the cloud server's /api/tunnel endpoint.
|
|
8
|
+
* 2. Dispatches RPC calls directly to local handler functions.
|
|
9
|
+
*/
|
|
10
|
+
import WebSocket from 'ws';
|
|
11
|
+
export interface TunnelOptions {
|
|
12
|
+
key: string;
|
|
13
|
+
cloud?: string;
|
|
14
|
+
dir?: string;
|
|
15
|
+
/** Override WebSocket factory (for testing) */
|
|
16
|
+
createWs?: (url: string) => WebSocket;
|
|
17
|
+
}
|
|
18
|
+
export declare function tunnelCommand(options: TunnelOptions): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=tunnel.d.ts.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tunnel command — Self-contained tunnel for cloud Studio.
|
|
3
|
+
*
|
|
4
|
+
* Handles all RPC methods locally using Node.js fs and the
|
|
5
|
+
* @synergenius/flow-weaver AST API. No local server required.
|
|
6
|
+
*
|
|
7
|
+
* 1. Opens a WebSocket to the cloud server's /api/tunnel endpoint.
|
|
8
|
+
* 2. Dispatches RPC calls directly to local handler functions.
|
|
9
|
+
*/
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import WebSocket from 'ws';
|
|
12
|
+
import { logger } from '../utils/logger.js';
|
|
13
|
+
import { dispatch } from '../tunnel/dispatch.js';
|
|
14
|
+
export async function tunnelCommand(options) {
|
|
15
|
+
const cloudUrl = options.cloud || 'https://flowweaver.dev';
|
|
16
|
+
const workspaceRoot = path.resolve(options.dir || process.cwd());
|
|
17
|
+
const createWs = options.createWs ?? ((url) => new WebSocket(url));
|
|
18
|
+
logger.section('Flow Weaver Tunnel');
|
|
19
|
+
logger.info(`Cloud: ${cloudUrl}`);
|
|
20
|
+
logger.info(`Workspace: ${workspaceRoot}`);
|
|
21
|
+
logger.newline();
|
|
22
|
+
// -----------------------------------------------------------------------
|
|
23
|
+
// 1. Connect to cloud server via WebSocket
|
|
24
|
+
// -----------------------------------------------------------------------
|
|
25
|
+
logger.info('Connecting to cloud server...');
|
|
26
|
+
const wsProtocol = cloudUrl.startsWith('https') ? 'wss' : 'ws';
|
|
27
|
+
const wsHost = cloudUrl.replace(/^https?:\/\//, '');
|
|
28
|
+
const wsUrl = `${wsProtocol}://${wsHost}/api/tunnel?token=${encodeURIComponent(options.key)}`;
|
|
29
|
+
const cloudWs = createWs(wsUrl);
|
|
30
|
+
await new Promise((resolve, reject) => {
|
|
31
|
+
const timeout = setTimeout(() => {
|
|
32
|
+
cloudWs.close();
|
|
33
|
+
reject(new Error('Cloud server connection timeout (10s)'));
|
|
34
|
+
}, 10_000);
|
|
35
|
+
cloudWs.on('open', () => {
|
|
36
|
+
clearTimeout(timeout);
|
|
37
|
+
});
|
|
38
|
+
cloudWs.on('message', (raw) => {
|
|
39
|
+
try {
|
|
40
|
+
const msg = JSON.parse(raw.toString());
|
|
41
|
+
if (msg.type === 'tunnel:hello') {
|
|
42
|
+
logger.success('Connected to cloud server');
|
|
43
|
+
resolve();
|
|
44
|
+
}
|
|
45
|
+
else if (msg.type === 'error') {
|
|
46
|
+
clearTimeout(timeout);
|
|
47
|
+
cloudWs.close();
|
|
48
|
+
reject(new Error(`Cloud server rejected connection: ${msg.message}`));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Ignore parse errors during handshake
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
cloudWs.on('error', (err) => {
|
|
56
|
+
clearTimeout(timeout);
|
|
57
|
+
reject(new Error(`Cannot connect to cloud server: ${err.message}`));
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
logger.newline();
|
|
61
|
+
logger.success('Tunnel active — local development mode enabled');
|
|
62
|
+
logger.info('Press Ctrl+C to disconnect');
|
|
63
|
+
logger.newline();
|
|
64
|
+
let requestCount = 0;
|
|
65
|
+
const ctx = { workspaceRoot };
|
|
66
|
+
// -----------------------------------------------------------------------
|
|
67
|
+
// 2. Handle RPC: cloud → local dispatch → cloud
|
|
68
|
+
// -----------------------------------------------------------------------
|
|
69
|
+
cloudWs.on('message', async (raw) => {
|
|
70
|
+
let msg;
|
|
71
|
+
try {
|
|
72
|
+
msg = JSON.parse(raw.toString());
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (msg.type === 'ping') {
|
|
78
|
+
cloudWs.send(JSON.stringify({ type: 'pong' }));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (msg.type === 'tunnel:request') {
|
|
82
|
+
const req = msg;
|
|
83
|
+
requestCount++;
|
|
84
|
+
logger.debug(`[${requestCount}] → ${req.method}`);
|
|
85
|
+
const response = await dispatch(req.method, req.params || {}, ctx);
|
|
86
|
+
cloudWs.send(JSON.stringify({
|
|
87
|
+
type: 'tunnel:response',
|
|
88
|
+
requestId: req.requestId,
|
|
89
|
+
id: req.id,
|
|
90
|
+
success: response.success,
|
|
91
|
+
result: response.result,
|
|
92
|
+
error: response.error,
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
// -----------------------------------------------------------------------
|
|
97
|
+
// 3. Handle disconnections
|
|
98
|
+
// -----------------------------------------------------------------------
|
|
99
|
+
cloudWs.on('close', (code, reason) => {
|
|
100
|
+
logger.warn(`Cloud server disconnected: ${code} ${reason.toString()}`);
|
|
101
|
+
logger.info('Shutting down tunnel...');
|
|
102
|
+
process.exit(code === 4001 ? 1 : 0);
|
|
103
|
+
});
|
|
104
|
+
cloudWs.on('error', (err) => {
|
|
105
|
+
logger.error(`Cloud WebSocket error: ${err.message}`);
|
|
106
|
+
});
|
|
107
|
+
// -----------------------------------------------------------------------
|
|
108
|
+
// 4. Graceful shutdown
|
|
109
|
+
// -----------------------------------------------------------------------
|
|
110
|
+
process.on('SIGINT', () => {
|
|
111
|
+
logger.newline();
|
|
112
|
+
logger.info(`Shutting down tunnel (${requestCount} requests handled)...`);
|
|
113
|
+
cloudWs.close();
|
|
114
|
+
process.exit(0);
|
|
115
|
+
});
|
|
116
|
+
// Keep alive until SIGINT or cloud disconnect
|
|
117
|
+
await new Promise(() => { });
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=tunnel.js.map
|