zugzbot 1.0.8 → 1.0.10
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/.opencode/commands/web.md +8 -10
- package/.utils/zugzweb/client/src/App.tsx +699 -262
- package/.utils/zugzweb/daemon.js +29 -33
- package/bin/init.js +1 -1
- package/package.json +1 -1
package/.utils/zugzweb/daemon.js
CHANGED
|
@@ -165,6 +165,33 @@ const startServer = () => {
|
|
|
165
165
|
return
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
// 3b. Endpoint: Crear carpeta física para un proyecto si no existe (gestión de carpetas locales)
|
|
169
|
+
if (req.url === '/api-custom/create-folder' && req.method === 'POST') {
|
|
170
|
+
let body = ''
|
|
171
|
+
req.on('data', chunk => body += chunk)
|
|
172
|
+
req.on('end', () => {
|
|
173
|
+
try {
|
|
174
|
+
const parsed = JSON.parse(body)
|
|
175
|
+
const targetPath = parsed.path
|
|
176
|
+
if (targetPath && path.isAbsolute(targetPath)) {
|
|
177
|
+
if (!fs.existsSync(targetPath)) {
|
|
178
|
+
fs.mkdirSync(targetPath, { recursive: true })
|
|
179
|
+
console.log(`\x1b[32m%s\x1b[0m`, `📁 Carpeta física creada: ${targetPath}`)
|
|
180
|
+
}
|
|
181
|
+
res.writeHead(200, { 'Content-Type': 'application/json' })
|
|
182
|
+
res.end(JSON.stringify({ success: true, message: `Carpeta lista: ${targetPath}` }))
|
|
183
|
+
} else {
|
|
184
|
+
res.writeHead(400, { 'Content-Type': 'application/json' })
|
|
185
|
+
res.end(JSON.stringify({ error: 'Ruta absoluta inválida o ausente' }))
|
|
186
|
+
}
|
|
187
|
+
} catch (e) {
|
|
188
|
+
res.writeHead(500, { 'Content-Type': 'application/json' })
|
|
189
|
+
res.end(JSON.stringify({ error: 'Error al crear la carpeta', detail: e.message }))
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
|
|
168
195
|
// 4. Proxy inverso para las APIs de Opencode (prefijo /api)
|
|
169
196
|
if (req.url.startsWith('/api/')) {
|
|
170
197
|
const targetPath = req.url.substring(4) // Quita el '/api'
|
|
@@ -183,8 +210,8 @@ const startServer = () => {
|
|
|
183
210
|
await scanInstances()
|
|
184
211
|
console.log('\x1b[33m%s\x1b[0m', `🔌 Proxyando peticiones de la API a Opencode en el puerto ${opencodePort}`)
|
|
185
212
|
|
|
186
|
-
//
|
|
187
|
-
|
|
213
|
+
// El túnel de Cloudflare se ha desactivado para garantizar que el panel web sea 100% local y seguro.
|
|
214
|
+
console.log('\x1b[32m%s\x1b[0m', '🔒 Seguridad: Servidor operando exclusivamente en modo LOCAL (Cloudflare inactivo)')
|
|
188
215
|
})
|
|
189
216
|
}
|
|
190
217
|
|
|
@@ -263,35 +290,4 @@ const serveStatic = (req, res) => {
|
|
|
263
290
|
})
|
|
264
291
|
}
|
|
265
292
|
|
|
266
|
-
const startTunnel = () => {
|
|
267
|
-
console.log('\x1b[35m%s\x1b[0m', '🌐 Abriendo túnel seguro trycloudflare.com...')
|
|
268
|
-
|
|
269
|
-
const cf = spawn('npx', ['-y', 'cloudflared', 'tunnel', '--url', `http://127.0.0.1:${PORT}`])
|
|
270
|
-
|
|
271
|
-
cf.stdout.on('data', (data) => {
|
|
272
|
-
parseCfOutput(data.toString())
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
cf.stderr.on('data', (data) => {
|
|
276
|
-
parseCfOutput(data.toString())
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
cf.on('close', (code) => {
|
|
280
|
-
console.log(`\x1b[31m%s\x1b[0m`, `⚠️ Túnel de Cloudflare finalizado (código: ${code}). Reintentando...`)
|
|
281
|
-
setTimeout(startTunnel, 5000)
|
|
282
|
-
})
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const parseCfOutput = (text) => {
|
|
286
|
-
const match = text.match(/https:\/\/[a-zA-Z0-9-]+\.trycloudflare\.com/)
|
|
287
|
-
if (match && match[0] !== tunnelUrl) {
|
|
288
|
-
tunnelUrl = match[0]
|
|
289
|
-
console.log('\n\x1b[32m%s\x1b[0m', '=========================================================')
|
|
290
|
-
console.log('\x1b[32m%s\x1b[0m', '🚀 ¡CENTRO DE CONTROL REMOTO DISPONIBLE!')
|
|
291
|
-
console.log('\x1b[32m%s\x1b[0m', '📱 Controla tu arnés Opencode desde cualquier lugar en:')
|
|
292
|
-
console.log('\x1b[36m%s\x1b[0m', ` 👉 ${tunnelUrl} 👈`)
|
|
293
|
-
console.log('\x1b[32m%s\x1b[0m', '=========================================================\n')
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
293
|
startServer()
|
package/bin/init.js
CHANGED
|
@@ -25,7 +25,7 @@ ${bold}${cyan}███████╗██╗ ██╗ ██████
|
|
|
25
25
|
███╔╝ ██║ ██║██║ ██║ ███╔╝
|
|
26
26
|
███████╗╚██████╔╝╚██████╔╝███████╗
|
|
27
27
|
╚══════╝ ╚═════╝ ╚═════╝ ╚══════╝${reset}
|
|
28
|
-
${bold}${yellow} Harness Installer v1.0.
|
|
28
|
+
${bold}${yellow} Harness Installer v1.0.10${reset}\n`;
|
|
29
29
|
|
|
30
30
|
console.log(banner);
|
|
31
31
|
console.log(`${bold}${cyan}🔍 Detectando entorno de trabajo...${reset}`);
|