code-mon-config 1.0.6 → 1.0.8

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.
@@ -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
@@ -21,105 +21,163 @@ const ROOT = process.cwd();
21
21
  let processes = {};
22
22
  let processId = 0;
23
23
 
24
+ /* ---------------- SAFE PATH ---------------- */
25
+
26
+ function safePath(filename) {
27
+
28
+ if (!filename) {
29
+ throw new Error("Filename required");
30
+ }
31
+
32
+ const resolved = path.join(ROOT, filename);
33
+
34
+ if (!resolved.startsWith(ROOT)) {
35
+ throw new Error("Invalid path");
36
+ }
37
+
38
+ return resolved;
39
+ }
40
+
24
41
  /* ---------------- FILE TREE ---------------- */
25
42
 
26
43
  function getTree(dir, base = "") {
27
44
 
28
- let results = [];
29
- const list = fs.readdirSync(dir);
45
+ let results = [];
46
+ const list = fs.readdirSync(dir);
30
47
 
31
- list.forEach(file => {
48
+ list.forEach(file => {
32
49
 
33
- const full = path.join(dir, file);
34
- const rel = path.join(base, file);
35
- const stat = fs.statSync(full);
50
+ const full = path.join(dir, file);
51
+ const rel = path.join(base, file);
52
+ const stat = fs.statSync(full);
36
53
 
37
- if (stat.isDirectory()) {
54
+ if (stat.isDirectory()) {
38
55
 
39
- results.push(rel + "/");
40
- results = results.concat(getTree(full, rel));
56
+ results.push(rel + "/");
57
+ results = results.concat(getTree(full, rel));
41
58
 
42
- } else {
59
+ } else {
43
60
 
44
- results.push(rel);
61
+ results.push(rel);
45
62
 
46
- }
63
+ }
47
64
 
48
- });
65
+ });
49
66
 
50
- return results;
67
+ return results;
51
68
  }
52
69
 
53
70
  /* ---------------- FILE APIs ---------------- */
54
71
 
55
72
  app.get("/list", (req, res) => {
56
73
 
57
- try {
74
+ try {
58
75
 
59
- const tree = getTree(ROOT);
76
+ const tree = getTree(ROOT);
60
77
 
61
- res.json({
62
- root: ROOT,
63
- files: tree
64
- });
78
+ res.json({
79
+ root: ROOT,
80
+ files: tree
81
+ });
65
82
 
66
- } catch (err) {
83
+ } catch (err) {
67
84
 
68
- res.json({ error: err.message });
85
+ res.json({ error: err.message });
69
86
 
70
- }
87
+ }
71
88
 
72
89
  });
73
90
 
91
+ /* LOAD FILE */
92
+
74
93
  app.get("/load", (req, res) => {
75
94
 
76
- const filename = req.query.filename;
77
- const filePath = path.join(ROOT, filename);
95
+ try {
96
+
97
+ const filename = req.query.filename;
98
+ const filePath = safePath(filename);
99
+
100
+ if (!fs.existsSync(filePath)) {
101
+ return res.json({ error: "File not found" });
102
+ }
103
+
104
+ const content = fs.readFileSync(filePath, "utf8");
78
105
 
79
- if (!fs.existsSync(filePath))
80
- return res.json({ error: "File not found" });
106
+ res.json({ content });
81
107
 
82
- const content = fs.readFileSync(filePath, "utf8");
108
+ } catch (err) {
83
109
 
84
- res.json({ content });
110
+ res.json({ error: err.message });
111
+
112
+ }
85
113
 
86
114
  });
87
115
 
116
+ /* SAVE FILE */
117
+
88
118
  app.post("/save", (req, res) => {
89
119
 
90
- const { filename, content } = req.body;
120
+ try {
121
+
122
+ const { filename, content } = req.body;
123
+
124
+ const filePath = safePath(filename);
125
+
126
+ fs.writeFileSync(filePath, content || "");
91
127
 
92
- const filePath = path.join(ROOT, filename);
128
+ res.json({ success: true });
93
129
 
94
- fs.writeFileSync(filePath, content || "");
130
+ } catch (err) {
95
131
 
96
- res.json({ success: true });
132
+ res.json({ error: err.message });
133
+
134
+ }
97
135
 
98
136
  });
99
137
 
138
+ /* CREATE FILE */
139
+
100
140
  app.post("/create", (req, res) => {
101
141
 
102
- const { filename } = req.body;
142
+ try {
143
+
144
+ const { filename } = req.body;
145
+
146
+ const filePath = safePath(filename);
147
+
148
+ fs.writeFileSync(filePath, "");
103
149
 
104
- const filePath = path.join(ROOT, filename);
150
+ res.json({ success: true });
105
151
 
106
- fs.writeFileSync(filePath, "");
152
+ } catch (err) {
107
153
 
108
- res.json({ success: true });
154
+ res.json({ error: err.message });
155
+
156
+ }
109
157
 
110
158
  });
111
159
 
160
+ /* DELETE FILE */
161
+
112
162
  app.delete("/delete", (req, res) => {
113
163
 
114
- const { filename } = req.body;
164
+ try {
115
165
 
116
- const filePath = path.join(ROOT, filename);
166
+ const { filename } = req.body;
117
167
 
118
- if (fs.existsSync(filePath)) {
119
- fs.unlinkSync(filePath);
120
- }
168
+ const filePath = safePath(filename);
169
+
170
+ if (fs.existsSync(filePath)) {
171
+ fs.unlinkSync(filePath);
172
+ }
173
+
174
+ res.json({ success: true });
121
175
 
122
- res.json({ success: true });
176
+ } catch (err) {
177
+
178
+ res.json({ error: err.message });
179
+
180
+ }
123
181
 
124
182
  });
125
183
 
@@ -127,40 +185,51 @@ res.json({ success: true });
127
185
 
128
186
  app.post("/execute", (req, res) => {
129
187
 
130
- const { command } = req.body;
188
+ try {
131
189
 
132
- if (!command) {
133
- return res.json({ error: "Command required" });
134
- }
190
+ const { command } = req.body;
135
191
 
136
- const parts = command.split(" ");
192
+ if (!command) {
193
+ return res.json({ error: "Command required" });
194
+ }
137
195
 
138
- const proc = spawn(parts[0], parts.slice(1), {
139
- cwd: ROOT,
140
- shell: true
141
- });
196
+ const parts = command.split(" ");
142
197
 
143
- const id = processId++;
198
+ const proc = spawn(parts[0], parts.slice(1), {
199
+ cwd: ROOT,
200
+ shell: true
201
+ });
144
202
 
145
- processes[id] = proc;
203
+ const id = processId++;
146
204
 
147
- proc.stdout.on("data", data => {
148
- console.log(`[${id}]`, data.toString());
149
- });
205
+ processes[id] = proc;
150
206
 
151
- proc.stderr.on("data", data => {
152
- console.error(`[${id}]`, data.toString());
153
- });
207
+ proc.stdout.on("data", data => {
208
+ console.log(`[${id}]`, data.toString());
209
+ });
154
210
 
155
- proc.on("close", code => {
156
- delete processes[id];
157
- console.log(`Process ${id} exited`);
158
- });
211
+ proc.stderr.on("data", data => {
212
+ console.error(`[${id}]`, data.toString());
213
+ });
159
214
 
160
- res.json({
161
- success: true,
162
- processId: id
163
- });
215
+ proc.on("close", code => {
216
+
217
+ delete processes[id];
218
+
219
+ console.log(`Process ${id} exited`);
220
+
221
+ });
222
+
223
+ res.json({
224
+ success: true,
225
+ processId: id
226
+ });
227
+
228
+ } catch (err) {
229
+
230
+ res.json({ error: err.message });
231
+
232
+ }
164
233
 
165
234
  });
166
235
 
@@ -168,11 +237,11 @@ processId: id
168
237
 
169
238
  app.get("/processes", (req, res) => {
170
239
 
171
- const list = Object.keys(processes).map(id => ({
172
- id: id
173
- }));
240
+ const list = Object.keys(processes).map(id => ({
241
+ id
242
+ }));
174
243
 
175
- res.json(list);
244
+ res.json(list);
176
245
 
177
246
  });
178
247
 
@@ -180,46 +249,87 @@ res.json(list);
180
249
 
181
250
  app.post("/stop-process", (req, res) => {
182
251
 
183
- const { id } = req.body;
252
+ try {
184
253
 
185
- if (!processes[id]) {
186
- return res.json({ error: "Process not found" });
187
- }
254
+ const { id } = req.body;
188
255
 
189
- processes[id].kill();
256
+ if (!processes[id]) {
257
+ return res.json({ error: "Process not found" });
258
+ }
190
259
 
191
- delete processes[id];
260
+ processes[id].kill();
192
261
 
193
- res.json({
194
- success: true,
195
- message: "Process stopped"
196
- });
262
+ delete processes[id];
263
+
264
+ res.json({
265
+ success: true,
266
+ message: "Process stopped"
267
+ });
268
+
269
+ } catch (err) {
270
+
271
+ res.json({ error: err.message });
272
+
273
+ }
197
274
 
198
275
  });
199
276
 
277
+ /* ---------------- EXTENSION LOADER ---------------- */
278
+
279
+ const EXTENSIONS_DIR = path.join(ROOT, "extensions");
280
+
281
+ if (fs.existsSync(EXTENSIONS_DIR)) {
282
+
283
+ fs.readdirSync(EXTENSIONS_DIR).forEach(file => {
284
+
285
+ if (file.endsWith(".js")) {
286
+
287
+ try {
288
+
289
+ require(path.join(EXTENSIONS_DIR, file))({
290
+ app,
291
+ ROOT,
292
+ spawn,
293
+ processes
294
+ });
295
+
296
+ console.log(`šŸ”Œ Loaded extension: ${file}`);
297
+
298
+ } catch (err) {
299
+
300
+ console.log(`āŒ Failed to load extension: ${file}`);
301
+
302
+ }
303
+
304
+ }
305
+
306
+ });
307
+
308
+ }
309
+
200
310
  /* ---------------- START SERVER ---------------- */
201
311
 
202
312
  const server = app.listen(PORT, async () => {
203
313
 
204
- console.log("\nšŸš€ Code Mon Config Starting...\n");
314
+ console.log("\nšŸš€ Code Mon Config Starting...\n");
205
315
 
206
- console.log("šŸ“‚ Connected Folder:", ROOT);
316
+ console.log("šŸ“‚ Connected Folder:", ROOT);
207
317
 
208
- console.log("\nāœ… Your terminal has been connected with Code Mon Code Space\n");
318
+ console.log("\nāœ… Your terminal has been connected with Code Mon Code Space\n");
209
319
 
210
- const url = "https://code-mon.pages.dev/code-mon-spacr";
320
+ const url = "http://localhost:3000";
211
321
 
212
- console.log("🌐 Opening:", url);
322
+ console.log("🌐 Opening:", url);
213
323
 
214
- try {
324
+ try {
215
325
 
216
- await open(url);
326
+ await open(url);
217
327
 
218
- } catch {
328
+ } catch {
219
329
 
220
- console.log("Open manually:", url);
330
+ console.log("Open manually:", url);
221
331
 
222
- }
332
+ }
223
333
 
224
334
  });
225
335
 
@@ -229,48 +339,51 @@ const wss = new WebSocket.Server({ server });
229
339
 
230
340
  wss.on("connection", ws => {
231
341
 
232
- console.log("🟢 Terminal connected");
342
+ console.log("🟢 Terminal connected");
233
343
 
234
- let proc;
344
+ let proc;
235
345
 
236
- ws.on("message", msg => {
346
+ ws.on("message", msg => {
237
347
 
238
- const command = msg.toString();
348
+ const command = msg.toString();
239
349
 
240
- if (!proc) {
350
+ if (!proc) {
241
351
 
242
- proc = spawn(command, {
243
- cwd: ROOT,
244
- shell: true
245
- });
352
+ proc = spawn(command, {
353
+ cwd: ROOT,
354
+ shell: true
355
+ });
246
356
 
247
- proc.stdout.on("data", data => {
248
- ws.send(data.toString());
249
- });
357
+ proc.stdout.on("data", data => {
358
+ ws.send(data.toString());
359
+ });
250
360
 
251
- proc.stderr.on("data", data => {
252
- ws.send(data.toString());
253
- });
361
+ proc.stderr.on("data", data => {
362
+ ws.send(data.toString());
363
+ });
254
364
 
255
- proc.on("close", code => {
256
- ws.send(`\nProcess exited with code ${code}\n`);
257
- proc = null;
258
- });
365
+ proc.on("close", code => {
259
366
 
260
- } else {
367
+ ws.send(`\nProcess exited with code ${code}\n`);
261
368
 
262
- proc.stdin.write(command);
369
+ proc = null;
263
370
 
264
- }
371
+ });
265
372
 
266
- });
373
+ } else {
267
374
 
268
- ws.on("close", () => {
375
+ proc.stdin.write(command + "\n");
269
376
 
270
- if (proc) proc.kill();
377
+ }
271
378
 
272
- console.log("šŸ”“ Terminal disconnected");
379
+ });
273
380
 
274
- });
381
+ ws.on("close", () => {
382
+
383
+ if (proc) proc.kill();
384
+
385
+ console.log("šŸ”“ Terminal disconnected");
386
+
387
+ });
275
388
 
276
389
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "code-mon-config",
3
- "version": "1.0.6",
4
- "description": "Code Mon Code Space CLI",
3
+ "version": "1.0.8",
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
  }