This repository has been archived on 2026-07-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
codespace/README.md
T
2026-07-02 17:46:04 +08:00

162 lines
4.8 KiB
Markdown

# codespace
A Go backend skeleton for managing local workspaces and file operations with process orchestration.
## V1 scope
- Workspace creation, listing, lookup, and deletion backed by local directories.
- File read/write/list/mkdir/remove/rename/stat through a `FileSystem` interface with path-escape protection.
- Workspace root deletion protection — cannot remove the workspace root directory through the file API.
- Configurable per-file write size limit — oversized writes are rejected early before hitting disk.
- OpenCode process start/stop/restart/status per workspace.
- HTTP API using [Gin](https://github.com/gin-gonic/gin) for routing with JSON responses.
- Explicit `http.Server` composition with configurable timeouts and max header bytes.
- Structured logging using Go standard library `log/slog` with JSON/text format and level control.
### Safety
- File paths are workspace-relative; absolute paths are rejected.
- `..` escape attempts are rejected before filesystem operations.
- Deleting the workspace root through the file API is explicitly blocked.
- File content is never logged; structured logging only includes metadata.
- Workspace root paths are not exposed in API responses or logs.
## Run
```sh
make run
```
The server listens on `:8080` by default.
## Configuration
`configs/config.yaml`:
```yaml
server:
addr: ":8080"
readTimeout: "15s"
writeTimeout: "15s"
idleTimeout: "60s"
maxHeaderBytes: 1048576
workspace:
root: "./workspaces"
process:
opencodeCommand: "opencode"
file:
maxWriteBytes: 1048576
gin:
mode: "release"
log:
level: "info"
format: "json"
```
### Environment overrides
| Variable | Description | Default |
|---|---|---|
| `CODESPACE_ADDR` | Listen address | `:8080` |
| `CODESPACE_WORKSPACE_ROOT` | Workspace storage root | `./workspaces` |
| `CODESPACE_OPENCODE_COMMAND` | OpenCode binary path | `opencode` |
| `CODESPACE_FILE_MAX_WRITE_BYTES` | Max bytes per file write | `1048576` |
| `CODESPACE_GIN_MODE` | Gin mode (`debug`, `release`, `test`) | `release` |
| `CODESPACE_READ_TIMEOUT` | HTTP read timeout | `15s` |
| `CODESPACE_WRITE_TIMEOUT` | HTTP write timeout | `15s` |
| `CODESPACE_IDLE_TIMEOUT` | HTTP idle timeout | `60s` |
| `CODESPACE_MAX_HEADER_BYTES` | Max HTTP header bytes | `1048576` |
| `CODESPACE_LOG_LEVEL` | Log level (`debug`, `info`, `warn`, `error`) | `info` |
| `CODESPACE_LOG_FORMAT` | Log format (`json`, `text`) | `json` |
## Logging
codespace uses the Go standard library `log/slog` for application logs.
All runtime logging uses slog; `fmt`, `log.Printf`, and the Gin default logger are not used.
## API
### Workspaces
| Method | Path | Description |
|---|---|---|
| `GET` | `/api/workspaces` | List all workspaces |
| `POST` | `/api/workspaces` | Create a workspace (`{"id": "name"}`) |
| `GET` | `/api/workspaces/:id` | Get workspace by ID |
| `DELETE` | `/api/workspaces/:id` | Delete workspace (stops running process first) |
### Files
| Method | Path | Description |
|---|---|---|
| `GET` | `/api/workspaces/:id/files?path=...` | List directory entries |
| `GET` | `/api/workspaces/:id/files/read?path=...` | Read file content |
| `GET` | `/api/workspaces/:id/files/stat?path=...` | Get file metadata (name, path, isDir, size, modTime) |
| `PUT` | `/api/workspaces/:id/files/write` | Write file (`{"path": "...", "content": "..."}`) |
| `POST` | `/api/workspaces/:id/files/mkdir` | Create directory (`{"path": "..."}`) |
| `DELETE` | `/api/workspaces/:id/files?path=...` | Remove file or directory recursively |
| `POST` | `/api/workspaces/:id/files/rename` | Rename file or directory (`{"oldPath": "...", "newPath": "..."}`) |
### Process
| Method | Path | Description |
|---|---|---|
| `POST` | `/api/workspaces/:id/process/start` | Start OpenCode process for workspace |
| `POST` | `/api/workspaces/:id/process/stop` | Stop OpenCode process |
| `POST` | `/api/workspaces/:id/process/restart` | Restart OpenCode process |
| `GET` | `/api/workspaces/:id/process/status` | Get process running status and PID |
### Health
| Method | Path | Description |
|---|---|---|
| `GET` | `/healthz` | Server health check |
## Examples
### Health check
```sh
curl -s http://localhost:8080/healthz
```
### Create a workspace
```sh
curl -s -X POST http://localhost:8080/api/workspaces \
-H 'Content-Type: application/json' \
-d '{"id":"user1"}'
```
### List workspaces
```sh
curl -s http://localhost:8080/api/workspaces
```
### Write a file
```sh
curl -s -X PUT http://localhost:8080/api/workspaces/user1/files/write \
-H 'Content-Type: application/json' \
-d '{"path":"main.go","content":"package main\n"}'
```
### Read a file
```sh
curl -s 'http://localhost:8080/api/workspaces/user1/files/read?path=main.go'
```
### Get file stat
```sh
curl -s 'http://localhost:8080/api/workspaces/user1/files/stat?path=main.go'
```
## Test
```sh
make test
```