opencode-studio-server 1.28.2 → 2.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 (3) hide show
  1. package/cli.js +39 -19
  2. package/index.js +37 -19
  3. package/package.json +4 -4
package/cli.js CHANGED
@@ -4,9 +4,27 @@ const path = require('path');
4
4
  const { exec } = require('child_process');
5
5
  const os = require('os');
6
6
  const fs = require('fs');
7
+ const net = require('net');
7
8
 
8
9
  const args = process.argv.slice(2);
9
10
 
11
+ async function findAvailablePort(startPort, maxTries = 10) {
12
+ return new Promise((resolve) => {
13
+ const server = net.createServer();
14
+ server.listen(startPort, () => {
15
+ server.once('close', () => resolve(startPort));
16
+ server.close();
17
+ });
18
+ server.on('error', () => {
19
+ if (maxTries > 1) {
20
+ findAvailablePort(startPort + 1, maxTries - 1).then(resolve);
21
+ } else {
22
+ resolve(startPort);
23
+ }
24
+ });
25
+ });
26
+ }
27
+
10
28
  // Handle --register flag
11
29
  if (args.includes('--register')) {
12
30
  require('./register-protocol');
@@ -103,27 +121,29 @@ if (pendingAction) {
103
121
 
104
122
  // Open browser if requested (only for fully local mode)
105
123
  if (shouldOpenBrowser) {
106
- const openUrl = 'http://localhost:3000';
107
- const platform = os.platform();
108
-
109
- setTimeout(() => {
110
- let cmd;
111
- if (platform === 'win32') {
112
- cmd = `start "" "${openUrl}"`;
113
- } else if (platform === 'darwin') {
114
- cmd = `open "${openUrl}"`;
115
- } else {
116
- cmd = `xdg-open "${openUrl}"`;
117
- }
118
-
119
- exec(cmd, (err) => {
120
- if (err) {
121
- console.log(`Open ${openUrl} in your browser`);
124
+ findAvailablePort(1080).then(port => {
125
+ const openUrl = `http://localhost:${port}`;
126
+ const platform = os.platform();
127
+
128
+ setTimeout(() => {
129
+ let cmd;
130
+ if (platform === 'win32') {
131
+ cmd = `start "" "${openUrl}"`;
132
+ } else if (platform === 'darwin') {
133
+ cmd = `open "${openUrl}"`;
122
134
  } else {
123
- console.log(`Opened ${openUrl}`);
135
+ cmd = `xdg-open "${openUrl}"`;
124
136
  }
125
- });
126
- }, 1500); // Give server time to start
137
+
138
+ exec(cmd, (err) => {
139
+ if (err) {
140
+ console.log(`Open ${openUrl} in your browser`);
141
+ } else {
142
+ console.log(`Opened ${openUrl}`);
143
+ }
144
+ });
145
+ }, 2000);
146
+ });
127
147
  }
128
148
 
129
149
  // Start the server
package/index.js CHANGED
@@ -40,9 +40,23 @@ const atomicWriteFileSync = (filePath, data, options = 'utf8') => {
40
40
  }
41
41
  };
42
42
 
43
- const app = express();
44
- const PORT = 3001;
45
- const IDLE_TIMEOUT_MS = 30 * 60 * 1000;
43
+ const app = express();
44
+ const DEFAULT_PORT = 1920;
45
+ const IDLE_TIMEOUT_MS = 30 * 60 * 1000;
46
+
47
+ function findAvailablePort(startPort) {
48
+ const net = require('net');
49
+ return new Promise((resolve) => {
50
+ const server = net.createServer();
51
+ server.listen(startPort, () => {
52
+ server.once('close', () => resolve(startPort));
53
+ server.close();
54
+ });
55
+ server.on('error', () => {
56
+ findAvailablePort(startPort + 1).then(resolve);
57
+ });
58
+ });
59
+ }
46
60
 
47
61
  let idleTimer = null;
48
62
 
@@ -61,15 +75,17 @@ app.use((req, res, next) => {
61
75
  next();
62
76
  });
63
77
 
64
- const ALLOWED_ORIGINS = [
65
- 'http://localhost:3000',
66
- 'http://127.0.0.1:3000',
67
- 'https://opencode-studio.vercel.app',
68
- 'https://opencode.micr.dev',
69
- 'https://opencode-studio.micr.dev',
70
- /\.vercel\.app$/,
71
- /\.micr\.dev$/,
72
- ];
78
+ const ALLOWED_ORIGINS = [
79
+ 'http://localhost:1080',
80
+ 'http://127.0.0.1:1080',
81
+ /^http:\/\/localhost:108\d$/,
82
+ /^http:\/\/127\.0\.0\.1:108\d$/,
83
+ 'https://opencode-studio.vercel.app',
84
+ 'https://opencode.micr.dev',
85
+ 'https://opencode-studio.micr.dev',
86
+ /\.vercel\.app$/,
87
+ /\.micr\.dev$/,
88
+ ];
73
89
 
74
90
  app.use(cors({
75
91
  origin: (origin, callback) => {
@@ -3488,11 +3504,13 @@ app.post('/api/presets/:id/apply', (req, res) => {
3488
3504
  res.json({ success: true });
3489
3505
  });
3490
3506
 
3491
- // Start watcher on server start
3492
- function startServer() {
3493
- ['google', 'anthropic', 'openai', 'xai', 'openrouter', 'together', 'mistral', 'deepseek', 'amazon-bedrock', 'azure', 'github-copilot'].forEach(p => importCurrentAuthToPool(p));
3494
- app.listen(PORT, () => {
3495
- console.log(`Server running at http://localhost:${PORT}`);
3507
+ // Start watcher on server start
3508
+ async function startServer() {
3509
+ ['google', 'anthropic', 'openai', 'xai', 'openrouter', 'together', 'mistral', 'deepseek', 'amazon-bedrock', 'azure', 'github-copilot'].forEach(p => importCurrentAuthToPool(p));
3510
+
3511
+ const port = await findAvailablePort(DEFAULT_PORT);
3512
+ app.listen(port, () => {
3513
+ console.log(`Server running at http://localhost:${port}`);
3496
3514
  // Initial sync on startup if enabled
3497
3515
  setTimeout(() => {
3498
3516
  const studio = loadStudioConfig();
@@ -3501,8 +3519,8 @@ function startServer() {
3501
3519
  triggerGitHubAutoSync();
3502
3520
  }
3503
3521
  }, 5000);
3504
- });
3505
- }
3522
+ });
3523
+ }
3506
3524
 
3507
3525
  if (require.main === module) {
3508
3526
  startServer();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
- {
2
- "name": "opencode-studio-server",
3
- "version": "1.28.2",
4
- "description": "Backend server for OpenCode Studio - manages opencode configurations",
1
+ {
2
+ "name": "opencode-studio-server",
3
+ "version": "2.0.0",
4
+ "description": "Backend server for OpenCode Studio - manages opencode configurations",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "opencode-studio-server": "cli.js"