@leverageaiapps/theseus-server 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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/dist/capture.d.ts +3 -0
  4. package/dist/capture.d.ts.map +1 -0
  5. package/dist/capture.js +134 -0
  6. package/dist/capture.js.map +1 -0
  7. package/dist/cloudflare-tunnel.d.ts +9 -0
  8. package/dist/cloudflare-tunnel.d.ts.map +1 -0
  9. package/dist/cloudflare-tunnel.js +218 -0
  10. package/dist/cloudflare-tunnel.js.map +1 -0
  11. package/dist/config.d.ts +7 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +84 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/context-extractor.d.ts +17 -0
  16. package/dist/context-extractor.d.ts.map +1 -0
  17. package/dist/context-extractor.js +118 -0
  18. package/dist/context-extractor.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +45 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/pty.d.ts +20 -0
  24. package/dist/pty.d.ts.map +1 -0
  25. package/dist/pty.js +148 -0
  26. package/dist/pty.js.map +1 -0
  27. package/dist/relay.d.ts +5 -0
  28. package/dist/relay.d.ts.map +1 -0
  29. package/dist/relay.js +131 -0
  30. package/dist/relay.js.map +1 -0
  31. package/dist/session.d.ts +5 -0
  32. package/dist/session.d.ts.map +1 -0
  33. package/dist/session.js +257 -0
  34. package/dist/session.js.map +1 -0
  35. package/dist/voice-recognition-modelscope.d.ts +50 -0
  36. package/dist/voice-recognition-modelscope.d.ts.map +1 -0
  37. package/dist/voice-recognition-modelscope.js +171 -0
  38. package/dist/voice-recognition-modelscope.js.map +1 -0
  39. package/dist/web-server.d.ts +6 -0
  40. package/dist/web-server.d.ts.map +1 -0
  41. package/dist/web-server.js +1971 -0
  42. package/dist/web-server.js.map +1 -0
  43. package/package.json +66 -0
  44. package/public/index.html +639 -0
  45. package/public/js/terminal-asr.js +508 -0
  46. package/public/js/terminal.js +514 -0
  47. package/public/js/voice-input.js +422 -0
  48. package/scripts/postinstall.js +66 -0
  49. package/scripts/verify-install.js +124 -0
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.startSession = startSession;
37
+ const qrcode = __importStar(require("qrcode-terminal"));
38
+ const net = __importStar(require("net"));
39
+ const http = __importStar(require("http"));
40
+ const pty_1 = require("./pty");
41
+ const web_server_1 = require("./web-server");
42
+ const cloudflare_tunnel_1 = require("./cloudflare-tunnel");
43
+ const MIN_PORT = 8000;
44
+ const MAX_PORT = 65535;
45
+ /**
46
+ * Generate a random 6-digit PIN
47
+ */
48
+ function generateRandomPIN() {
49
+ return Math.floor(100000 + Math.random() * 900000).toString();
50
+ }
51
+ /**
52
+ * Validate PIN format (6 digits)
53
+ */
54
+ function validatePIN(pin) {
55
+ return /^\d{6}$/.test(pin);
56
+ }
57
+ /**
58
+ * Check if a port is available
59
+ */
60
+ function isPortAvailable(port) {
61
+ return new Promise((resolve) => {
62
+ const server = net.createServer();
63
+ server.listen(port, () => {
64
+ server.once('close', () => {
65
+ resolve(true);
66
+ });
67
+ server.close();
68
+ });
69
+ server.on('error', () => {
70
+ resolve(false);
71
+ });
72
+ });
73
+ }
74
+ /**
75
+ * Find an available port in the specified range
76
+ */
77
+ async function findAvailablePort() {
78
+ const maxAttempts = 100;
79
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
80
+ const port = Math.floor(Math.random() * (MAX_PORT - MIN_PORT + 1)) + MIN_PORT;
81
+ if (await isPortAvailable(port)) {
82
+ return port;
83
+ }
84
+ }
85
+ throw new Error(`Unable to find available port after ${maxAttempts} attempts`);
86
+ }
87
+ /**
88
+ * Verify that the web server is actually accessible
89
+ */
90
+ function verifyServerStarted(port) {
91
+ return new Promise((resolve, reject) => {
92
+ const maxAttempts = 10;
93
+ let attempts = 0;
94
+ const checkServer = () => {
95
+ attempts++;
96
+ const req = http.get(`http://localhost:${port}/health`, (res) => {
97
+ // Server is responding, even if with 404 (health endpoint doesn't exist)
98
+ // The important thing is that the server is reachable
99
+ resolve();
100
+ });
101
+ req.on('error', (err) => {
102
+ if (attempts >= maxAttempts) {
103
+ reject(new Error(`Server failed to start on port ${port} after ${maxAttempts} attempts`));
104
+ }
105
+ else {
106
+ // Try again after a short delay
107
+ setTimeout(checkServer, 200);
108
+ }
109
+ });
110
+ req.setTimeout(1000, () => {
111
+ req.destroy();
112
+ if (attempts >= maxAttempts) {
113
+ reject(new Error(`Server startup timeout on port ${port}`));
114
+ }
115
+ else {
116
+ setTimeout(checkServer, 200);
117
+ }
118
+ });
119
+ };
120
+ checkServer();
121
+ });
122
+ }
123
+ /**
124
+ * Generate QR code for terminal
125
+ */
126
+ function displayQRCode(url) {
127
+ console.log('');
128
+ console.log(' 📱 Scan this QR code with your phone:');
129
+ console.log('');
130
+ qrcode.generate(url, { small: true }, (qr) => {
131
+ console.log(qr);
132
+ });
133
+ console.log('');
134
+ console.log(` 📱 Or open: ${url}`);
135
+ console.log('');
136
+ }
137
+ async function startSession(machineName, userPin, command, options = {}) {
138
+ console.log('');
139
+ console.log(' 🚀 Theseus - Coding anywhere in your pocket');
140
+ console.log('');
141
+ // Bypass system proxy to avoid issues with Shadowrocket, Clash, etc.
142
+ // These proxies can interfere with localhost connections
143
+ delete process.env.HTTP_PROXY;
144
+ delete process.env.HTTPS_PROXY;
145
+ delete process.env.http_proxy;
146
+ delete process.env.https_proxy;
147
+ delete process.env.ALL_PROXY;
148
+ delete process.env.all_proxy;
149
+ // Set NO_PROXY to ensure local connections bypass any remaining proxy
150
+ process.env.NO_PROXY = 'localhost,127.0.0.1,*.local,*.trycloudflare.com';
151
+ process.env.no_proxy = process.env.NO_PROXY;
152
+ try {
153
+ // Generate or validate PIN silently
154
+ let pin;
155
+ if (userPin) {
156
+ if (validatePIN(userPin)) {
157
+ pin = userPin;
158
+ }
159
+ else {
160
+ throw new Error('PIN must be exactly 6 digits');
161
+ }
162
+ }
163
+ else {
164
+ pin = generateRandomPIN();
165
+ }
166
+ // Show progress steps
167
+ console.log(' Finding available port...');
168
+ const port = await findAvailablePort();
169
+ console.log(` Using port: ${port}`);
170
+ console.log(' Starting local server...');
171
+ await (0, web_server_1.startWebServer)(port, pin, { debugAsr: options.debugAsr });
172
+ // Verify server is accessible before creating tunnel
173
+ await verifyServerStarted(port);
174
+ console.log(' Creating tunnel...');
175
+ let tunnelUrl;
176
+ try {
177
+ tunnelUrl = await (0, cloudflare_tunnel_1.startTunnel)(port);
178
+ }
179
+ catch (error) {
180
+ console.log('');
181
+ console.log(' ❌ Failed to create tunnel:');
182
+ console.log('');
183
+ console.log(error instanceof Error ? error.message : String(error));
184
+ console.log('');
185
+ process.exit(1);
186
+ }
187
+ // Display QR code and connection info
188
+ displayQRCode(tunnelUrl);
189
+ // Show PIN after QR code
190
+ if (userPin) {
191
+ console.log(` PIN for web access: ${pin}`);
192
+ }
193
+ else {
194
+ console.log(` Generated PIN for web access: ${pin}`);
195
+ }
196
+ console.log('');
197
+ console.log(' Started.');
198
+ console.log('');
199
+ // Determine what to run
200
+ let commandToRun;
201
+ let argsToRun;
202
+ if (command && command.length > 0) {
203
+ // Check if first argument contains spaces (quoted command)
204
+ if (command.length === 1 && command[0].includes(' ')) {
205
+ // Single quoted command like "claude --dangerously-skip-permissions"
206
+ const parts = command[0].split(' ');
207
+ commandToRun = parts[0];
208
+ argsToRun = parts.slice(1);
209
+ }
210
+ else {
211
+ // Normal command with separate arguments
212
+ commandToRun = command[0];
213
+ argsToRun = command.slice(1);
214
+ }
215
+ }
216
+ else {
217
+ // No command provided, just start a shell
218
+ const shell = process.env.SHELL || '/bin/zsh';
219
+ commandToRun = shell;
220
+ argsToRun = [];
221
+ }
222
+ // Spawn the command in PTY
223
+ (0, pty_1.spawnPTY)({
224
+ command: commandToRun,
225
+ args: argsToRun,
226
+ cwd: process.cwd(),
227
+ });
228
+ // Handle command exit
229
+ (0, pty_1.onPTYExit)((code) => {
230
+ console.log('');
231
+ if (command && command.length > 0) {
232
+ console.log(` ${command.join(' ')} exited. Session ended.`);
233
+ }
234
+ else {
235
+ console.log(' Terminal session ended.');
236
+ }
237
+ cleanup();
238
+ });
239
+ // Cleanup function
240
+ const cleanup = () => {
241
+ (0, pty_1.killPTY)();
242
+ (0, web_server_1.stopWebServer)();
243
+ (0, cloudflare_tunnel_1.stopTunnel)();
244
+ process.exit(0);
245
+ };
246
+ // Handle Ctrl+C
247
+ process.on('SIGINT', cleanup);
248
+ process.on('SIGTERM', cleanup);
249
+ }
250
+ catch (error) {
251
+ console.error(' ✗ Failed to start session:', error);
252
+ (0, web_server_1.stopWebServer)();
253
+ (0, cloudflare_tunnel_1.stopTunnel)();
254
+ process.exit(1);
255
+ }
256
+ }
257
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { EventEmitter } from 'events';
2
+ interface ModelScopeConfig {
3
+ apiKey?: string;
4
+ apiUrl?: string;
5
+ model?: string;
6
+ language?: string;
7
+ maxContextLength?: number;
8
+ }
9
+ export declare class VoiceRecognitionModelScope extends EventEmitter {
10
+ private apiKey;
11
+ private apiUrl;
12
+ private model;
13
+ private language;
14
+ private maxContextLength;
15
+ private audioBuffer;
16
+ private isRecording;
17
+ private streamingSession;
18
+ private contextText;
19
+ constructor(config?: ModelScopeConfig);
20
+ /**
21
+ * Update the context for better recognition accuracy
22
+ */
23
+ updateContext(terminalOutput: string[]): void;
24
+ /**
25
+ * Start streaming recognition
26
+ */
27
+ startStreamingRecognition(): Promise<void>;
28
+ /**
29
+ * Send audio chunk for recognition
30
+ */
31
+ sendAudioChunk(audioData: Buffer): Promise<void>;
32
+ /**
33
+ * Stop recognition
34
+ */
35
+ stopRecognition(): void;
36
+ /**
37
+ * Check if API is properly configured
38
+ */
39
+ isConfigured(): boolean;
40
+ /**
41
+ * Get current context
42
+ */
43
+ getContext(): string;
44
+ /**
45
+ * Set maximum context length
46
+ */
47
+ setMaxContextLength(length: number): void;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=voice-recognition-modelscope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-recognition-modelscope.d.ts","sourceRoot":"","sources":["../src/voice-recognition-modelscope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,UAAU,gBAAgB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAQD,qBAAa,0BAA2B,SAAQ,YAAY;IACxD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,WAAW,CAAc;gBAErB,MAAM,GAAE,gBAAqB;IAazC;;OAEG;IACI,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI;IAcpD;;OAEG;IACU,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCvD;;OAEG;IACU,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2E7D;;OAEG;IACI,eAAe,IAAI,IAAI;IAO9B;;OAEG;IACI,YAAY,IAAI,OAAO;IAI9B;;OAEG;IACI,UAAU,IAAI,MAAM;IAI3B;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGnD"}
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VoiceRecognitionModelScope = void 0;
7
+ const events_1 = require("events");
8
+ const axios_1 = __importDefault(require("axios"));
9
+ class VoiceRecognitionModelScope extends events_1.EventEmitter {
10
+ constructor(config = {}) {
11
+ super();
12
+ this.audioBuffer = [];
13
+ this.isRecording = false;
14
+ this.streamingSession = null;
15
+ this.contextText = '';
16
+ this.apiKey = config.apiKey || process.env.MODELSCOPE_API_KEY || '';
17
+ this.apiUrl = config.apiUrl || 'https://api-inference.modelscope.cn/v1/';
18
+ this.model = config.model || 'qwen3-asr-flash';
19
+ this.language = config.language || 'zh';
20
+ this.maxContextLength = config.maxContextLength || 2000;
21
+ if (!this.apiKey) {
22
+ console.warn('[ModelScope ASR] API key not configured. Set MODELSCOPE_API_KEY environment variable.');
23
+ }
24
+ }
25
+ /**
26
+ * Update the context for better recognition accuracy
27
+ */
28
+ updateContext(terminalOutput) {
29
+ // Extract the most recent terminal output as context
30
+ const recentOutput = terminalOutput.slice(-50).join('\n');
31
+ // Truncate to max context length
32
+ if (recentOutput.length > this.maxContextLength) {
33
+ this.contextText = recentOutput.slice(-this.maxContextLength);
34
+ }
35
+ else {
36
+ this.contextText = recentOutput;
37
+ }
38
+ console.log('[ModelScope ASR] Context updated, length:', this.contextText.length);
39
+ }
40
+ /**
41
+ * Start streaming recognition
42
+ */
43
+ async startStreamingRecognition() {
44
+ if (!this.apiKey) {
45
+ this.emit('error', new Error('ModelScope API key not configured'));
46
+ return;
47
+ }
48
+ this.isRecording = true;
49
+ this.audioBuffer = [];
50
+ try {
51
+ // Initialize streaming session with ModelScope
52
+ const response = await axios_1.default.post(`${this.apiUrl}audio/transcriptions/stream`, {
53
+ model: this.model,
54
+ language: this.language,
55
+ stream: true,
56
+ context: this.contextText,
57
+ enable_itn: false, // Disable inverse text normalization
58
+ response_format: 'json'
59
+ }, {
60
+ headers: {
61
+ 'Authorization': `Bearer ${this.apiKey}`,
62
+ 'Content-Type': 'application/json',
63
+ 'X-DashScope-SSE': 'enable' // Enable server-sent events for streaming
64
+ }
65
+ });
66
+ this.streamingSession = response.data;
67
+ console.log('[ModelScope ASR] Streaming session started');
68
+ }
69
+ catch (error) {
70
+ console.error('[ModelScope ASR] Failed to start streaming:', error);
71
+ this.emit('error', error);
72
+ }
73
+ }
74
+ /**
75
+ * Send audio chunk for recognition
76
+ */
77
+ async sendAudioChunk(audioData) {
78
+ if (!this.isRecording || !this.apiKey) {
79
+ return;
80
+ }
81
+ this.audioBuffer.push(audioData);
82
+ // Accumulate some audio before sending (e.g., 100ms worth)
83
+ if (this.audioBuffer.length >= 3) {
84
+ const combinedBuffer = Buffer.concat(this.audioBuffer);
85
+ this.audioBuffer = [];
86
+ try {
87
+ // Convert audio to base64
88
+ const base64Audio = combinedBuffer.toString('base64');
89
+ // Send to ModelScope API
90
+ const response = await axios_1.default.post(`${this.apiUrl}audio/transcriptions`, {
91
+ model: this.model,
92
+ audio: base64Audio,
93
+ language: this.language,
94
+ context: this.contextText,
95
+ stream: true,
96
+ response_format: 'json'
97
+ }, {
98
+ headers: {
99
+ 'Authorization': `Bearer ${this.apiKey}`,
100
+ 'Content-Type': 'application/json'
101
+ },
102
+ responseType: 'stream'
103
+ });
104
+ // Handle streaming response
105
+ response.data.on('data', (chunk) => {
106
+ try {
107
+ const lines = chunk.toString().split('\n').filter(line => line.trim());
108
+ for (const line of lines) {
109
+ if (line.startsWith('data: ')) {
110
+ const data = line.slice(6);
111
+ if (data === '[DONE]') {
112
+ continue;
113
+ }
114
+ const parsed = JSON.parse(data);
115
+ if (parsed.text) {
116
+ const result = {
117
+ text: parsed.text,
118
+ isFinal: parsed.is_final || false,
119
+ timestamp: Date.now()
120
+ };
121
+ if (result.isFinal) {
122
+ this.emit('final', result.text);
123
+ }
124
+ else {
125
+ this.emit('partial', result.text);
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ catch (err) {
132
+ console.error('[ModelScope ASR] Error parsing stream data:', err);
133
+ }
134
+ });
135
+ }
136
+ catch (error) {
137
+ console.error('[ModelScope ASR] Failed to send audio chunk:', error);
138
+ this.emit('error', error);
139
+ }
140
+ }
141
+ }
142
+ /**
143
+ * Stop recognition
144
+ */
145
+ stopRecognition() {
146
+ this.isRecording = false;
147
+ this.audioBuffer = [];
148
+ this.streamingSession = null;
149
+ console.log('[ModelScope ASR] Recognition stopped');
150
+ }
151
+ /**
152
+ * Check if API is properly configured
153
+ */
154
+ isConfigured() {
155
+ return !!this.apiKey;
156
+ }
157
+ /**
158
+ * Get current context
159
+ */
160
+ getContext() {
161
+ return this.contextText;
162
+ }
163
+ /**
164
+ * Set maximum context length
165
+ */
166
+ setMaxContextLength(length) {
167
+ this.maxContextLength = Math.min(Math.max(100, length), 10000);
168
+ }
169
+ }
170
+ exports.VoiceRecognitionModelScope = VoiceRecognitionModelScope;
171
+ //# sourceMappingURL=voice-recognition-modelscope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-recognition-modelscope.js","sourceRoot":"","sources":["../src/voice-recognition-modelscope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface WebServerOptions {
2
+ debugAsr?: boolean;
3
+ }
4
+ export declare function startWebServer(port: number, pin?: string, options?: WebServerOptions): Promise<void>;
5
+ export declare function stopWebServer(): void;
6
+ //# sourceMappingURL=web-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../src/web-server.ts"],"names":[],"mappings":"AAgSA,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAiKD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8hDxG;AAED,wBAAgB,aAAa,IAAI,IAAI,CAepC"}