the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add settings pages UI and Tailscale route

+243 -16
+21 -2
apps/web/src/pages/settings/files/Files.tsx
··· 16 16 root={data?.sandbox?.name} 17 17 rootLink={pathname.replace("/files", "")} 18 18 > 19 - {/* Your page content goes here */} 20 - <></> 19 + <> 20 + <div className="w-[95%] m-auto"> 21 + <div className="flex flex-row items-center"> 22 + <h1 className="mb-2 text-xl flex-1">Files</h1> 23 + <button className="btn btn-primary font-semibold">New File</button> 24 + </div> 25 + <p className="opacity-60 mb-5"> 26 + Files (encrypted) that are automatically injected into the sandbox 27 + filesystem. 28 + </p> 29 + <table className="table mb-20"> 30 + <thead> 31 + <tr> 32 + <th className="normal-case text-[14px]">Path</th> 33 + <th className="normal-case text-[14px]"></th> 34 + </tr> 35 + </thead> 36 + <tbody></tbody> 37 + </table> 38 + </div> 39 + </> 21 40 </Main> 22 41 ); 23 42 }
+23 -2
apps/web/src/pages/settings/integrations/Integrations.tsx
··· 16 16 root={data?.sandbox?.name} 17 17 rootLink={pathname.replace("/integrations", "")} 18 18 > 19 - {/* Your page content goes here */} 20 - <></> 19 + <> 20 + <div className="w-[95%] m-auto"> 21 + <div className="flex flex-row items-center"> 22 + <h1 className="mb-1 text-xl flex-1">Integrations</h1> 23 + <button className="btn btn-md btn-primary font-semibold"> 24 + New Webhook 25 + </button> 26 + </div> 27 + <p className="opacity-60 mb-5"> 28 + Integrations are third-party services that you can connect to your 29 + sandbox by adding a webhook. 30 + </p> 31 + <table className="table mb-20"> 32 + <thead> 33 + <tr> 34 + <th className="normal-case text-[14px]">Name</th> 35 + <th className="normal-case text-[14px]"></th> 36 + </tr> 37 + </thead> 38 + <tbody></tbody> 39 + </table> 40 + </div> 41 + </> 21 42 </Main> 22 43 ); 23 44 }
+33 -2
apps/web/src/pages/settings/repository/Repository.tsx
··· 9 9 const { data } = useSandboxQuery( 10 10 `at:/${pathname.replace("/repository", "").replace("sandbox", "io.pocketenv.sandbox")}`, 11 11 ); 12 + const index = Math.floor(Math.random() * 7); 12 13 13 14 return ( 14 15 <Main ··· 16 17 root={data?.sandbox?.name} 17 18 rootLink={pathname.replace("/repository", "")} 18 19 > 19 - {/* Your page content goes here */} 20 - <></> 20 + <> 21 + <div className="w-[95%] m-auto"> 22 + <h1 className="text-lg">Git Repository</h1> 23 + <p className="opacity-60 mt-1"> 24 + Bring your project's Git repository into your Sandbox. 25 + </p> 26 + <div className="input input-bordered w-xl input-lg text-[15px] font-semibold bg-transparent mt-5"> 27 + <input 28 + type="text" 29 + className={`grow`} 30 + placeholder={`e.g. ${ 31 + [ 32 + "https://tangled.org/tranquil.farm/tranquil-pds", 33 + "https://tangled.org/rocksky.app/rocksky", 34 + "https://tangled.org/pocketenv.io/pocketenv", 35 + "https://tangled.org/zat.dev/zat", 36 + "https://tangled.org/pds.ls/pdsls", 37 + "https://tangled.org/teal.fm/piper", 38 + "https://tangled.org/tangled.org/core", 39 + ][index] 40 + }`} 41 + autoComplete="off" 42 + data-1p-ignore 43 + data-lpignore="true" 44 + data-form-type="other" 45 + /> 46 + </div> 47 + <div className="mt-8"> 48 + <button className="btn btn-primary w-25 font-semibold">Save</button> 49 + </div> 50 + </div> 51 + </> 21 52 </Main> 22 53 ); 23 54 }
+23 -2
apps/web/src/pages/settings/secrets/Secrets.tsx
··· 16 16 root={data?.sandbox?.name} 17 17 rootLink={pathname.replace("/secrets", "")} 18 18 > 19 - {/* Your page content goes here */} 20 - <></> 19 + <> 20 + <div className="w-[95%] m-auto"> 21 + <div className="flex flex-row items-center"> 22 + <h1 className="mb-2 text-xl flex-1">Secrets</h1> 23 + <button className="btn btn-primary font-semibold"> 24 + New Secret 25 + </button> 26 + </div> 27 + <p className="opacity-60 mb-5"> 28 + Sensitive environment variables (API keys, tokens, credentials) 29 + stored securely. 30 + </p> 31 + <table className="table mb-20"> 32 + <thead> 33 + <tr> 34 + <th className="normal-case text-[14px]">Name</th> 35 + <th className="normal-case text-[14px]"></th> 36 + </tr> 37 + </thead> 38 + <tbody></tbody> 39 + </table> 40 + </div> 41 + </> 21 42 </Main> 22 43 ); 23 44 }
+18 -2
apps/web/src/pages/settings/sidebar/Sidebar.tsx
··· 65 65 title={isCollapsed ? "General" : undefined} 66 66 > 67 67 <span 68 - className={`icon-[pepicons-pencil--file] size-6 ${isCollapsed ? "" : "mr-2"}`} 68 + className={`icon-[codicon--settings] size-6 ${isCollapsed ? "" : "mr-2"}`} 69 69 ></span> 70 70 {!isCollapsed && "General"} 71 71 </Link> ··· 161 161 title={isCollapsed ? "Volumes" : undefined} 162 162 > 163 163 <span 164 - className={`icon-[icon-park-outline--hard-disk] size-5 ${isCollapsed ? "" : "mr-2"}`} 164 + className={`icon-[icon-park-outline--hard-disk] size-5 ${isCollapsed ? "" : "mr-2 ml-1"}`} 165 165 ></span> 166 166 {!isCollapsed && "Volumes"} 167 167 </Link> ··· 180 180 className={`icon-[tabler--key] size-6 ${isCollapsed ? "" : "mr-2"}`} 181 181 ></span> 182 182 {!isCollapsed && "SSH Keys"} 183 + </Link> 184 + </li> 185 + <li> 186 + <Link 187 + to={`/${did}/sandbox/${rkey}/tailscale`} 188 + className={`${ 189 + isActive("/tailscale") 190 + ? "active bg-white/7 text-[#00e8c6]! font-semibold rounded-full" 191 + : "rounded-full hover:text-white" 192 + } ${isCollapsed ? "justify-center px-2" : ""}`} 193 + title={isCollapsed ? "Tailscale" : undefined} 194 + > 195 + <span 196 + className={`icon-[simple-icons--tailscale] size-4 ${isCollapsed ? "" : "mr-3 ml-1"}`} 197 + ></span> 198 + {!isCollapsed && "Tailscale"} 183 199 </Link> 184 200 </li> 185 201 </ul>
+13 -2
apps/web/src/pages/settings/sshkeys/SshKeys.tsx
··· 16 16 root={data?.sandbox?.name} 17 17 rootLink={pathname.replace("/ssh-keys", "")} 18 18 > 19 - {/* Your page content goes here */} 20 - <></> 19 + <> 20 + <div className="w-[95%] m-auto"> 21 + <div className="flex flex-row items-center"> 22 + <h1 className="mb-2 text-xl flex-1">SSH Keys</h1> 23 + <button className="btn btn-primary w-25 font-semibold"> 24 + Generate 25 + </button> 26 + </div> 27 + <p className="opacity-60 mb-5"> 28 + SSH keys used to securely access Git repositories or remote servers. 29 + </p> 30 + </div> 31 + </> 21 32 </Main> 22 33 ); 23 34 }
+35
apps/web/src/pages/settings/tailscale/Tailscale.tsx
··· 1 + import { useRouterState } from "@tanstack/react-router"; 2 + import { useSandboxQuery } from "../../../hooks/useSandbox"; 3 + import Main from "../../../layouts/Main"; 4 + import Sidebar from "../sidebar/Sidebar"; 5 + 6 + function Tailscale() { 7 + const routerState = useRouterState(); 8 + const pathname = routerState.location.pathname; 9 + const { data } = useSandboxQuery( 10 + `at:/${pathname.replace("/ssh-keys", "").replace("sandbox", "io.pocketenv.sandbox")}`, 11 + ); 12 + 13 + return ( 14 + <Main 15 + sidebar={<Sidebar />} 16 + root={data?.sandbox?.name} 17 + rootLink={pathname.replace("/tailscale", "")} 18 + > 19 + <> 20 + <div className="w-[95%] m-auto"> 21 + <div className="flex flex-row items-center"> 22 + <h1 className="mb-2 text-xl flex-1">Tailscale</h1> 23 + <button className="btn btn-primary font-semibold">Add Token</button> 24 + </div> 25 + <p className="opacity-60 mb-5"> 26 + Connect your Sandbox to your Tailscale network for secure private 27 + access to services and devices. 28 + </p> 29 + </div> 30 + </> 31 + </Main> 32 + ); 33 + } 34 + 35 + export default Tailscale;
+3
apps/web/src/pages/settings/tailscale/index.tsx
··· 1 + import Tailscale from "./Tailscale"; 2 + 3 + export default Tailscale;
+23 -2
apps/web/src/pages/settings/variables/Variables.tsx
··· 16 16 root={data?.sandbox?.name} 17 17 rootLink={pathname.replace("/variables", "")} 18 18 > 19 - {/* Your page content goes here */} 20 - <></> 19 + <> 20 + <div className="w-[95%] m-auto"> 21 + <div className="flex flex-row items-center"> 22 + <h1 className="mb-2 text-xl flex-1">Variables</h1> 23 + <button className="btn btn-primary font-semibold"> 24 + New Variable 25 + </button> 26 + </div> 27 + <p className="opacity-60 mb-5"> 28 + Environment variables available to your sandbox during execution. 29 + </p> 30 + <table className="table mb-20"> 31 + <thead> 32 + <tr> 33 + <th className="normal-case text-[14px]">Name</th> 34 + <th className="normal-case text-[14px]">Value</th> 35 + <th className="normal-case text-[14px]"></th> 36 + </tr> 37 + </thead> 38 + <tbody></tbody> 39 + </table> 40 + </div> 41 + </> 21 42 </Main> 22 43 ); 23 44 }
+24 -2
apps/web/src/pages/settings/volumes/Volumes.tsx
··· 16 16 root={data?.sandbox?.name} 17 17 rootLink={pathname.replace("/files", "")} 18 18 > 19 - {/* Your page content goes here */} 20 - <></> 19 + <> 20 + <div className="w-[95%] m-auto"> 21 + <div className="flex flex-row items-center"> 22 + <h1 className="mb-2 text-xl flex-1">Volumes</h1> 23 + <button className="btn btn-primary font-semibold"> 24 + New Volume 25 + </button> 26 + </div> 27 + <p className="opacity-60 mb-5"> 28 + Persistent storage mounted into the sandbox to keep data between 29 + sessions. 30 + </p> 31 + <table className="table mb-20"> 32 + <thead> 33 + <tr> 34 + <th className="normal-case text-[14px]">Name</th> 35 + <th className="normal-case text-[14px]">Mount Path</th> 36 + <th className="normal-case text-[14px]"></th> 37 + </tr> 38 + </thead> 39 + <tbody></tbody> 40 + </table> 41 + </div> 42 + </> 21 43 </Main> 22 44 ); 23 45 }
+21
apps/web/src/routeTree.gen.ts
··· 21 21 import { Route as DidSandboxRkeyIndexRouteImport } from './routes/$did.sandbox.$rkey/index' 22 22 import { Route as DidSandboxRkeyVolumesRouteImport } from './routes/$did.sandbox.$rkey/volumes' 23 23 import { Route as DidSandboxRkeyVariablesRouteImport } from './routes/$did.sandbox.$rkey/variables' 24 + import { Route as DidSandboxRkeyTailscaleRouteImport } from './routes/$did.sandbox.$rkey/tailscale' 24 25 import { Route as DidSandboxRkeySshKeysRouteImport } from './routes/$did.sandbox.$rkey/ssh-keys' 25 26 import { Route as DidSandboxRkeySettingsRouteImport } from './routes/$did.sandbox.$rkey/settings' 26 27 import { Route as DidSandboxRkeySecretsRouteImport } from './routes/$did.sandbox.$rkey/secrets' ··· 86 87 const DidSandboxRkeyVariablesRoute = DidSandboxRkeyVariablesRouteImport.update({ 87 88 id: '/variables', 88 89 path: '/variables', 90 + getParentRoute: () => DidSandboxRkeyRoute, 91 + } as any) 92 + const DidSandboxRkeyTailscaleRoute = DidSandboxRkeyTailscaleRouteImport.update({ 93 + id: '/tailscale', 94 + path: '/tailscale', 89 95 getParentRoute: () => DidSandboxRkeyRoute, 90 96 } as any) 91 97 const DidSandboxRkeySshKeysRoute = DidSandboxRkeySshKeysRouteImport.update({ ··· 137 143 '/$did/sandbox/$rkey/secrets': typeof DidSandboxRkeySecretsRoute 138 144 '/$did/sandbox/$rkey/settings': typeof DidSandboxRkeySettingsRoute 139 145 '/$did/sandbox/$rkey/ssh-keys': typeof DidSandboxRkeySshKeysRoute 146 + '/$did/sandbox/$rkey/tailscale': typeof DidSandboxRkeyTailscaleRoute 140 147 '/$did/sandbox/$rkey/variables': typeof DidSandboxRkeyVariablesRoute 141 148 '/$did/sandbox/$rkey/volumes': typeof DidSandboxRkeyVolumesRoute 142 149 '/$did/sandbox/$rkey/': typeof DidSandboxRkeyIndexRoute ··· 156 163 '/$did/sandbox/$rkey/secrets': typeof DidSandboxRkeySecretsRoute 157 164 '/$did/sandbox/$rkey/settings': typeof DidSandboxRkeySettingsRoute 158 165 '/$did/sandbox/$rkey/ssh-keys': typeof DidSandboxRkeySshKeysRoute 166 + '/$did/sandbox/$rkey/tailscale': typeof DidSandboxRkeyTailscaleRoute 159 167 '/$did/sandbox/$rkey/variables': typeof DidSandboxRkeyVariablesRoute 160 168 '/$did/sandbox/$rkey/volumes': typeof DidSandboxRkeyVolumesRoute 161 169 '/$did/sandbox/$rkey': typeof DidSandboxRkeyIndexRoute ··· 177 185 '/$did/sandbox/$rkey/secrets': typeof DidSandboxRkeySecretsRoute 178 186 '/$did/sandbox/$rkey/settings': typeof DidSandboxRkeySettingsRoute 179 187 '/$did/sandbox/$rkey/ssh-keys': typeof DidSandboxRkeySshKeysRoute 188 + '/$did/sandbox/$rkey/tailscale': typeof DidSandboxRkeyTailscaleRoute 180 189 '/$did/sandbox/$rkey/variables': typeof DidSandboxRkeyVariablesRoute 181 190 '/$did/sandbox/$rkey/volumes': typeof DidSandboxRkeyVolumesRoute 182 191 '/$did/sandbox/$rkey/': typeof DidSandboxRkeyIndexRoute ··· 199 208 | '/$did/sandbox/$rkey/secrets' 200 209 | '/$did/sandbox/$rkey/settings' 201 210 | '/$did/sandbox/$rkey/ssh-keys' 211 + | '/$did/sandbox/$rkey/tailscale' 202 212 | '/$did/sandbox/$rkey/variables' 203 213 | '/$did/sandbox/$rkey/volumes' 204 214 | '/$did/sandbox/$rkey/' ··· 218 228 | '/$did/sandbox/$rkey/secrets' 219 229 | '/$did/sandbox/$rkey/settings' 220 230 | '/$did/sandbox/$rkey/ssh-keys' 231 + | '/$did/sandbox/$rkey/tailscale' 221 232 | '/$did/sandbox/$rkey/variables' 222 233 | '/$did/sandbox/$rkey/volumes' 223 234 | '/$did/sandbox/$rkey' ··· 238 249 | '/$did/sandbox/$rkey/secrets' 239 250 | '/$did/sandbox/$rkey/settings' 240 251 | '/$did/sandbox/$rkey/ssh-keys' 252 + | '/$did/sandbox/$rkey/tailscale' 241 253 | '/$did/sandbox/$rkey/variables' 242 254 | '/$did/sandbox/$rkey/volumes' 243 255 | '/$did/sandbox/$rkey/' ··· 341 353 preLoaderRoute: typeof DidSandboxRkeyVariablesRouteImport 342 354 parentRoute: typeof DidSandboxRkeyRoute 343 355 } 356 + '/$did/sandbox/$rkey/tailscale': { 357 + id: '/$did/sandbox/$rkey/tailscale' 358 + path: '/tailscale' 359 + fullPath: '/$did/sandbox/$rkey/tailscale' 360 + preLoaderRoute: typeof DidSandboxRkeyTailscaleRouteImport 361 + parentRoute: typeof DidSandboxRkeyRoute 362 + } 344 363 '/$did/sandbox/$rkey/ssh-keys': { 345 364 id: '/$did/sandbox/$rkey/ssh-keys' 346 365 path: '/ssh-keys' ··· 393 412 DidSandboxRkeySecretsRoute: typeof DidSandboxRkeySecretsRoute 394 413 DidSandboxRkeySettingsRoute: typeof DidSandboxRkeySettingsRoute 395 414 DidSandboxRkeySshKeysRoute: typeof DidSandboxRkeySshKeysRoute 415 + DidSandboxRkeyTailscaleRoute: typeof DidSandboxRkeyTailscaleRoute 396 416 DidSandboxRkeyVariablesRoute: typeof DidSandboxRkeyVariablesRoute 397 417 DidSandboxRkeyVolumesRoute: typeof DidSandboxRkeyVolumesRoute 398 418 DidSandboxRkeyIndexRoute: typeof DidSandboxRkeyIndexRoute ··· 405 425 DidSandboxRkeySecretsRoute: DidSandboxRkeySecretsRoute, 406 426 DidSandboxRkeySettingsRoute: DidSandboxRkeySettingsRoute, 407 427 DidSandboxRkeySshKeysRoute: DidSandboxRkeySshKeysRoute, 428 + DidSandboxRkeyTailscaleRoute: DidSandboxRkeyTailscaleRoute, 408 429 DidSandboxRkeyVariablesRoute: DidSandboxRkeyVariablesRoute, 409 430 DidSandboxRkeyVolumesRoute: DidSandboxRkeyVolumesRoute, 410 431 DidSandboxRkeyIndexRoute: DidSandboxRkeyIndexRoute,
+6
apps/web/src/routes/$did.sandbox.$rkey/tailscale.tsx
··· 1 + import { createFileRoute } from "@tanstack/react-router"; 2 + import TailscalePage from "../../pages/settings/tailscale"; 3 + 4 + export const Route = createFileRoute("/$did/sandbox/$rkey/tailscale")({ 5 + component: TailscalePage, 6 + });