opencode-studio-server 1.0.7 → 1.0.10

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 +76 -78
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -56,9 +56,34 @@ const HOME_DIR = os.homedir();
56
56
  const STUDIO_CONFIG_PATH = path.join(HOME_DIR, '.config', 'opencode-studio', 'studio.json');
57
57
  const PENDING_ACTION_PATH = path.join(HOME_DIR, '.config', 'opencode-studio', 'pending-action.json');
58
58
 
59
- let pendingActionMemory = null;
60
-
61
- function loadPendingAction() {
59
+ let pendingActionMemory = null;
60
+
61
+ function loadStudioConfig() {
62
+ if (!fs.existsSync(STUDIO_CONFIG_PATH)) {
63
+ return {};
64
+ }
65
+ try {
66
+ return JSON.parse(fs.readFileSync(STUDIO_CONFIG_PATH, 'utf8'));
67
+ } catch {
68
+ return {};
69
+ }
70
+ }
71
+
72
+ function saveStudioConfig(config) {
73
+ try {
74
+ const dir = path.dirname(STUDIO_CONFIG_PATH);
75
+ if (!fs.existsSync(dir)) {
76
+ fs.mkdirSync(dir, { recursive: true });
77
+ }
78
+ fs.writeFileSync(STUDIO_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
79
+ return true;
80
+ } catch (err) {
81
+ console.error('Failed to save studio config:', err);
82
+ return false;
83
+ }
84
+ }
85
+
86
+ function loadPendingAction() {
62
87
  if (pendingActionMemory) return pendingActionMemory;
63
88
 
64
89
  if (fs.existsSync(PENDING_ACTION_PATH)) {
@@ -94,53 +119,38 @@ const AUTH_CANDIDATE_PATHS = [
94
119
  path.join(process.env.APPDATA || '', 'opencode', 'auth.json'),
95
120
  ];
96
121
 
97
- const CANDIDATE_PATHS = [
98
- path.join(HOME_DIR, '.config', 'opencode'),
99
- path.join(HOME_DIR, '.opencode'),
100
- path.join(process.env.APPDATA || '', 'opencode'),
101
- path.join(process.env.LOCALAPPDATA || '', 'opencode'),
102
- path.join(HOME_DIR, 'AppData', 'Roaming', 'opencode'),
103
- path.join(HOME_DIR, 'AppData', 'Local', 'opencode'),
104
- ];
105
-
106
- function detectConfigDir() {
107
- for (const candidate of CANDIDATE_PATHS) {
108
- const configFile = path.join(candidate, 'opencode.json');
109
- if (fs.existsSync(configFile)) {
110
- return candidate;
111
- }
112
- }
113
- return null;
114
- }
115
-
116
- function loadStudioConfig() {
117
- if (fs.existsSync(STUDIO_CONFIG_PATH)) {
118
- try {
119
- return JSON.parse(fs.readFileSync(STUDIO_CONFIG_PATH, 'utf8'));
120
- } catch {
121
- return { disabledSkills: [], disabledPlugins: [] };
122
- }
123
- }
124
- return { disabledSkills: [], disabledPlugins: [] };
125
- }
126
-
127
- function saveStudioConfig(config) {
128
- const dir = path.dirname(STUDIO_CONFIG_PATH);
129
- if (!fs.existsSync(dir)) {
130
- fs.mkdirSync(dir, { recursive: true });
131
- }
132
- fs.writeFileSync(STUDIO_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
133
- }
134
-
135
- function getConfigDir() {
136
- const studioConfig = loadStudioConfig();
137
- if (studioConfig.configPath && fs.existsSync(studioConfig.configPath)) {
138
- return studioConfig.configPath;
139
- }
140
- return detectConfigDir();
141
- }
142
-
143
- function getPaths() {
122
+ const CANDIDATE_PATHS = [
123
+ path.join(HOME_DIR, '.config', 'opencode'),
124
+ path.join(HOME_DIR, '.opencode'),
125
+ path.join(process.env.APPDATA || '', 'opencode'),
126
+ path.join(process.env.LOCALAPPDATA || '', 'opencode'),
127
+ ];
128
+
129
+ function getConfigDir() {
130
+ for (const candidate of CANDIDATE_PATHS) {
131
+ if (fs.existsSync(candidate)) {
132
+ return candidate;
133
+ }
134
+ }
135
+ return null;
136
+ }
137
+
138
+ const PROVIDER_DISPLAY_NAMES = {
139
+ 'github-copilot': 'GitHub Copilot',
140
+ 'google': 'Google AI',
141
+ 'anthropic': 'Anthropic',
142
+ 'openai': 'OpenAI',
143
+ 'xai': 'xAI',
144
+ 'groq': 'Groq',
145
+ 'together': 'Together AI',
146
+ 'mistral': 'Mistral',
147
+ 'deepseek': 'DeepSeek',
148
+ 'openrouter': 'OpenRouter',
149
+ 'amazon-bedrock': 'Amazon Bedrock',
150
+ 'azure': 'Azure OpenAI',
151
+ };
152
+
153
+ function getPaths() {
144
154
  const configDir = getConfigDir();
145
155
  if (!configDir) return null;
146
156
  return {
@@ -761,14 +771,17 @@ app.post('/api/restore', (req, res) => {
761
771
  });
762
772
 
763
773
  // Auth endpoints
764
- function getAuthFile() {
765
- for (const candidate of AUTH_CANDIDATE_PATHS) {
766
- if (fs.existsSync(candidate)) {
767
- return candidate;
768
- }
769
- }
770
- return null;
771
- }
774
+ function getAuthFile() {
775
+ console.log('Searching for auth file in:', AUTH_CANDIDATE_PATHS);
776
+ for (const candidate of AUTH_CANDIDATE_PATHS) {
777
+ if (fs.existsSync(candidate)) {
778
+ console.log('Found auth file at:', candidate);
779
+ return candidate;
780
+ }
781
+ }
782
+ console.log('No auth file found');
783
+ return null;
784
+ }
772
785
 
773
786
  function loadAuthConfig() {
774
787
  const authFile = getAuthFile();
@@ -793,22 +806,7 @@ function saveAuthConfig(config) {
793
806
  }
794
807
  }
795
808
 
796
- const PROVIDER_DISPLAY_NAMES = {
797
- 'github-copilot': 'GitHub Copilot',
798
- 'google': 'Google',
799
- 'google-gemini-oauth': 'Google Gemini (OAuth)',
800
- 'anthropic': 'Anthropic',
801
- 'openai': 'OpenAI',
802
- 'zai': 'Z.AI',
803
- 'xai': 'xAI',
804
- 'groq': 'Groq',
805
- 'together': 'Together AI',
806
- 'mistral': 'Mistral',
807
- 'deepseek': 'DeepSeek',
808
- 'openrouter': 'OpenRouter',
809
- 'amazon-bedrock': 'Amazon Bedrock',
810
- 'azure': 'Azure OpenAI',
811
- };
809
+
812
810
 
813
811
  app.get('/api/auth', (req, res) => {
814
812
  const authConfig = loadAuthConfig();
@@ -852,7 +850,6 @@ app.get('/api/auth', (req, res) => {
852
850
 
853
851
  app.post('/api/auth/login', (req, res) => {
854
852
  // opencode auth login is interactive and requires a terminal
855
- // Open a new terminal window with the command
856
853
  const isWindows = process.platform === 'win32';
857
854
  const isMac = process.platform === 'darwin';
858
855
 
@@ -865,7 +862,7 @@ app.post('/api/auth/login', (req, res) => {
865
862
  command = 'x-terminal-emulator -e "opencode auth login" || gnome-terminal -- opencode auth login || xterm -e "opencode auth login"';
866
863
  }
867
864
 
868
- exec(command, (err) => {
865
+ exec(command, { shell: true }, (err) => {
869
866
  if (err) console.error('Failed to open terminal:', err);
870
867
  });
871
868
 
@@ -992,6 +989,7 @@ function setActiveProfile(provider, profileName) {
992
989
  saveStudioConfig(studioConfig);
993
990
  }
994
991
 
992
+ function verifyActiveProfile(p, n, c) { if (!n || !c) return false; const d = loadAuthProfile(p, n); if (!d) return false; return JSON.stringify(d) === JSON.stringify(c); }
995
993
  app.get('/api/auth/profiles', (req, res) => {
996
994
  ensureAuthProfilesDir();
997
995
  const activeProfiles = getActiveProfiles();
@@ -1003,7 +1001,7 @@ app.get('/api/auth/profiles', (req, res) => {
1003
1001
  const providerProfiles = listAuthProfiles(provider);
1004
1002
  profiles[provider] = {
1005
1003
  profiles: providerProfiles,
1006
- active: activeProfiles[provider] || null,
1004
+ active: (activeProfiles[provider] && verifyActiveProfile(provider, activeProfiles[provider], authConfig[provider])) ? activeProfiles[provider] : null,
1007
1005
  hasCurrentAuth: !!authConfig[provider],
1008
1006
  };
1009
1007
  });
@@ -1019,7 +1017,7 @@ app.get('/api/auth/profiles/:provider', (req, res) => {
1019
1017
 
1020
1018
  res.json({
1021
1019
  profiles: providerProfiles,
1022
- active: activeProfiles[provider] || null,
1020
+ active: (activeProfiles[provider] && verifyActiveProfile(provider, activeProfiles[provider], authConfig[provider])) ? activeProfiles[provider] : null,
1023
1021
  hasCurrentAuth: !!authConfig[provider],
1024
1022
  });
1025
1023
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-studio-server",
3
- "version": "1.0.7",
3
+ "version": "1.0.10",
4
4
  "description": "Backend server for OpenCode Studio - manages opencode configurations",
5
5
  "main": "index.js",
6
6
  "bin": {