opencode-studio-server 1.28.0 → 1.28.1
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/index.js +174 -110
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -341,8 +341,9 @@ function loadStudioConfig() {
|
|
|
341
341
|
"variants": {
|
|
342
342
|
"low": { "options": { "thinkingConfig": { "thinkingLevel": "low", "includeThoughts": true } } },
|
|
343
343
|
"medium": { "options": { "thinkingConfig": { "thinkingLevel": "medium", "includeThoughts": true } } },
|
|
344
|
-
"high": { "options": { "thinkingConfig": { "thinkingLevel": "high", "includeThoughts": true } } }
|
|
345
|
-
|
|
344
|
+
"high": { "options": { "thinkingConfig": { "thinkingLevel": "high", "includeThoughts": true } } },
|
|
345
|
+
"xhigh": { "options": { "thinkingConfig": { "thinkingLevel": "xhigh", "includeThoughts": true } } }
|
|
346
|
+
}
|
|
346
347
|
},
|
|
347
348
|
"gemini-3-flash": {
|
|
348
349
|
"id": "gemini-3-flash",
|
|
@@ -359,8 +360,9 @@ function loadStudioConfig() {
|
|
|
359
360
|
"minimal": { "options": { "thinkingConfig": { "thinkingLevel": "minimal", "includeThoughts": true } } },
|
|
360
361
|
"low": { "options": { "thinkingConfig": { "thinkingLevel": "low", "includeThoughts": true } } },
|
|
361
362
|
"medium": { "options": { "thinkingConfig": { "thinkingLevel": "medium", "includeThoughts": true } } },
|
|
362
|
-
"high": { "options": { "thinkingConfig": { "thinkingLevel": "high", "includeThoughts": true } } }
|
|
363
|
-
|
|
363
|
+
"high": { "options": { "thinkingConfig": { "thinkingLevel": "high", "includeThoughts": true } } },
|
|
364
|
+
"xhigh": { "options": { "thinkingConfig": { "thinkingLevel": "xhigh", "includeThoughts": true } } }
|
|
365
|
+
}
|
|
364
366
|
},
|
|
365
367
|
"gemini-2.5-flash-lite": {
|
|
366
368
|
"id": "gemini-2.5-flash-lite",
|
|
@@ -381,8 +383,9 @@ function loadStudioConfig() {
|
|
|
381
383
|
"minimal": { "options": { "thinkingConfig": { "thinkingLevel": "minimal", "includeThoughts": true } } },
|
|
382
384
|
"low": { "options": { "thinkingConfig": { "thinkingLevel": "low", "includeThoughts": true } } },
|
|
383
385
|
"medium": { "options": { "thinkingConfig": { "thinkingLevel": "medium", "includeThoughts": true } } },
|
|
384
|
-
"high": { "options": { "thinkingConfig": { "thinkingLevel": "high", "includeThoughts": true } } }
|
|
385
|
-
|
|
386
|
+
"high": { "options": { "thinkingConfig": { "thinkingLevel": "high", "includeThoughts": true } } },
|
|
387
|
+
"xhigh": { "options": { "thinkingConfig": { "thinkingLevel": "xhigh", "includeThoughts": true } } }
|
|
388
|
+
}
|
|
386
389
|
},
|
|
387
390
|
"opencode/glm-4.7-free": {
|
|
388
391
|
"id": "opencode/glm-4.7-free",
|
|
@@ -408,8 +411,9 @@ function loadStudioConfig() {
|
|
|
408
411
|
"none": { "reasoning": false, "options": { "thinkingConfig": { "includeThoughts": false } } },
|
|
409
412
|
"low": { "options": { "thinkingConfig": { "thinkingBudget": 4000, "includeThoughts": true } } },
|
|
410
413
|
"medium": { "options": { "thinkingConfig": { "thinkingBudget": 16000, "includeThoughts": true } } },
|
|
411
|
-
"high": { "options": { "thinkingConfig": { "thinkingBudget": 32000, "includeThoughts": true } } }
|
|
412
|
-
|
|
414
|
+
"high": { "options": { "thinkingConfig": { "thinkingBudget": 32000, "includeThoughts": true } } },
|
|
415
|
+
"xhigh": { "options": { "thinkingConfig": { "thinkingBudget": 64000, "includeThoughts": true } } }
|
|
416
|
+
}
|
|
413
417
|
},
|
|
414
418
|
"gemini-claude-opus-4-5-thinking": {
|
|
415
419
|
"id": "gemini-claude-opus-4-5-thinking",
|
|
@@ -424,8 +428,9 @@ function loadStudioConfig() {
|
|
|
424
428
|
"variants": {
|
|
425
429
|
"low": { "options": { "thinkingConfig": { "thinkingBudget": 4000, "includeThoughts": true } } },
|
|
426
430
|
"medium": { "options": { "thinkingConfig": { "thinkingBudget": 16000, "includeThoughts": true } } },
|
|
427
|
-
"high": { "options": { "thinkingConfig": { "thinkingBudget": 32000, "includeThoughts": true } } }
|
|
428
|
-
|
|
431
|
+
"high": { "options": { "thinkingConfig": { "thinkingBudget": 32000, "includeThoughts": true } } },
|
|
432
|
+
"xhigh": { "options": { "thinkingConfig": { "thinkingBudget": 64000, "includeThoughts": true } } }
|
|
433
|
+
}
|
|
429
434
|
}
|
|
430
435
|
}
|
|
431
436
|
}
|
|
@@ -611,14 +616,15 @@ app.get('/api/config', (req, res) => {
|
|
|
611
616
|
res.json(config);
|
|
612
617
|
});
|
|
613
618
|
|
|
614
|
-
app.post('/api/config', (req, res) => {
|
|
615
|
-
try {
|
|
616
|
-
saveConfig(req.body);
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
619
|
+
app.post('/api/config', (req, res) => {
|
|
620
|
+
try {
|
|
621
|
+
saveConfig(req.body);
|
|
622
|
+
triggerGitHubAutoSync();
|
|
623
|
+
res.json({ success: true });
|
|
624
|
+
} catch (err) {
|
|
625
|
+
res.status(500).json({ error: err.message });
|
|
626
|
+
}
|
|
627
|
+
});
|
|
622
628
|
|
|
623
629
|
app.get('/api/backup', (req, res) => {
|
|
624
630
|
try {
|
|
@@ -1074,10 +1080,11 @@ app.post('/api/ohmyopencode', (req, res) => {
|
|
|
1074
1080
|
|
|
1075
1081
|
saveOhMyOpenCodeConfig(currentConfig);
|
|
1076
1082
|
|
|
1077
|
-
const ohMyPath = getOhMyOpenCodeConfigPath();
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1083
|
+
const ohMyPath = getOhMyOpenCodeConfigPath();
|
|
1084
|
+
triggerGitHubAutoSync();
|
|
1085
|
+
res.json({
|
|
1086
|
+
success: true,
|
|
1087
|
+
path: ohMyPath,
|
|
1081
1088
|
exists: true,
|
|
1082
1089
|
config: currentConfig,
|
|
1083
1090
|
preferences,
|
|
@@ -1181,6 +1188,107 @@ function execPromise(cmd, opts = {}) {
|
|
|
1181
1188
|
});
|
|
1182
1189
|
}
|
|
1183
1190
|
|
|
1191
|
+
|
|
1192
|
+
let autoSyncTimer = null;
|
|
1193
|
+
|
|
1194
|
+
async function performGitHubBackup(options = {}) {
|
|
1195
|
+
const { owner, repo, branch } = options;
|
|
1196
|
+
let tempDir = null;
|
|
1197
|
+
try {
|
|
1198
|
+
const token = await getGitHubToken();
|
|
1199
|
+
if (!token) throw new Error('Not logged in to gh CLI. Run: gh auth login');
|
|
1200
|
+
|
|
1201
|
+
const user = await getGitHubUser(token);
|
|
1202
|
+
if (!user) throw new Error('Failed to get GitHub user');
|
|
1203
|
+
|
|
1204
|
+
const studio = loadStudioConfig();
|
|
1205
|
+
|
|
1206
|
+
const finalOwner = owner || studio.githubBackup?.owner || user.login;
|
|
1207
|
+
const finalRepo = repo || studio.githubBackup?.repo;
|
|
1208
|
+
const finalBranch = branch || studio.githubBackup?.branch || 'main';
|
|
1209
|
+
|
|
1210
|
+
if (!finalRepo) throw new Error('No repo name provided');
|
|
1211
|
+
|
|
1212
|
+
const repoName = `${finalOwner}/${finalRepo}`;
|
|
1213
|
+
|
|
1214
|
+
await ensureGitHubRepo(token, repoName);
|
|
1215
|
+
|
|
1216
|
+
const opencodeConfig = getConfigPath();
|
|
1217
|
+
if (!opencodeConfig) throw new Error('No opencode config path found');
|
|
1218
|
+
|
|
1219
|
+
const opencodeDir = path.dirname(opencodeConfig);
|
|
1220
|
+
const studioDir = path.join(HOME_DIR, '.config', 'opencode-studio');
|
|
1221
|
+
|
|
1222
|
+
tempDir = path.join(os.tmpdir(), `opencode-backup-${Date.now()}`);
|
|
1223
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
1224
|
+
|
|
1225
|
+
// Clone or init
|
|
1226
|
+
try {
|
|
1227
|
+
await execPromise(`git clone --depth 1 https://x-access-token:${token}@github.com/${repoName}.git .`, { cwd: tempDir });
|
|
1228
|
+
} catch (e) {
|
|
1229
|
+
// If clone fails (empty repo?), try init
|
|
1230
|
+
await execPromise('git init', { cwd: tempDir });
|
|
1231
|
+
await execPromise(`git remote add origin https://x-access-token:${token}@github.com/${repoName}.git`, { cwd: tempDir });
|
|
1232
|
+
await execPromise(`git checkout -b ${finalBranch}`, { cwd: tempDir });
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
const backupOpencodeDir = path.join(tempDir, 'opencode');
|
|
1236
|
+
const backupStudioDir = path.join(tempDir, 'opencode-studio');
|
|
1237
|
+
|
|
1238
|
+
if (fs.existsSync(backupOpencodeDir)) fs.rmSync(backupOpencodeDir, { recursive: true });
|
|
1239
|
+
if (fs.existsSync(backupStudioDir)) fs.rmSync(backupStudioDir, { recursive: true });
|
|
1240
|
+
|
|
1241
|
+
copyDirContents(opencodeDir, backupOpencodeDir);
|
|
1242
|
+
copyDirContents(studioDir, backupStudioDir);
|
|
1243
|
+
|
|
1244
|
+
await execPromise('git add -A', { cwd: tempDir });
|
|
1245
|
+
|
|
1246
|
+
const timestamp = new Date().toISOString();
|
|
1247
|
+
const commitMessage = `OpenCode Studio backup ${timestamp}`;
|
|
1248
|
+
|
|
1249
|
+
let result = { success: true, timestamp, url: `https://github.com/${repoName}` };
|
|
1250
|
+
|
|
1251
|
+
try {
|
|
1252
|
+
await execPromise(`git commit -m "${commitMessage}"`, { cwd: tempDir });
|
|
1253
|
+
await execPromise(`git push origin ${finalBranch}`, { cwd: tempDir });
|
|
1254
|
+
} catch (e) {
|
|
1255
|
+
if (e.message.includes('nothing to commit')) {
|
|
1256
|
+
result.message = 'No changes to backup';
|
|
1257
|
+
} else {
|
|
1258
|
+
throw e;
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
studio.githubBackup = { owner: finalOwner, repo: finalRepo, branch: finalBranch };
|
|
1263
|
+
studio.lastGithubBackup = timestamp;
|
|
1264
|
+
saveStudioConfig(studio);
|
|
1265
|
+
|
|
1266
|
+
return result;
|
|
1267
|
+
} finally {
|
|
1268
|
+
if (tempDir && fs.existsSync(tempDir)) {
|
|
1269
|
+
try { fs.rmSync(tempDir, { recursive: true }); } catch (e) {}
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
function triggerGitHubAutoSync() {
|
|
1275
|
+
const studio = loadStudioConfig();
|
|
1276
|
+
if (!studio.githubAutoSync) return;
|
|
1277
|
+
|
|
1278
|
+
if (autoSyncTimer) clearTimeout(autoSyncTimer);
|
|
1279
|
+
|
|
1280
|
+
console.log('[AutoSync] Change detected, scheduling GitHub backup in 15s...');
|
|
1281
|
+
autoSyncTimer = setTimeout(async () => {
|
|
1282
|
+
console.log('[AutoSync] Starting GitHub backup...');
|
|
1283
|
+
try {
|
|
1284
|
+
const result = await performGitHubBackup();
|
|
1285
|
+
console.log(`[AutoSync] Backup completed: ${result.message || 'Pushed to GitHub'}`);
|
|
1286
|
+
} catch (err) {
|
|
1287
|
+
console.error('[AutoSync] Backup failed:', err.message);
|
|
1288
|
+
}
|
|
1289
|
+
}, 15000); // 15s debounce
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1184
1292
|
app.get('/api/github/backup/status', async (req, res) => {
|
|
1185
1293
|
try {
|
|
1186
1294
|
const token = await getGitHubToken();
|
|
@@ -1212,77 +1320,15 @@ app.get('/api/github/backup/status', async (req, res) => {
|
|
|
1212
1320
|
}
|
|
1213
1321
|
});
|
|
1214
1322
|
|
|
1215
|
-
app.post('/api/github/backup', async (req, res) => {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
const { owner, repo, branch } = req.body;
|
|
1225
|
-
const studio = loadStudioConfig();
|
|
1226
|
-
|
|
1227
|
-
const finalOwner = owner || studio.githubBackup?.owner || user.login;
|
|
1228
|
-
const finalRepo = repo || studio.githubBackup?.repo;
|
|
1229
|
-
const finalBranch = branch || studio.githubBackup?.branch || 'main';
|
|
1230
|
-
|
|
1231
|
-
if (!finalRepo) return res.status(400).json({ error: 'No repo name provided' });
|
|
1232
|
-
|
|
1233
|
-
const repoName = `${finalOwner}/${finalRepo}`;
|
|
1234
|
-
|
|
1235
|
-
await ensureGitHubRepo(token, repoName);
|
|
1236
|
-
|
|
1237
|
-
const opencodeConfig = getConfigPath();
|
|
1238
|
-
if (!opencodeConfig) return res.status(400).json({ error: 'No opencode config path found' });
|
|
1239
|
-
|
|
1240
|
-
const opencodeDir = path.dirname(opencodeConfig);
|
|
1241
|
-
const studioDir = path.join(HOME_DIR, '.config', 'opencode-studio');
|
|
1242
|
-
|
|
1243
|
-
tempDir = path.join(os.tmpdir(), `opencode-backup-${Date.now()}`);
|
|
1244
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
1245
|
-
|
|
1246
|
-
await execPromise(`git clone --depth 1 https://x-access-token:${token}@github.com/${repoName}.git .`, { cwd: tempDir });
|
|
1247
|
-
|
|
1248
|
-
const backupOpencodeDir = path.join(tempDir, 'opencode');
|
|
1249
|
-
const backupStudioDir = path.join(tempDir, 'opencode-studio');
|
|
1250
|
-
|
|
1251
|
-
if (fs.existsSync(backupOpencodeDir)) fs.rmSync(backupOpencodeDir, { recursive: true });
|
|
1252
|
-
if (fs.existsSync(backupStudioDir)) fs.rmSync(backupStudioDir, { recursive: true });
|
|
1253
|
-
|
|
1254
|
-
copyDirContents(opencodeDir, backupOpencodeDir);
|
|
1255
|
-
copyDirContents(studioDir, backupStudioDir);
|
|
1256
|
-
|
|
1257
|
-
await execPromise('git add -A', { cwd: tempDir });
|
|
1258
|
-
|
|
1259
|
-
const timestamp = new Date().toISOString();
|
|
1260
|
-
const commitMessage = `OpenCode Studio backup ${timestamp}`;
|
|
1261
|
-
|
|
1262
|
-
try {
|
|
1263
|
-
await execPromise(`git commit -m "${commitMessage}"`, { cwd: tempDir });
|
|
1264
|
-
await execPromise(`git push origin ${finalBranch}`, { cwd: tempDir });
|
|
1265
|
-
} catch (e) {
|
|
1266
|
-
if (e.message.includes('nothing to commit')) {
|
|
1267
|
-
fs.rmSync(tempDir, { recursive: true });
|
|
1268
|
-
return res.json({ success: true, timestamp, message: 'No changes to backup', url: `https://github.com/${repoName}` });
|
|
1269
|
-
}
|
|
1270
|
-
throw e;
|
|
1271
|
-
}
|
|
1272
|
-
|
|
1273
|
-
fs.rmSync(tempDir, { recursive: true });
|
|
1274
|
-
|
|
1275
|
-
studio.githubBackup = { owner: finalOwner, repo: finalRepo, branch: finalBranch };
|
|
1276
|
-
studio.lastGithubBackup = timestamp;
|
|
1277
|
-
saveStudioConfig(studio);
|
|
1278
|
-
|
|
1279
|
-
res.json({ success: true, timestamp, url: `https://github.com/${repoName}` });
|
|
1280
|
-
} catch (err) {
|
|
1281
|
-
if (tempDir && fs.existsSync(tempDir)) fs.rmSync(tempDir, { recursive: true });
|
|
1282
|
-
console.error('GitHub backup error:', err);
|
|
1283
|
-
res.status(500).json({ error: err.message });
|
|
1284
|
-
}
|
|
1285
|
-
});
|
|
1323
|
+
app.post('/api/github/backup', async (req, res) => {
|
|
1324
|
+
try {
|
|
1325
|
+
const result = await performGitHubBackup(req.body);
|
|
1326
|
+
res.json(result);
|
|
1327
|
+
} catch (err) {
|
|
1328
|
+
console.error('GitHub backup error:', err);
|
|
1329
|
+
res.status(500).json({ error: err.message });
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1286
1332
|
|
|
1287
1333
|
app.post('/api/github/restore', async (req, res) => {
|
|
1288
1334
|
let tempDir = null;
|
|
@@ -1341,9 +1387,10 @@ app.post('/api/github/restore', async (req, res) => {
|
|
|
1341
1387
|
app.post('/api/github/autosync', async (req, res) => {
|
|
1342
1388
|
const studio = loadStudioConfig();
|
|
1343
1389
|
const enabled = req.body.enabled;
|
|
1344
|
-
studio.githubAutoSync = enabled;
|
|
1345
|
-
saveStudioConfig(studio);
|
|
1346
|
-
|
|
1390
|
+
studio.githubAutoSync = enabled;
|
|
1391
|
+
saveStudioConfig(studio);
|
|
1392
|
+
if (enabled) triggerGitHubAutoSync();
|
|
1393
|
+
res.json({ success: true, enabled });
|
|
1347
1394
|
});
|
|
1348
1395
|
|
|
1349
1396
|
const getSkillDir = () => {
|
|
@@ -1380,8 +1427,9 @@ app.post('/api/skills/:name', (req, res) => {
|
|
|
1380
1427
|
if (!sd) return res.status(404).json({ error: 'No config' });
|
|
1381
1428
|
const dp = path.join(sd, req.params.name);
|
|
1382
1429
|
if (!fs.existsSync(dp)) fs.mkdirSync(dp, { recursive: true });
|
|
1383
|
-
fs.writeFileSync(path.join(dp, 'SKILL.md'), req.body.content, 'utf8');
|
|
1384
|
-
|
|
1430
|
+
fs.writeFileSync(path.join(dp, 'SKILL.md'), req.body.content, 'utf8');
|
|
1431
|
+
triggerGitHubAutoSync();
|
|
1432
|
+
res.json({ success: true });
|
|
1385
1433
|
});
|
|
1386
1434
|
|
|
1387
1435
|
app.delete('/api/skills/:name', (req, res) => {
|
|
@@ -1390,8 +1438,9 @@ app.delete('/api/skills/:name', (req, res) => {
|
|
|
1390
1438
|
}
|
|
1391
1439
|
const sd = getSkillDir();
|
|
1392
1440
|
const dp = sd ? path.join(sd, req.params.name) : null;
|
|
1393
|
-
if (dp && fs.existsSync(dp)) fs.rmSync(dp, { recursive: true, force: true });
|
|
1394
|
-
|
|
1441
|
+
if (dp && fs.existsSync(dp)) fs.rmSync(dp, { recursive: true, force: true });
|
|
1442
|
+
triggerGitHubAutoSync();
|
|
1443
|
+
res.json({ success: true });
|
|
1395
1444
|
});
|
|
1396
1445
|
|
|
1397
1446
|
app.post('/api/skills/:name/toggle', (req, res) => {
|
|
@@ -1405,8 +1454,9 @@ app.post('/api/skills/:name/toggle', (req, res) => {
|
|
|
1405
1454
|
studio.disabledSkills.push(name);
|
|
1406
1455
|
}
|
|
1407
1456
|
|
|
1408
|
-
saveStudioConfig(studio);
|
|
1409
|
-
|
|
1457
|
+
saveStudioConfig(studio);
|
|
1458
|
+
triggerGitHubAutoSync();
|
|
1459
|
+
res.json({ success: true, enabled: !studio.disabledSkills.includes(name) });
|
|
1410
1460
|
});
|
|
1411
1461
|
|
|
1412
1462
|
const getPluginDir = () => {
|
|
@@ -1483,9 +1533,10 @@ app.post('/api/plugins/:name', (req, res) => {
|
|
|
1483
1533
|
if (!fs.existsSync(pd)) fs.mkdirSync(pd, { recursive: true });
|
|
1484
1534
|
|
|
1485
1535
|
// Default to .js if new
|
|
1486
|
-
const filePath = path.join(pd, name.endsWith('.js') || name.endsWith('.ts') ? name : name + '.js');
|
|
1487
|
-
atomicWriteFileSync(filePath, content);
|
|
1488
|
-
|
|
1536
|
+
const filePath = path.join(pd, name.endsWith('.js') || name.endsWith('.ts') ? name : name + '.js');
|
|
1537
|
+
atomicWriteFileSync(filePath, content);
|
|
1538
|
+
triggerGitHubAutoSync();
|
|
1539
|
+
res.json({ success: true });
|
|
1489
1540
|
});
|
|
1490
1541
|
|
|
1491
1542
|
app.delete('/api/plugins/:name', (req, res) => {
|
|
@@ -1510,8 +1561,10 @@ app.delete('/api/plugins/:name', (req, res) => {
|
|
|
1510
1561
|
}
|
|
1511
1562
|
}
|
|
1512
1563
|
|
|
1513
|
-
if (deleted)
|
|
1514
|
-
|
|
1564
|
+
if (deleted) {
|
|
1565
|
+
triggerGitHubAutoSync();
|
|
1566
|
+
res.json({ success: true });
|
|
1567
|
+
} else res.status(404).json({ error: 'Plugin not found' });
|
|
1515
1568
|
});
|
|
1516
1569
|
|
|
1517
1570
|
app.post('/api/plugins/:name/toggle', (req, res) => {
|
|
@@ -1525,8 +1578,9 @@ app.post('/api/plugins/:name/toggle', (req, res) => {
|
|
|
1525
1578
|
studio.disabledPlugins.push(name);
|
|
1526
1579
|
}
|
|
1527
1580
|
|
|
1528
|
-
saveStudioConfig(studio);
|
|
1529
|
-
|
|
1581
|
+
saveStudioConfig(studio);
|
|
1582
|
+
triggerGitHubAutoSync();
|
|
1583
|
+
res.json({ success: true, enabled: !studio.disabledPlugins.includes(name) });
|
|
1530
1584
|
});
|
|
1531
1585
|
|
|
1532
1586
|
const getActiveGooglePlugin = () => {
|
|
@@ -3423,7 +3477,17 @@ app.post('/api/presets/:id/apply', (req, res) => {
|
|
|
3423
3477
|
// Start watcher on server start
|
|
3424
3478
|
function startServer() {
|
|
3425
3479
|
['google', 'anthropic', 'openai', 'xai', 'openrouter', 'together', 'mistral', 'deepseek', 'amazon-bedrock', 'azure', 'github-copilot'].forEach(p => importCurrentAuthToPool(p));
|
|
3426
|
-
app.listen(PORT, () =>
|
|
3480
|
+
app.listen(PORT, () => {
|
|
3481
|
+
console.log(`Server running at http://localhost:${PORT}`);
|
|
3482
|
+
// Initial sync on startup if enabled
|
|
3483
|
+
setTimeout(() => {
|
|
3484
|
+
const studio = loadStudioConfig();
|
|
3485
|
+
if (studio.githubAutoSync) {
|
|
3486
|
+
console.log('[AutoSync] Triggering initial sync...');
|
|
3487
|
+
triggerGitHubAutoSync();
|
|
3488
|
+
}
|
|
3489
|
+
}, 5000);
|
|
3490
|
+
});
|
|
3427
3491
|
}
|
|
3428
3492
|
|
|
3429
3493
|
if (require.main === module) {
|