code-mon-config 1.0.5 ā 1.0.7
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/extensions/example-extenson.js +27 -0
- package/index.js +103 -202
- package/package.json +12 -3
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Example Extension for Code Mon
|
|
2
|
+
// This demonstrates how to add new APIs or hook into the CLI
|
|
3
|
+
|
|
4
|
+
module.exports = ({ app, ROOT, spawn, processes }) => {
|
|
5
|
+
|
|
6
|
+
// Example: add a simple test route
|
|
7
|
+
app.get("/hello", (req, res) => {
|
|
8
|
+
res.json({ message: "Hello from example extension!" });
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Example: a custom execute endpoint that uses the process manager
|
|
12
|
+
app.post("/execute-extension", (req, res) => {
|
|
13
|
+
const { command } = req.body;
|
|
14
|
+
if (!command) return res.json({ error: "Command required" });
|
|
15
|
+
|
|
16
|
+
const proc = spawn(command, { cwd: ROOT, shell: true });
|
|
17
|
+
const id = Object.keys(processes).length;
|
|
18
|
+
processes[id] = proc;
|
|
19
|
+
|
|
20
|
+
proc.stdout.on("data", data => console.log(`[ext-${id}]`, data.toString()));
|
|
21
|
+
proc.stderr.on("data", data => console.error(`[ext-${id}]`, data.toString()));
|
|
22
|
+
proc.on("close", code => delete processes[id]);
|
|
23
|
+
|
|
24
|
+
res.json({ success: true, processId: id });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
};
|
package/index.js
CHANGED
|
@@ -9,7 +9,6 @@ const open = require("open");
|
|
|
9
9
|
const WebSocket = require("ws");
|
|
10
10
|
|
|
11
11
|
const app = express();
|
|
12
|
-
|
|
13
12
|
app.use(cors());
|
|
14
13
|
app.use(express.json());
|
|
15
14
|
|
|
@@ -17,260 +16,162 @@ const PORT = 3000;
|
|
|
17
16
|
const ROOT = process.cwd();
|
|
18
17
|
|
|
19
18
|
/* ---------------- PROCESS MANAGER ---------------- */
|
|
20
|
-
|
|
21
19
|
let processes = {};
|
|
22
20
|
let processId = 0;
|
|
23
21
|
|
|
24
22
|
/* ---------------- FILE TREE ---------------- */
|
|
25
|
-
|
|
26
23
|
function getTree(dir, base = "") {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
results.push(rel
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
results.push(rel);
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return results;
|
|
24
|
+
let results = [];
|
|
25
|
+
const list = fs.readdirSync(dir);
|
|
26
|
+
|
|
27
|
+
list.forEach(file => {
|
|
28
|
+
const full = path.join(dir, file);
|
|
29
|
+
const rel = path.join(base, file);
|
|
30
|
+
const stat = fs.statSync(full);
|
|
31
|
+
|
|
32
|
+
if (stat.isDirectory()) {
|
|
33
|
+
results.push(rel + "/");
|
|
34
|
+
results = results.concat(getTree(full, rel));
|
|
35
|
+
} else {
|
|
36
|
+
results.push(rel);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return results;
|
|
51
41
|
}
|
|
52
42
|
|
|
53
43
|
/* ---------------- FILE APIs ---------------- */
|
|
54
|
-
|
|
55
44
|
app.get("/list", (req, res) => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
root: ROOT,
|
|
63
|
-
files: tree
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
} catch (err) {
|
|
67
|
-
|
|
68
|
-
res.json({ error: err.message });
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
45
|
+
try {
|
|
46
|
+
const tree = getTree(ROOT);
|
|
47
|
+
res.json({ root: ROOT, files: tree });
|
|
48
|
+
} catch (err) {
|
|
49
|
+
res.json({ error: err.message });
|
|
50
|
+
}
|
|
72
51
|
});
|
|
73
52
|
|
|
74
53
|
app.get("/load", (req, res) => {
|
|
54
|
+
const filename = req.query.filename;
|
|
55
|
+
const filePath = path.join(ROOT, filename);
|
|
75
56
|
|
|
76
|
-
|
|
77
|
-
const filePath = path.join(ROOT, filename);
|
|
78
|
-
|
|
79
|
-
if (!fs.existsSync(filePath))
|
|
80
|
-
return res.json({ error: "File not found" });
|
|
81
|
-
|
|
82
|
-
const content = fs.readFileSync(filePath, "utf8");
|
|
83
|
-
|
|
84
|
-
res.json({ content });
|
|
57
|
+
if (!fs.existsSync(filePath)) return res.json({ error: "File not found" });
|
|
85
58
|
|
|
59
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
60
|
+
res.json({ content });
|
|
86
61
|
});
|
|
87
62
|
|
|
88
63
|
app.post("/save", (req, res) => {
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
fs.writeFileSync(filePath, content || "");
|
|
95
|
-
|
|
96
|
-
res.json({ success: true });
|
|
97
|
-
|
|
64
|
+
const { filename, content } = req.body;
|
|
65
|
+
const filePath = path.join(ROOT, filename);
|
|
66
|
+
fs.writeFileSync(filePath, content || "");
|
|
67
|
+
res.json({ success: true });
|
|
98
68
|
});
|
|
99
69
|
|
|
100
70
|
app.post("/create", (req, res) => {
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
fs.writeFileSync(filePath, "");
|
|
107
|
-
|
|
108
|
-
res.json({ success: true });
|
|
109
|
-
|
|
71
|
+
const { filename } = req.body;
|
|
72
|
+
const filePath = path.join(ROOT, filename);
|
|
73
|
+
fs.writeFileSync(filePath, "");
|
|
74
|
+
res.json({ success: true });
|
|
110
75
|
});
|
|
111
76
|
|
|
112
77
|
app.delete("/delete", (req, res) => {
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (fs.existsSync(filePath)) {
|
|
119
|
-
fs.unlinkSync(filePath);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
res.json({ success: true });
|
|
123
|
-
|
|
78
|
+
const { filename } = req.body;
|
|
79
|
+
const filePath = path.join(ROOT, filename);
|
|
80
|
+
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
|
|
81
|
+
res.json({ success: true });
|
|
124
82
|
});
|
|
125
83
|
|
|
126
84
|
/* ---------------- EXECUTE COMMAND ---------------- */
|
|
127
|
-
|
|
128
85
|
app.post("/execute", (req, res) => {
|
|
86
|
+
const { command } = req.body;
|
|
87
|
+
if (!command) return res.json({ error: "Command required" });
|
|
129
88
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const parts = command.split(" ");
|
|
137
|
-
|
|
138
|
-
const proc = spawn(parts[0], parts.slice(1), {
|
|
139
|
-
cwd: ROOT,
|
|
140
|
-
shell: true
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
const id = processId++;
|
|
144
|
-
|
|
145
|
-
processes[id] = proc;
|
|
89
|
+
const parts = command.split(" ");
|
|
90
|
+
const proc = spawn(parts[0], parts.slice(1), { cwd: ROOT, shell: true });
|
|
91
|
+
const id = processId++;
|
|
92
|
+
processes[id] = proc;
|
|
146
93
|
|
|
147
|
-
proc.stdout.on("data", data => {
|
|
148
|
-
console.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
proc.on("close", code => {
|
|
156
|
-
delete processes[id];
|
|
157
|
-
console.log(`Process ${id} exited`);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
res.json({
|
|
161
|
-
success: true,
|
|
162
|
-
processId: id
|
|
163
|
-
});
|
|
94
|
+
proc.stdout.on("data", data => console.log(`[${id}]`, data.toString()));
|
|
95
|
+
proc.stderr.on("data", data => console.error(`[${id}]`, data.toString()));
|
|
96
|
+
proc.on("close", code => {
|
|
97
|
+
delete processes[id];
|
|
98
|
+
console.log(`Process ${id} exited`);
|
|
99
|
+
});
|
|
164
100
|
|
|
101
|
+
res.json({ success: true, processId: id });
|
|
165
102
|
});
|
|
166
103
|
|
|
167
104
|
/* ---------------- PROCESS LIST ---------------- */
|
|
168
|
-
|
|
169
105
|
app.get("/processes", (req, res) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
id: id
|
|
173
|
-
}));
|
|
174
|
-
|
|
175
|
-
res.json(list);
|
|
176
|
-
|
|
106
|
+
const list = Object.keys(processes).map(id => ({ id }));
|
|
107
|
+
res.json(list);
|
|
177
108
|
});
|
|
178
109
|
|
|
179
110
|
/* ---------------- STOP PROCESS ---------------- */
|
|
180
|
-
|
|
181
111
|
app.post("/stop-process", (req, res) => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
112
|
+
const { id } = req.body;
|
|
113
|
+
if (!processes[id]) return res.json({ error: "Process not found" });
|
|
114
|
+
|
|
115
|
+
processes[id].kill();
|
|
116
|
+
delete processes[id];
|
|
117
|
+
|
|
118
|
+
res.json({ success: true, message: "Process stopped" });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
/* ---------------- EXTENSION LOADER ---------------- */
|
|
122
|
+
const EXT_DIR = path.join(__dirname, "extensions");
|
|
123
|
+
if (fs.existsSync(EXT_DIR)) {
|
|
124
|
+
fs.readdirSync(EXT_DIR).forEach(file => {
|
|
125
|
+
if (file.endsWith(".js")) {
|
|
126
|
+
try {
|
|
127
|
+
require(path.join(EXT_DIR, file))({ app, ROOT, spawn, processes });
|
|
128
|
+
console.log(`š Loaded extension: ${file}`);
|
|
129
|
+
} catch (e) {
|
|
130
|
+
console.error(`ā Failed to load extension ${file}:`, e);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
187
134
|
}
|
|
188
135
|
|
|
189
|
-
processes[id].kill();
|
|
190
|
-
|
|
191
|
-
delete processes[id];
|
|
192
|
-
|
|
193
|
-
res.json({
|
|
194
|
-
success: true,
|
|
195
|
-
message: "Process stopped"
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
});
|
|
199
|
-
|
|
200
136
|
/* ---------------- START SERVER ---------------- */
|
|
201
|
-
|
|
202
137
|
const server = app.listen(PORT, async () => {
|
|
138
|
+
console.log("\nš Code Mon Config Starting...");
|
|
139
|
+
console.log("š Connected Folder:", ROOT);
|
|
140
|
+
console.log("\nā
Your terminal has been connected with Code Mon Code Space\n");
|
|
203
141
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
console.log("
|
|
207
|
-
|
|
208
|
-
console.log("\nā
Your terminal has been connected with Code Mon Code Space\n");
|
|
209
|
-
|
|
210
|
-
const url = "https://your-domain.com";
|
|
211
|
-
|
|
212
|
-
console.log("š Opening:", url);
|
|
213
|
-
|
|
214
|
-
try {
|
|
215
|
-
|
|
216
|
-
await open(url);
|
|
217
|
-
|
|
218
|
-
} catch {
|
|
219
|
-
|
|
220
|
-
console.log("Open manually:", url);
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
|
|
142
|
+
const url = `http://localhost:${PORT}`;
|
|
143
|
+
console.log("š Opening:", url);
|
|
144
|
+
try { await open(url); } catch { console.log("Open manually:", url); }
|
|
224
145
|
});
|
|
225
146
|
|
|
226
147
|
/* ---------------- WEBSOCKET TERMINAL ---------------- */
|
|
227
|
-
|
|
228
148
|
const wss = new WebSocket.Server({ server });
|
|
229
149
|
|
|
230
150
|
wss.on("connection", ws => {
|
|
151
|
+
console.log("š¢ Terminal connected");
|
|
231
152
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
ws.on("message", msg => {
|
|
237
|
-
|
|
238
|
-
const command = msg.toString();
|
|
239
|
-
|
|
240
|
-
if (!proc) {
|
|
241
|
-
|
|
242
|
-
proc = spawn(command, {
|
|
243
|
-
cwd: ROOT,
|
|
244
|
-
shell: true
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
proc.stdout.on("data", data => {
|
|
248
|
-
ws.send(data.toString());
|
|
249
|
-
});
|
|
153
|
+
let proc;
|
|
154
|
+
ws.on("message", msg => {
|
|
155
|
+
const command = msg.toString();
|
|
250
156
|
|
|
251
|
-
proc
|
|
252
|
-
|
|
253
|
-
});
|
|
157
|
+
if (!proc) {
|
|
158
|
+
proc = spawn(command, { cwd: ROOT, shell: true });
|
|
254
159
|
|
|
255
|
-
proc.on("
|
|
256
|
-
|
|
257
|
-
proc = null;
|
|
258
|
-
});
|
|
160
|
+
proc.stdout.on("data", data => ws.send(data.toString()));
|
|
161
|
+
proc.stderr.on("data", data => ws.send(data.toString()));
|
|
259
162
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
proc
|
|
263
|
-
|
|
264
|
-
}
|
|
163
|
+
proc.on("close", code => {
|
|
164
|
+
ws.send(`\nProcess exited with code ${code}\n`);
|
|
165
|
+
proc = null;
|
|
166
|
+
});
|
|
265
167
|
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (proc) proc.kill();
|
|
271
|
-
|
|
272
|
-
console.log("š“ Terminal disconnected");
|
|
273
|
-
|
|
274
|
-
});
|
|
168
|
+
} else {
|
|
169
|
+
proc.stdin.write(command + "\n"); // support multi-step input
|
|
170
|
+
}
|
|
171
|
+
});
|
|
275
172
|
|
|
173
|
+
ws.on("close", () => {
|
|
174
|
+
if (proc) proc.kill();
|
|
175
|
+
console.log("š“ Terminal disconnected");
|
|
176
|
+
});
|
|
276
177
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-mon-config",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Code Mon Code Space CLI",
|
|
3
|
+
"version": "1.0.7",
|
|
4
|
+
"description": "Code Mon Code Space CLI with plugin/extension system",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"code-mon-config": "./index.js"
|
|
@@ -14,5 +14,14 @@
|
|
|
14
14
|
"express": "^4.22.1",
|
|
15
15
|
"open": "^10.2.0",
|
|
16
16
|
"ws": "^8.19.0"
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"cli",
|
|
20
|
+
"terminal",
|
|
21
|
+
"websocket",
|
|
22
|
+
"extensions",
|
|
23
|
+
"code-mon-config"
|
|
24
|
+
],
|
|
25
|
+
"author": "C69P2W",
|
|
26
|
+
"license": "MIT"
|
|
18
27
|
}
|