tlc-claude-code 0.6.4 → 0.7.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.
@@ -0,0 +1,301 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * Detect project type and return start configuration
6
+ */
7
+ function detectProject(projectDir) {
8
+ // Check for .tlc.json custom config first
9
+ const tlcConfigPath = path.join(projectDir, '.tlc.json');
10
+ if (fs.existsSync(tlcConfigPath)) {
11
+ try {
12
+ const config = JSON.parse(fs.readFileSync(tlcConfigPath, 'utf-8'));
13
+ if (config.server?.startCommand) {
14
+ const parts = config.server.startCommand.split(' ');
15
+ return {
16
+ name: 'Custom (.tlc.json)',
17
+ cmd: parts[0],
18
+ args: parts.slice(1),
19
+ port: config.server.appPort || 3000
20
+ };
21
+ }
22
+ } catch (e) {
23
+ // Continue with auto-detection
24
+ }
25
+ }
26
+
27
+ // Node.js / JavaScript
28
+ const pkgPath = path.join(projectDir, 'package.json');
29
+ if (fs.existsSync(pkgPath)) {
30
+ try {
31
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
32
+
33
+ // Next.js
34
+ if (pkg.dependencies?.next || pkg.devDependencies?.next) {
35
+ return {
36
+ name: 'Next.js',
37
+ cmd: 'npm',
38
+ args: ['run', 'dev'],
39
+ port: 3000
40
+ };
41
+ }
42
+
43
+ // Vite
44
+ if (pkg.dependencies?.vite || pkg.devDependencies?.vite) {
45
+ return {
46
+ name: 'Vite',
47
+ cmd: 'npm',
48
+ args: ['run', 'dev'],
49
+ port: 5173
50
+ };
51
+ }
52
+
53
+ // Create React App
54
+ if (pkg.dependencies?.['react-scripts']) {
55
+ return {
56
+ name: 'Create React App',
57
+ cmd: 'npm',
58
+ args: ['start'],
59
+ port: 3000
60
+ };
61
+ }
62
+
63
+ // Express / Node server
64
+ if (pkg.dependencies?.express) {
65
+ if (pkg.scripts?.dev) {
66
+ return {
67
+ name: 'Express (dev script)',
68
+ cmd: 'npm',
69
+ args: ['run', 'dev'],
70
+ port: parseInt(process.env.PORT || '3000')
71
+ };
72
+ }
73
+ return {
74
+ name: 'Express',
75
+ cmd: 'npm',
76
+ args: ['start'],
77
+ port: parseInt(process.env.PORT || '3000')
78
+ };
79
+ }
80
+
81
+ // Nuxt.js
82
+ if (pkg.dependencies?.nuxt || pkg.devDependencies?.nuxt) {
83
+ return {
84
+ name: 'Nuxt.js',
85
+ cmd: 'npm',
86
+ args: ['run', 'dev'],
87
+ port: 3000
88
+ };
89
+ }
90
+
91
+ // Astro
92
+ if (pkg.dependencies?.astro || pkg.devDependencies?.astro) {
93
+ return {
94
+ name: 'Astro',
95
+ cmd: 'npm',
96
+ args: ['run', 'dev'],
97
+ port: 4321
98
+ };
99
+ }
100
+
101
+ // SvelteKit
102
+ if (pkg.devDependencies?.['@sveltejs/kit']) {
103
+ return {
104
+ name: 'SvelteKit',
105
+ cmd: 'npm',
106
+ args: ['run', 'dev'],
107
+ port: 5173
108
+ };
109
+ }
110
+
111
+ // Generic npm dev script
112
+ if (pkg.scripts?.dev) {
113
+ return {
114
+ name: 'Node.js (npm run dev)',
115
+ cmd: 'npm',
116
+ args: ['run', 'dev'],
117
+ port: 3000
118
+ };
119
+ }
120
+
121
+ // Generic npm start
122
+ if (pkg.scripts?.start) {
123
+ return {
124
+ name: 'Node.js (npm start)',
125
+ cmd: 'npm',
126
+ args: ['start'],
127
+ port: 3000
128
+ };
129
+ }
130
+ } catch (e) {
131
+ // Continue with other detection
132
+ }
133
+ }
134
+
135
+ // Python - pyproject.toml
136
+ const pyprojectPath = path.join(projectDir, 'pyproject.toml');
137
+ if (fs.existsSync(pyprojectPath)) {
138
+ const content = fs.readFileSync(pyprojectPath, 'utf-8');
139
+
140
+ // FastAPI/Uvicorn
141
+ if (content.includes('fastapi') || content.includes('uvicorn')) {
142
+ return {
143
+ name: 'FastAPI',
144
+ cmd: 'uvicorn',
145
+ args: ['main:app', '--reload', '--port', '8000'],
146
+ port: 8000
147
+ };
148
+ }
149
+
150
+ // Django
151
+ if (content.includes('django')) {
152
+ return {
153
+ name: 'Django',
154
+ cmd: 'python',
155
+ args: ['manage.py', 'runserver', '8000'],
156
+ port: 8000
157
+ };
158
+ }
159
+ }
160
+
161
+ // Python - requirements.txt
162
+ const requirementsPath = path.join(projectDir, 'requirements.txt');
163
+ if (fs.existsSync(requirementsPath)) {
164
+ const content = fs.readFileSync(requirementsPath, 'utf-8');
165
+
166
+ // Flask
167
+ if (content.includes('flask') || content.includes('Flask')) {
168
+ return {
169
+ name: 'Flask',
170
+ cmd: 'flask',
171
+ args: ['run', '--port', '5000'],
172
+ port: 5000
173
+ };
174
+ }
175
+
176
+ // FastAPI
177
+ if (content.includes('fastapi') || content.includes('uvicorn')) {
178
+ return {
179
+ name: 'FastAPI',
180
+ cmd: 'uvicorn',
181
+ args: ['main:app', '--reload', '--port', '8000'],
182
+ port: 8000
183
+ };
184
+ }
185
+
186
+ // Django
187
+ if (content.includes('django') || content.includes('Django')) {
188
+ return {
189
+ name: 'Django',
190
+ cmd: 'python',
191
+ args: ['manage.py', 'runserver', '8000'],
192
+ port: 8000
193
+ };
194
+ }
195
+ }
196
+
197
+ // Go
198
+ const goModPath = path.join(projectDir, 'go.mod');
199
+ if (fs.existsSync(goModPath)) {
200
+ return {
201
+ name: 'Go',
202
+ cmd: 'go',
203
+ args: ['run', '.'],
204
+ port: 8080
205
+ };
206
+ }
207
+
208
+ // Ruby - Rails
209
+ const gemfilePath = path.join(projectDir, 'Gemfile');
210
+ if (fs.existsSync(gemfilePath)) {
211
+ const content = fs.readFileSync(gemfilePath, 'utf-8');
212
+
213
+ if (content.includes('rails')) {
214
+ return {
215
+ name: 'Ruby on Rails',
216
+ cmd: 'rails',
217
+ args: ['server', '-p', '3000'],
218
+ port: 3000
219
+ };
220
+ }
221
+
222
+ // Sinatra
223
+ if (content.includes('sinatra')) {
224
+ return {
225
+ name: 'Sinatra',
226
+ cmd: 'ruby',
227
+ args: ['app.rb'],
228
+ port: 4567
229
+ };
230
+ }
231
+ }
232
+
233
+ // Rust
234
+ const cargoPath = path.join(projectDir, 'Cargo.toml');
235
+ if (fs.existsSync(cargoPath)) {
236
+ return {
237
+ name: 'Rust (Cargo)',
238
+ cmd: 'cargo',
239
+ args: ['run'],
240
+ port: 8080
241
+ };
242
+ }
243
+
244
+ // PHP - Laravel
245
+ const composerPath = path.join(projectDir, 'composer.json');
246
+ if (fs.existsSync(composerPath)) {
247
+ try {
248
+ const composer = JSON.parse(fs.readFileSync(composerPath, 'utf-8'));
249
+ if (composer.require?.['laravel/framework']) {
250
+ return {
251
+ name: 'Laravel',
252
+ cmd: 'php',
253
+ args: ['artisan', 'serve'],
254
+ port: 8000
255
+ };
256
+ }
257
+ } catch (e) {
258
+ // Continue
259
+ }
260
+ }
261
+
262
+ // Elixir - Phoenix
263
+ const mixPath = path.join(projectDir, 'mix.exs');
264
+ if (fs.existsSync(mixPath)) {
265
+ const content = fs.readFileSync(mixPath, 'utf-8');
266
+ if (content.includes('phoenix')) {
267
+ return {
268
+ name: 'Phoenix',
269
+ cmd: 'mix',
270
+ args: ['phx.server'],
271
+ port: 4000
272
+ };
273
+ }
274
+ }
275
+
276
+ // Deno
277
+ const denoPath = path.join(projectDir, 'deno.json');
278
+ if (fs.existsSync(denoPath)) {
279
+ return {
280
+ name: 'Deno',
281
+ cmd: 'deno',
282
+ args: ['run', '--allow-net', '--allow-read', 'main.ts'],
283
+ port: 8000
284
+ };
285
+ }
286
+
287
+ // Static site (has index.html)
288
+ const indexPath = path.join(projectDir, 'index.html');
289
+ if (fs.existsSync(indexPath)) {
290
+ return {
291
+ name: 'Static Site',
292
+ cmd: 'npx',
293
+ args: ['serve', '-p', '3000'],
294
+ port: 3000
295
+ };
296
+ }
297
+
298
+ return null;
299
+ }
300
+
301
+ module.exports = { detectProject };
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "tlc-server",
3
+ "version": "0.1.0",
4
+ "description": "TLC Development Server - Mini-Replit experience",
5
+ "type": "commonjs",
6
+ "bin": {
7
+ "tlc-server": "./index.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node index.js",
11
+ "dev": "node --watch index.js"
12
+ },
13
+ "dependencies": {
14
+ "chokidar": "^3.5.3",
15
+ "express": "^4.18.2",
16
+ "http-proxy-middleware": "^2.0.6",
17
+ "ws": "^8.14.2"
18
+ }
19
+ }