opencode-studio-server 1.26.0 → 1.27.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 (2) hide show
  1. package/index.js +73 -11
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1175,22 +1175,22 @@ app.get('/api/github/backup/status', async (req, res) => {
1175
1175
  const user = await getGitHubUser(token);
1176
1176
  if (!user) return res.json({ connected: false, config: backupConfig, error: 'Failed to get GitHub user' });
1177
1177
 
1178
- if (!backupConfig.repo) {
1179
- return res.json({ connected: true, user: user.login, config: backupConfig });
1180
- }
1178
+ if (!backupConfig.repo) {
1179
+ return res.json({ connected: true, user: user.login, config: backupConfig, autoSync: studio.githubAutoSync || false });
1180
+ }
1181
1181
 
1182
1182
  const owner = backupConfig.owner || user.login;
1183
1183
  const response = await fetch(`https://api.github.com/repos/${owner}/${backupConfig.repo}`, {
1184
1184
  headers: { 'Authorization': `Bearer ${token}` }
1185
1185
  });
1186
1186
 
1187
- if (!response.ok) {
1188
- return res.json({ connected: true, user: user.login, config: backupConfig, repoExists: false });
1189
- }
1187
+ if (!response.ok) {
1188
+ return res.json({ connected: true, user: user.login, config: backupConfig, repoExists: false, autoSync: studio.githubAutoSync || false });
1189
+ }
1190
1190
 
1191
- const data = await response.json();
1192
- res.json({ connected: true, user: user.login, config: backupConfig, repoExists: true, lastUpdated: data.pushed_at });
1193
- } catch (err) {
1191
+ const data = await response.json();
1192
+ res.json({ connected: true, user: user.login, config: backupConfig, repoExists: true, lastUpdated: data.pushed_at, autoSync: studio.githubAutoSync || false });
1193
+ } catch (err) {
1194
1194
  res.json({ connected: false, error: err.message });
1195
1195
  }
1196
1196
  });
@@ -1266,8 +1266,70 @@ app.post('/api/github/backup', async (req, res) => {
1266
1266
  res.status(500).json({ error: err.message });
1267
1267
  }
1268
1268
  });
1269
-
1270
- const getSkillDir = () => {
1269
+
1270
+ app.post('/api/github/restore', async (req, res) => {
1271
+ let tempDir = null;
1272
+ try {
1273
+ const token = await getGitHubToken();
1274
+ if (!token) return res.status(400).json({ error: 'Not logged in to gh CLI. Run: gh auth login' });
1275
+
1276
+ const user = await getGitHubUser(token);
1277
+ if (!user) return res.status(400).json({ error: 'Failed to get GitHub user' });
1278
+
1279
+ const { owner, repo, branch } = req.body;
1280
+ const studio = loadStudioConfig();
1281
+
1282
+ const finalOwner = owner || studio.githubBackup?.owner || user.login;
1283
+ const finalRepo = repo || studio.githubBackup?.repo;
1284
+ const finalBranch = branch || studio.githubBackup?.branch || 'main';
1285
+
1286
+ if (!finalRepo) return res.status(400).json({ error: 'No repo configured' });
1287
+
1288
+ const repoName = `${finalOwner}/${finalRepo}`;
1289
+
1290
+ const opencodeConfig = getConfigPath();
1291
+ if (!opencodeConfig) return res.status(400).json({ error: 'No opencode config path found' });
1292
+
1293
+ const opencodeDir = path.dirname(opencodeConfig);
1294
+ const studioDir = path.join(HOME_DIR, '.config', 'opencode-studio');
1295
+
1296
+ tempDir = path.join(os.tmpdir(), `opencode-restore-${Date.now()}`);
1297
+ fs.mkdirSync(tempDir, { recursive: true });
1298
+
1299
+ await execPromise(`git clone --depth 1 -b ${finalBranch} https://x-access-token:${token}@github.com/${repoName}.git .`, { cwd: tempDir });
1300
+
1301
+ const backupOpencodeDir = path.join(tempDir, 'opencode');
1302
+ const backupStudioDir = path.join(tempDir, 'opencode-studio');
1303
+
1304
+ if (!fs.existsSync(backupOpencodeDir)) {
1305
+ fs.rmSync(tempDir, { recursive: true });
1306
+ return res.status(400).json({ error: 'No opencode backup found in repository' });
1307
+ }
1308
+
1309
+ copyDirContents(backupOpencodeDir, opencodeDir);
1310
+ if (fs.existsSync(backupStudioDir)) {
1311
+ copyDirContents(backupStudioDir, studioDir);
1312
+ }
1313
+
1314
+ fs.rmSync(tempDir, { recursive: true });
1315
+
1316
+ res.json({ success: true, message: 'Config restored from GitHub' });
1317
+ } catch (err) {
1318
+ if (tempDir && fs.existsSync(tempDir)) fs.rmSync(tempDir, { recursive: true });
1319
+ console.error('GitHub restore error:', err);
1320
+ res.status(500).json({ error: err.message });
1321
+ }
1322
+ });
1323
+
1324
+ app.post('/api/github/autosync', async (req, res) => {
1325
+ const studio = loadStudioConfig();
1326
+ const enabled = req.body.enabled;
1327
+ studio.githubAutoSync = enabled;
1328
+ saveStudioConfig(studio);
1329
+ res.json({ success: true, enabled });
1330
+ });
1331
+
1332
+ const getSkillDir = () => {
1271
1333
  const cp = getConfigPath();
1272
1334
  return cp ? path.join(path.dirname(cp), 'skill') : null;
1273
1335
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-studio-server",
3
- "version": "1.26.0",
3
+ "version": "1.27.0",
4
4
  "description": "Backend server for OpenCode Studio - manages opencode configurations",
5
5
  "main": "index.js",
6
6
  "bin": {