opencode-studio-server 1.16.3 → 1.16.4

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/index.js +124 -0
  2. package/package.json +1 -1
  3. package/server.log +1 -2
package/index.js CHANGED
@@ -84,6 +84,7 @@ app.use(cors({
84
84
  }));
85
85
  app.use(bodyParser.json({ limit: '50mb' }));
86
86
  app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
87
+ app.use(bodyParser.text({ type: ['text/*', 'application/yaml'], limit: '50mb' }));
87
88
 
88
89
  const HOME_DIR = os.homedir();
89
90
  const STUDIO_CONFIG_PATH = path.join(HOME_DIR, '.config', 'opencode-studio', 'studio.json');
@@ -2639,6 +2640,129 @@ app.post('/api/proxy/config', (req, res) => {
2639
2640
  res.json({ success: true });
2640
2641
  });
2641
2642
 
2643
+ const PROXY_CONFIG_PATH = path.join(HOME_DIR, '.config', 'opencode-studio', 'cliproxy.yaml');
2644
+
2645
+ app.get('/api/management/config.yaml', (req, res) => {
2646
+ console.log('GET config.yaml hit');
2647
+ if (!fs.existsSync(PROXY_CONFIG_PATH)) {
2648
+ console.log('Config file not found:', PROXY_CONFIG_PATH);
2649
+ return res.send("");
2650
+ }
2651
+ console.log('Sending config file:', PROXY_CONFIG_PATH);
2652
+ const content = fs.readFileSync(PROXY_CONFIG_PATH, 'utf8');
2653
+ res.send(content);
2654
+ });
2655
+
2656
+ app.put('/api/management/config.yaml', (req, res) => {
2657
+ fs.writeFileSync(PROXY_CONFIG_PATH, req.body);
2658
+ res.json({ ok: true, changed: [] });
2659
+ });
2660
+
2661
+ app.get('/api/management/api-keys', (req, res) => {
2662
+ if (!fs.existsSync(PROXY_CONFIG_PATH)) return res.json({ "api-keys": [] });
2663
+ const content = fs.readFileSync(PROXY_CONFIG_PATH, 'utf8');
2664
+ const yaml = require('js-yaml');
2665
+ try {
2666
+ const doc = yaml.load(content) || {};
2667
+ const keys = [];
2668
+ if (doc['management-key']) keys.push(doc['management-key']);
2669
+ if (Array.isArray(doc['api-keys'])) keys.push(...doc['api-keys']);
2670
+ res.json({ "api-keys": [...new Set(keys)].filter(k => k) });
2671
+ } catch (e) {
2672
+ res.json({ "api-keys": [] });
2673
+ }
2674
+ });
2675
+
2676
+ app.put('/api/management/api-keys', (req, res) => {
2677
+ const keys = req.body;
2678
+ if (!fs.existsSync(PROXY_CONFIG_PATH)) return res.status(404).json({ error: "Config not found" });
2679
+ const content = fs.readFileSync(PROXY_CONFIG_PATH, 'utf8');
2680
+ const yaml = require('js-yaml');
2681
+ try {
2682
+ const doc = yaml.load(content) || {};
2683
+ doc['api-keys'] = keys;
2684
+ if (keys.length > 0) doc['management-key'] = keys[0];
2685
+
2686
+ fs.writeFileSync(PROXY_CONFIG_PATH, yaml.dump(doc));
2687
+ res.json({ status: "ok" });
2688
+ } catch (e) {
2689
+ res.status(500).json({ error: e.message });
2690
+ }
2691
+ });
2692
+
2693
+ app.get('/api/management/logs', (req, res) => {
2694
+ if (!fs.existsSync(LOG_DIR)) return res.json({ lines: [], "line-count": 0, "latest-timestamp": Date.now() });
2695
+ const logFiles = fs.readdirSync(LOG_DIR).filter(f => f.endsWith('.log'));
2696
+ if (logFiles.length === 0) return res.json({ lines: [], "line-count": 0, "latest-timestamp": Date.now() });
2697
+
2698
+ const latest = logFiles.map(f => ({ name: f, time: fs.statSync(path.join(LOG_DIR, f)).mtime.getTime() }))
2699
+ .sort((a, b) => b.time - a.time)[0];
2700
+
2701
+ const content = fs.readFileSync(path.join(LOG_DIR, latest.name), 'utf8');
2702
+ const lines = content.split('\n').slice(-1000);
2703
+ res.json({ lines, "line-count": lines.length, "latest-timestamp": latest.time });
2704
+ });
2705
+
2706
+ app.get('/api/management/usage', (req, res) => {
2707
+ res.json({
2708
+ usage: {
2709
+ total_requests: 0,
2710
+ success_count: 0,
2711
+ failure_count: 0,
2712
+ total_tokens: 0,
2713
+ requests_by_day: {},
2714
+ requests_by_hour: {},
2715
+ tokens_by_day: {},
2716
+ tokens_by_hour: {},
2717
+ apis: {},
2718
+ failed_requests: 0
2719
+ }
2720
+ });
2721
+ });
2722
+
2723
+ app.get('/api/management/logging-to-file', (req, res) => {
2724
+ if (!fs.existsSync(PROXY_CONFIG_PATH)) return res.json({ "logging-to-file": false });
2725
+ try {
2726
+ const content = fs.readFileSync(PROXY_CONFIG_PATH, 'utf8');
2727
+ const yaml = require('js-yaml');
2728
+ const doc = yaml.load(content) || {};
2729
+ res.json({ "logging-to-file": !!doc['logging-to-file'] });
2730
+ } catch (e) {
2731
+ res.json({ "logging-to-file": false });
2732
+ }
2733
+ });
2734
+
2735
+ app.patch('/api/management/logging-to-file', (req, res) => {
2736
+ if (!fs.existsSync(PROXY_CONFIG_PATH)) return res.status(404).json({ error: "Config not found" });
2737
+ const enabled = req.body.value;
2738
+ const content = fs.readFileSync(PROXY_CONFIG_PATH, 'utf8');
2739
+ const yaml = require('js-yaml');
2740
+ try {
2741
+ const doc = yaml.load(content) || {};
2742
+ doc['logging-to-file'] = enabled;
2743
+ fs.writeFileSync(PROXY_CONFIG_PATH, yaml.dump(doc));
2744
+ res.json({ status: "ok" });
2745
+ } catch (e) {
2746
+ res.status(500).json({ error: e.message });
2747
+ }
2748
+ });
2749
+
2750
+ app.delete('/api/management/logs', (req, res) => {
2751
+ if (!fs.existsSync(LOG_DIR)) return res.json({ success: true, removed: 0 });
2752
+ const logFiles = fs.readdirSync(LOG_DIR).filter(f => f.endsWith('.log'));
2753
+ let removed = 0;
2754
+ try {
2755
+ logFiles.forEach(f => {
2756
+ const filePath = path.join(LOG_DIR, f);
2757
+ fs.unlinkSync(filePath);
2758
+ removed++;
2759
+ });
2760
+ res.json({ success: true, removed });
2761
+ } catch (e) {
2762
+ res.status(500).json({ error: e.message });
2763
+ }
2764
+ });
2765
+
2642
2766
  app.get('/api/profiles', (req, res) => {
2643
2767
  res.json(profileManager.listProfiles());
2644
2768
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-studio-server",
3
- "version": "1.16.3",
3
+ "version": "1.16.4",
4
4
  "description": "Backend server for OpenCode Studio - manages opencode configurations",
5
5
  "main": "index.js",
6
6
  "bin": {
package/server.log CHANGED
@@ -1,2 +1 @@
1
- [Auth] Syncing github-copilot login for profile-1768767863510 to pool.
2
- Server running at http://localhost:3001
1
+ Acceso denegado.