CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

SkyCode is a multi-tenant browser-based code editor built with Skykit. It provides a VS Code-like experience with Monaco Editor for code editing and xterm.js for an integrated PTY terminal with real-time command execution via WebSocket.

Development Commands

# Run locally
go run .

# Build
go build -o skycode .

# Run with Docker
docker build -t skycode .
docker run -p 5000:5000 skycode

Architecture

Project Structure

skycode/
├── main.go                 # Application entry point, public file serving
├── controllers/
│   ├── code.go             # File CRUD, git operations, editor UI
│   ├── terminal.go         # SSE command execution (legacy)
│   ├── ws.go               # WebSocket PTY terminal (primary)
│   └── admin.go            # Admin user management
├── models/
│   ├── database.go         # Database connection
│   ├── file.go             # File model and operations
│   ├── project.go          # Project model (cloned repos, workspaces)
│   └── session.go          # Workspace session management
└── views/
    ├── home.html           # Landing page (Vercel-inspired design)
    ├── editor.html         # Monaco + xterm.js editor (loads external scripts)
    ├── admin.html          # Admin dashboard
    └── public/
        ├── scripts/        # Frontend JavaScript modules
        │   ├── main.js     # Global state, settings, Monaco init
        │   ├── terminal.js # PTY terminal multiplexing, resize
        │   ├── files.js    # File operations, tabs, file tree
        │   ├── git.js      # Git operations, project management
        │   └── search.js   # Code search functionality
        └── styles/         # CSS stylesheets
            └── home.css    # Homepage styles (grid bg, animations)

Core Concepts

Concept Location Purpose
File Database Source of truth for all user files
Project Database Tracks cloned repos with RemoteURL for restoration
Session In-memory Ephemeral workspace, 30-min timeout
Workspace Filesystem /tmp/skycode/{sessionID}/workspace/
Tool Directory Filesystem /tmp/skycode/users/{userID}/ (persists tool installs)

Route Handlers

Editor & Files:

Route Method Handler Purpose
/ GET home.html Landing page
/editor GET editor.html Code editor (requires auth)
/api/files GET listFiles List user's files
/api/files/open GET openFile Get file content
/api/files/save POST saveFile Save file content
/api/files/rename POST renameFile Rename a file
/api/files DELETE deleteFile Delete a file
/api/projects GET listProjects List user's projects

Git Operations:

Route Method Handler Purpose
/api/workspace/clone POST cloneRepo Clone a git repository
/api/git/status GET gitStatus Get git status for project
/api/git/stage POST gitStage Stage files
/api/git/commit POST gitCommit Create commit
/api/git/push POST gitPush Push to remote
/api/git/pull POST gitPull Pull from remote
/api/git/checkout POST gitCheckout Checkout branch
/clone GET handleClone Public clone endpoint (OAuth flow)

Terminal:

Route Method Handler Purpose
/api/terminal WebSocket handleTerminalWS PTY terminal (primary)
/api/terminals GET listTerminals List active terminals
/api/terminals POST createTerminal Create new terminal
/api/terminals/{id} DELETE deleteTerminal Close terminal
/api/exec POST execCommand SSE command execution (legacy)

Models

File - User's code files stored in database:

type File struct {
    skykit.Model
    OwnerID  string  // User ID
    Path     string  // e.g., "project/main.go" or "src/utils.go"
    Content  string
    Language string  // Detected from extension
}

Project - Tracks cloned repositories and workspaces:

type Project struct {
    skykit.Model
    OwnerID   string  // User ID
    Name      string  // Display name
    Path      string  // Directory name in workspace
    RemoteURL string  // Git remote URL (for re-cloning on restore)
    IsDefault bool    // If true, this is the default project
}

Session - Ephemeral workspace for terminal execution:

type Session struct {
    ID          string
    UserID      string
    WorkDir     string    // /tmp/skycode/{sessionID}/workspace
    CreatedAt   time.Time
    LastUsed    time.Time
    initialized int32     // atomic flag
}

Workspace Architecture

Data Flow:

Database (source of truth)
    ↓ MaterializeFiles()
Workspace (ephemeral filesystem)
    ↓ Terminal/Git operations
Workspace modifications
    ↓ SyncWorkspaceToDB()
Database (updated)

Session Lifecycle:

  1. User accesses editor → Session created with unique ID (cookie)
  2. MaterializeFiles() called:
    • Projects with RemoteURL are re-cloned (restores .git directory)
    • Files from DB overlaid (local modifications preserved)
  3. Terminal commands execute in workspace
  4. File saves update both DB and workspace
  5. Session expires after 30 minutes of inactivity → workspace cleaned up

Why Re-clone? The .git directory is not stored in the database (too large, binary data). When a session expires and restores, we re-clone repos with RemoteURL to restore full git functionality, then overlay any local file modifications from the database.

Terminal Architecture

PTY Terminal (Primary) - controllers/ws.go:

  • WebSocket connection at /ws/terminal
  • True PTY via github.com/creack/pty
  • Full shell experience (bash, interactive commands)
  • Multiple terminals per session (max 5)

SSE Terminal (Legacy) - controllers/terminal.go:

  • POST to /api/exec
  • Server-Sent Events streaming
  • Single command execution with timeout
  • Kept for API compatibility

Environment Configuration

Both terminals configure identical environments:

cmd.Env = append(os.Environ(),
    "HOME="+workDir,           // Workspace is home (~ works correctly)
    "PATH="+userPath,          // Includes user tool directories
    "NPM_CONFIG_PREFIX="+...,  // npm global installs persist
    "GOPATH="+...,             // Go installs persist
    "CARGO_HOME="+...,         // Rust installs persist
)

Directory Structure:

/tmp/skycode/
├── {sessionID}/
│   └── workspace/         # User's workspace (HOME)
│       ├── project1/      # Cloned repo
│       └── project2/      # Another project
├── users/
│   └── {userID}/          # Tool directory (persists across sessions)
│       ├── .local/bin/
│       ├── .npm-global/
│       ├── go/
│       └── .cargo/
└── cache/                 # Shared cache
    ├── npm/
    └── go/mod/

Frontend Components

JavaScript Modules

Scripts are served from /public/scripts/ (embedded in binary):

File Purpose
main.js Global state, user settings, Monaco editor initialization
terminal.js Terminal multiplexing, resize handling, show/hide toggle
files.js File tree, tabs, open/save/rename/delete operations
git.js Git status, staging, commit, push, pull, clone modal
search.js Code search with regex support, result navigation

CSS Stylesheets

Styles are served from /public/styles/ (embedded in binary):

File Purpose
home.css Homepage styles: grid background pattern, gradient borders, terminal mockup, feature card hover effects, animations (pulse, blink cursor)

Monaco Editor

  • Version: monaco-editor@0.52.0 (CDN)
  • Theme: Synced with DaisyUI theme (light/dark detection)
  • Features: Syntax highlighting, multi-file tabs, Ctrl+S save
  • Language detection from file extension

xterm.js Terminal

  • Version: xterm@5.3.0 (CDN)
  • Addons: fit (auto-resize)
  • WebSocket connection to PTY backend
  • Multiple terminals per session (tabs)
  • Resizable panel with drag handle
  • Keyboard shortcut: Ctrl+` to toggle

UI Components (DaisyUI 5)

  • File tree with project grouping
  • Context menus for file operations
  • Git sidebar with status, staging, commit
  • Clone modal for adding repositories
  • Settings modal for theme, font size, tab size, word wrap, minimap

Environment Variables

Variable Required Description
PORT No Server port (default: 5000)
DB_NAME For replica Database name
DB_URL For replica LibSQL primary URL
DB_TOKEN For replica Database JWT token

Security Architecture

Authentication

  • All editor/API routes require authentication via Skykit
  • Session cookies for workspace association
  • Files isolated per user (OwnerID filter on all queries)

Workspace Isolation

  • Each user gets isolated workspace directory
  • Sessions are user-bound (validated on access)
  • Path traversal prevented via safePath() validation

Git Security

  • Git URLs validated: isValidGitURL() checks protocol and shell safety
  • Git refs validated: isValidGitRef() prevents command injection
  • Only HTTPS, HTTP, and git:// protocols allowed

Terminal Security

  • Commands run in isolated workspace
  • 60-second timeout prevents runaway processes
  • PTY sessions limited to 5 per user
  • Future: Add sandboxing (nsjail/firejail) for production

Rate Limiting

  • Authentication handled by Skykit with built-in rate limiting
  • Terminal sessions limited per user

Git Operations

Clone Flow

  1. Validate URL (protocol, shell safety)
  2. Create project record with RemoteURL
  3. Run git clone --depth 1 --branch main --single-branch (shallow clone)
    • Falls back to default branch if main doesn't exist
  4. Configure git user (email, name)
  5. Sync files to database
  6. UI selects new project

Session Restore Flow

  1. Get projects with RemoteURL
  2. Re-clone each with --branch main --single-branch to restore .git
  3. Overlay files from database (preserves local modifications)
  4. Git operations work normally (pull/push/commit)

Docker Configuration

The Dockerfile includes development tools:

  • Go 1.24
  • Python 3
  • Node.js/npm
  • git, curl, make, vim

Best Practices (Inspired by code-server)

  1. Never expose without auth - Terminal access = machine access
  2. Use WebSocket for terminals - Real-time, bidirectional
  3. Persist tool installs - Separate from ephemeral workspace
  4. Database as source of truth - Filesystem is ephemeral
  5. Re-clone for git - Don't store .git in database
  6. Validate all git inputs - Prevent command injection
  7. Timeout all operations - Prevent resource exhaustion
7e2ccdf

Update skykit to fix database replica corruption

Connor McCutcheon
@connor
1 stars

Coding tools for The Skyscape

Sign in to comment Sign In
Awesome app everyone should try for building their ideas on The Skyscape
Connor McCutcheon
@connor
1 month ago