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.
- package/index.js +124 -0
- package/package.json +1 -1
- 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
package/server.log
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Server running at http://localhost:3001
|
|
1
|
+
Acceso denegado.
|