diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8fd7c57
--- /dev/null
+++ b/README.md
@@ -0,0 +1,58 @@
+# Fast Sandbox
+
+This project is a work in progress and does not contain any serious
+documentation.
+
+## API
+
+ POST /api/v1/ws?lang=python
+
+The API is based on message passing.
+
+### Server messages
+
+Received output from process.
+
+ {
+ "event": "terminalOutput",
+ "output": ">>> "
+ }
+
+Package name completions.
+
+ {
+ "event": "packageNameCompletions",
+ "packageNameCompletions": ["Flask", "Flask-Talisman"],
+ "messageSerial": 42
+ }
+
+### Client messages
+
+Received input from user.
+
+ {
+ "event": "terminalInput",
+ "input": "print('Hello, world!')\n"
+ }
+
+User wants to run code.
+
+ {
+ "event": "runCode",
+ "code": "import this"
+ }
+
+User wants to install a package.
+
+ {
+ "event": "installPackage",
+ "packageName": "Flask"
+ }
+
+Complete package names.
+
+ {
+ "event": "completePackageName",
+ "partialPackageName": "fla",
+ "messageSerial": 42
+ }
diff --git a/dynamic/app.html b/dynamic/app.html
new file mode 100644
index 0000000..fc2765f
--- /dev/null
+++ b/dynamic/app.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Fast Sandbox
+
+
+ Editor :)
+
+
diff --git a/langs.json b/langs.json
new file mode 100644
index 0000000..c838694
--- /dev/null
+++ b/langs.json
@@ -0,0 +1,17 @@
+{
+ "c": {
+ "name": "C"
+ },
+ "c++": {
+ "name": "C++"
+ },
+ "haskell": {
+ "name": "Haskell"
+ },
+ "nodejs": {
+ "name": "Node.js"
+ },
+ "python": {
+ "name": "Python"
+ }
+}
diff --git a/scripts/docker-install.bash b/scripts/docker-install.bash
index f3a7400..1391aba 100755
--- a/scripts/docker-install.bash
+++ b/scripts/docker-install.bash
@@ -19,6 +19,7 @@ emacs-nox
git
make
nano
+sudo
vim
wget
@@ -45,6 +46,11 @@ apt-get update
apt-get install -y $(grep -v "^#" <<< "$packages")
rm -rf /var/lib/apt/lists/*
+cd /tmp
+wget -nv https://github.com/watchexec/watchexec/releases/download/1.13.1/watchexec-1.13.1-x86_64-unknown-linux-gnu.deb
+dpkg -i watchexec-*.deb
+rm watchexec-*.deb
+
if (( "$uid" != 0 )); then
useradd --uid="$uid" --create-home --groups sudo docker
passwd -d docker
diff --git a/scripts/pid1.bash b/scripts/pid1.bash
index 21b5099..1ceaa37 100755
--- a/scripts/pid1.bash
+++ b/scripts/pid1.bash
@@ -7,6 +7,8 @@ export LANG=C.UTF-8
export LC_ALL=C.UTF-8
export SHELL="$(which bash)"
+export HOST=0.0.0.0
+
if [[ -d src ]]; then
cd src
fi
diff --git a/src/server.js b/src/server.js
index 875c365..b21e2bb 100644
--- a/src/server.js
+++ b/src/server.js
@@ -1,4 +1,7 @@
const appRoot = require("app-root-path");
+
+const langs = require(appRoot + "/langs");
+
const express = require("express");
const sslRedirect = require("heroku-ssl-redirect");
@@ -7,6 +10,13 @@ const host = process.env.HOST || "localhost";
const port = parseInt(process.env.PORT) || 6119;
app.use(sslRedirect());
+app.get("/:lang", (req, res) => {
+ if (langs[req.params.lang]) {
+ res.sendFile(appRoot + "/dynamic/app.html");
+ } else {
+ res.send(`No such language: ${req.params.lang}`);
+ }
+});
app.use("/", express.static(appRoot + "/static"));
app.listen(port, host, () =>