247-cli 2.32.1 → 2.33.0
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/agent/dist/routes/projects.d.ts +1 -1
- package/agent/dist/routes/projects.d.ts.map +1 -1
- package/agent/dist/routes/projects.js +90 -1
- package/agent/dist/routes/projects.js.map +1 -1
- package/agent/node_modules/247-shared/package.json +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/routes/projects.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/routes/projects.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKjC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CA4H5C"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project-related API routes: listing and
|
|
2
|
+
* Project-related API routes: listing, folder scanning, and git clone.
|
|
3
3
|
*/
|
|
4
4
|
import { Router } from 'express';
|
|
5
|
+
import { spawn } from 'child_process';
|
|
5
6
|
import { config } from '../config.js';
|
|
6
7
|
// Helper to check if project is allowed (whitelist empty = allow any)
|
|
7
8
|
export function isProjectAllowed(project) {
|
|
@@ -32,6 +33,94 @@ export function createProjectRoutes() {
|
|
|
32
33
|
res.status(500).json({ error: 'Failed to list folders' });
|
|
33
34
|
}
|
|
34
35
|
});
|
|
36
|
+
// Clone a git repository
|
|
37
|
+
router.post('/clone', async (req, res) => {
|
|
38
|
+
const { url } = req.body;
|
|
39
|
+
if (!url) {
|
|
40
|
+
return res.status(400).json({ success: false, error: 'URL is required' });
|
|
41
|
+
}
|
|
42
|
+
// Validate URL format (https:// or git@)
|
|
43
|
+
const httpsPattern = /^https:\/\/.+\/.+/;
|
|
44
|
+
const sshPattern = /^git@.+:.+/;
|
|
45
|
+
if (!httpsPattern.test(url) && !sshPattern.test(url)) {
|
|
46
|
+
return res.status(400).json({ success: false, error: 'Invalid URL format' });
|
|
47
|
+
}
|
|
48
|
+
// Extract repo name from URL
|
|
49
|
+
let repoName;
|
|
50
|
+
try {
|
|
51
|
+
if (url.startsWith('git@')) {
|
|
52
|
+
// git@github.com:user/repo.git -> repo
|
|
53
|
+
const match = url.match(/:([^/]+\/)?(.+?)(\.git)?$/);
|
|
54
|
+
repoName = match?.[2] || '';
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// https://github.com/user/repo.git -> repo
|
|
58
|
+
const urlObj = new URL(url);
|
|
59
|
+
const pathParts = urlObj.pathname.split('/').filter(Boolean);
|
|
60
|
+
repoName = pathParts[pathParts.length - 1]?.replace(/\.git$/, '') || '';
|
|
61
|
+
}
|
|
62
|
+
if (!repoName) {
|
|
63
|
+
return res
|
|
64
|
+
.status(400)
|
|
65
|
+
.json({ success: false, error: 'Could not extract repo name from URL' });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (_err) {
|
|
69
|
+
return res.status(400).json({ success: false, error: 'Invalid URL format' });
|
|
70
|
+
}
|
|
71
|
+
const fs = await import('fs/promises');
|
|
72
|
+
const path = await import('path');
|
|
73
|
+
const basePath = config.projects.basePath.replace('~', process.env.HOME);
|
|
74
|
+
const targetPath = path.join(basePath, repoName);
|
|
75
|
+
// Check if folder already exists
|
|
76
|
+
try {
|
|
77
|
+
await fs.access(targetPath);
|
|
78
|
+
return res.status(400).json({
|
|
79
|
+
success: false,
|
|
80
|
+
error: `Folder "${repoName}" already exists`,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (_err) {
|
|
84
|
+
// Folder doesn't exist, good to proceed
|
|
85
|
+
}
|
|
86
|
+
// Clone the repository
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
const gitProcess = spawn('git', ['clone', url, repoName], {
|
|
89
|
+
cwd: basePath,
|
|
90
|
+
env: process.env,
|
|
91
|
+
});
|
|
92
|
+
let stderr = '';
|
|
93
|
+
gitProcess.stderr.on('data', (data) => {
|
|
94
|
+
stderr += data.toString();
|
|
95
|
+
});
|
|
96
|
+
gitProcess.on('close', (code) => {
|
|
97
|
+
if (code === 0) {
|
|
98
|
+
console.log(`Successfully cloned ${url} to ${targetPath}`);
|
|
99
|
+
res.json({
|
|
100
|
+
success: true,
|
|
101
|
+
project: repoName,
|
|
102
|
+
path: targetPath,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.error(`Git clone failed: ${stderr}`);
|
|
107
|
+
res.status(500).json({
|
|
108
|
+
success: false,
|
|
109
|
+
error: stderr.trim() || 'Git clone failed',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
resolve();
|
|
113
|
+
});
|
|
114
|
+
gitProcess.on('error', (err) => {
|
|
115
|
+
console.error('Failed to spawn git:', err);
|
|
116
|
+
res.status(500).json({
|
|
117
|
+
success: false,
|
|
118
|
+
error: 'Failed to execute git command',
|
|
119
|
+
});
|
|
120
|
+
resolve();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
35
124
|
return router;
|
|
36
125
|
}
|
|
37
126
|
//# sourceMappingURL=projects.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/routes/projects.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,sEAAsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAqB,CAAC;IACxD,MAAM,YAAY,GAAG,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IACvD,OAAO,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,4BAA4B;IAC5B,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACpC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,0DAA0D;IAC1D,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACzC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,IAAK,CAAC,CAAC;YAE1E,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACpE,MAAM,OAAO,GAAG,OAAO;iBACpB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;iBACrE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;iBAC1B,IAAI,EAAE,CAAC;YAEV,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;YAC9C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/routes/projects.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const program = new Command();
|
|
|
15
15
|
program
|
|
16
16
|
.name('247')
|
|
17
17
|
.description('247 - Access Claude Code from anywhere 24/7\nby The Vibe Company')
|
|
18
|
-
.version('2.
|
|
18
|
+
.version('2.33.0')
|
|
19
19
|
.option('-P, --profile <name>', 'Use a specific profile (dev, prod, etc.)');
|
|
20
20
|
// Add commands
|
|
21
21
|
program.addCommand(initCommand);
|