FROM node:22-slim # 1. Install system utilities required for git operations RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* # 2. Configure directory structure with correct permission scopes for Hugging Face (User 1000) WORKDIR /appw RUN mkdir -p /appw/server/workspaces /appw/server/public && chown -R 1000:1000 /appw # Switch to the non-root node user USER 1000 # 3. Clone repository to a temporary directory, merge files into the active workdir, and run npm install RUN git clone https://github.com/Electroiscoding/Swades-Agent.git /tmp/swades \ && cp -r /tmp/swades/. /appw/ \ && rm -rf /tmp/swades \ && npm install # 4. Write the Backend Broker RUN cat << 'EOF' > server/index.js const express = require("express"); const { spawn, execSync } = require("child_process"); const http = require("http"); const WebSocket = require("ws"); const path = require("path"); const fs = require("fs"); const app = express(); const server = http.createServer(app); const wss = new WebSocket.Server({ server }); const PORT = process.env.PORT || 7860; const WORKSPACE_BASE = path.join(__dirname, "workspaces"); const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID || ""; const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET || ""; const activeWebsocketPool = new Map(); if (!fs.existsSync(WORKSPACE_BASE)) { fs.mkdirSync(WORKSPACE_BASE, { recursive: true }); } app.use(express.static(path.join(__dirname, "public"))); app.get("/login/github", (req, res) => { const { socketId } = req.query; if (!socketId) return res.send("Active channel window connection identifier tracking key missing."); res.redirect(`https://github.com/login/oauth/authorize?client_id=${GITHUB_CLIENT_ID}&scope=repo&state=${socketId}`); }); app.get("/callback", async (req, res) => { const { code, state } = req.query; if (!code || !state) return res.send("Authorization metadata parameters corrupted."); try { const response = await fetch("https://github.com/login/oauth/access_token", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify({ client_id: GITHUB_CLIENT_ID, client_secret: GITHUB_CLIENT_SECRET, code }) }); const data = await response.json(); const token = data.access_token; const userRes = await fetch("https://api.github.com/user", { headers: { "Authorization": `token ${token}`, "User-Agent": "Swades-Orchestrator" } }); const userData = await userRes.json(); const reposRes = await fetch("https://api.github.com/user/repos?per_page=100&sort=updated", { headers: { "Authorization": `token ${token}`, "User-Agent": "Swades-Orchestrator" } }); const reposData = await reposRes.json(); const formattedRepos = Array.isArray(reposData) ? reposData.map(r => ({ name: r.full_name, url: r.clone_url })) : []; const clientSocket = activeWebsocketPool.get(state); if (clientSocket && clientSocket.readyState === WebSocket.OPEN) { clientSocket.send(JSON.stringify({ type: "AUTH_COMPLETE", token: token, username: userData.login, avatar: userData.avatar_url, repos: formattedRepos })); } res.send(` Identity authenticated. Syncing dashboard... `); } catch (err) { res.status(500).send("Handshake Sync breakdown: " + err.message); } }); wss.on("connection", (ws) => { let boundSocketId = null; let agentProcess = null; ws.on("message", async (message) => { try { const payload = JSON.parse(message); if (payload.type === "register_channel") { boundSocketId = payload.socketId; activeWebsocketPool.set(boundSocketId, ws); return; } if (payload.type === "hydrate_repos") { try { const reposRes = await fetch("https://api.github.com/user/repos?per_page=100&sort=updated", { headers: { "Authorization": `token ${payload.token}`, "User-Agent": "Swades-Orchestrator" } }); const reposData = await reposRes.json(); const formattedRepos = Array.isArray(reposData) ? reposData.map(r => ({ name: r.full_name, url: r.clone_url })) : []; ws.send(JSON.stringify({ type: "REPO_HYDRATION_COMPLETE", repos: formattedRepos })); } catch (e) { ws.send(JSON.stringify({ type: "system", data: "⚠️ Session validation expired. Please re-authenticate." })); } return; } if (payload.type === "run") { if (agentProcess) { return ws.send(JSON.stringify({ type: "system", data: "[Busy] Thread execution lock active." })); } const { task, autonomous, userApiKey, userModel, repoUrl, githubToken } = payload; if (!userApiKey || !repoUrl || !githubToken) { return ws.send(JSON.stringify({ type: "system", data: "❌ Setup Error: Verification attributes empty." })); } const sessionID = "session_" + Date.now(); const userWorkspace = path.join(WORKSPACE_BASE, sessionID); ws.send(JSON.stringify({ type: "system", data: "⏳ Provisioning clean workspace sandbox container nodes..." })); try { const cleanRepo = repoUrl.trim().replace(/^https?:\/\//, ""); const authenticatedRepoUrl = `https://x-access-token:${githubToken}@${cleanRepo}`; execSync(`git clone ${authenticatedRepoUrl} ${userWorkspace}`, { stdio: "ignore" }); execSync(`git remote set-url origin ${authenticatedRepoUrl}`, { cwd: userWorkspace }); ws.send(JSON.stringify({ type: "system", data: "🧠 Activating Swades context engine layer..." })); const args = [path.join(__dirname, "../src/index.js"), task]; if (autonomous) args.push("--autonomous"); agentProcess = spawn("node", args, { cwd: path.join(__dirname, ".."), env: { ...process.env, API_KEY: userApiKey, BASE_URL: "https://openrouter.ai/api/v1", MODEL: userModel || "openrouter/free", WORKDIR: userWorkspace } }); agentProcess.stdout.on("data", (data) => { ws.send(JSON.stringify({ type: "output", data: data.toString() })); }); agentProcess.stderr.on("data", (data) => { ws.send(JSON.stringify({ type: "output", data: data.toString() })); }); agentProcess.on("close", (code) => { agentProcess = null; ws.send(JSON.stringify({ type: "system", data: "🏁 Task sequence terminated. Evaluating modification tree..." })); try { const statusCheck = execSync(`git status --porcelain`, { cwd: userWorkspace }).toString().trim(); if (!statusCheck) { ws.send(JSON.stringify({ type: "system", data: "ℹ No changes detected. Tree matches origin exactly. Skipping branch creation." })); return; } const branchName = `swades-patch-${Math.floor(1000 + Math.random() * 9000)}`; execSync(`git checkout -b ${branchName}`, { cwd: userWorkspace, stdio: "ignore" }); execSync(`git config --local user.email "agent@swades.ai" && git config --local user.name "Swades Agent Hub"`, { cwd: userWorkspace }); execSync(`git add . && git commit -m "feat: automated engineering updates via Swades ReAct core loop"`, { cwd: userWorkspace }); execSync(`git push origin ${branchName}`, { cwd: userWorkspace }); const cleanRepoWebPath = repoUrl.replace(/\.git$/, "").replace(/\/$/, ""); const prUrl = `${cleanRepoWebPath}/tree/${branchName}`; ws.send(JSON.stringify({ type: "success_link", data: `\x1b[32m✔ Engineering adjustments published upstream!\x1b[0m`, link: prUrl })); } catch (gitErr) { ws.send(JSON.stringify({ type: "system", data: `❌ Workspace synchronization failed: ${gitErr.message}` })); } }); } catch (setupErr) { ws.send(JSON.stringify({ type: "system", data: `❌ Workspace Initialization Failure: ${setupErr.message}` })); } } if (payload.type === "input" && agentProcess) { agentProcess.stdin.write(payload.data); } } catch (e) { ws.send(JSON.stringify({ type: "system", data: e.message })); } }); ws.on("close", () => { if (agentProcess) agentProcess.kill(); if (boundSocketId) activeWebsocketPool.delete(boundSocketId); }); }); server.listen(PORT, "0.0.0.0", () => console.log("System Online")); EOF # 5. Write the Premium Silicon Valley Chat Interface Layout with Infinite Session Persistence RUN cat << 'EOF' > server/public/index.html