diff --git a/.cta.json b/.cta.json
deleted file mode 100644
index c4321f6..0000000
--- a/.cta.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "projectName": "loopable",
- "mode": "file-router",
- "typescript": true,
- "tailwind": true,
- "packageManager": "pnpm",
- "git": false,
- "install": true,
- "intent": false,
- "addOnOptions": {},
- "projectPreset": "default",
- "includeExamples": false,
- "routerOnly": false,
- "version": 1,
- "framework": "react",
- "chosenAddOns": [
- "nitro"
- ]
-}
\ No newline at end of file
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 1a0ccbc..d8f5fa0 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -24,10 +24,6 @@ on:
ref:
description: "Commit or tag to deploy (defaults to main)"
required: false
- redirect:
- description: "Also deploy the old site address as a redirect to loop.goodone.si"
- type: boolean
- default: false
concurrency:
group: deploy
@@ -72,13 +68,6 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- - name: Deploy the old site address as a redirect
- if: ${{ inputs.redirect }}
- run: pnpm site:deploy
- env:
- CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
-
- name: Check it answers
run: |
for i in 1 2 3 4 5 6; do
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index f9e7d1b..0000000
--- a/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-**/*.map
-**/*.tsbuildinfo
diff --git a/Dockerfile b/Dockerfile
index e50c5b0..93345f3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,7 +4,6 @@ WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
-COPY site/package.json ./site/
RUN pnpm install --frozen-lockfile
COPY tsconfig.json ./
diff --git a/README.md b/README.md
index dc4da04..40b92d3 100644
--- a/README.md
+++ b/README.md
@@ -88,7 +88,6 @@ Changes go through a pull request; CI must pass before it merges. Merging to `ma
| `src/routes/` | Pages and `/api/` |
| `src/landing/` | The front page |
| `src/worker.ts` | The Cloudflare Worker and its dispatcher container |
-| `site/` | The old site address, now a redirect to loop.goodone.si |
| `drizzle/` | Migrations |
A new connector is a folder plus one line in `src/connectors/manifests.ts` and `src/connectors/runtimes.ts`. See [docs/connectors.md](docs/connectors.md).
diff --git a/docs/hosting.md b/docs/hosting.md
index c4fe991..4347819 100644
--- a/docs/hosting.md
+++ b/docs/hosting.md
@@ -42,9 +42,11 @@ Merging to `main` deploys: once CI passes there, the **Deploy** workflow migrate
Done in October 2026, and kept for reference. loop.goodone.si used to point at the old site Worker, `loopable-web`. To hand it to the app:
1. In the Cloudflare dashboard, under Workers & Pages → `loopable-web` → Settings → Domains & Routes, remove `loop.goodone.si`.
-2. Run the **Deploy** workflow with **Also deploy the old site address as a redirect** ticked. The app takes loop.goodone.si, and `loopable-web.sobear-me.workers.dev` starts redirecting there.
+2. Run the **Deploy** workflow. The app takes loop.goodone.si.
3. Check `https://loop.goodone.si` shows the front page, and that signing in works.
+The old Worker was then left as a redirect from `loopable-web.sobear-me.workers.dev` to the app. Its source is gone from this repository; the deployed Worker stays up until it is deleted in the Cloudflare dashboard.
+
## Limits
Each workspace can have up to 20 loops and 5 runners, and a loop is looked at no more than once a minute. Change them with the Worker variables `LOOPABLE_LIMIT_LOOPS`, `LOOPABLE_LIMIT_RUNNERS` and `LOOPABLE_LIMIT_MIN_POLL_MS`.
diff --git a/package.json b/package.json
index 1556543..eaa0aba 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,6 @@
"typecheck": "tsc --noEmit",
"bump": "node scripts/bump.mjs",
"deploy": "LOOPABLE_CF=1 vite build && wrangler deploy",
- "site:deploy": "pnpm --filter loopable-site run deploy",
"prepublishOnly": "pnpm typecheck && pnpm test && pnpm build"
},
"dependencies": {
@@ -63,7 +62,6 @@
"@cloudflare/containers": "^0.3.7",
"@cloudflare/vite-plugin": "^1.54.10",
"@fontsource-variable/geist": "^5.3.0",
- "@fontsource/geist-mono": "^5.3.0",
"@tailwindcss/vite": "4.1.18",
"@tanstack/devtools-vite": "0.8.5",
"@tanstack/react-devtools": "0.10.12",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5d55b73..145bfb4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -24,9 +24,6 @@ importers:
'@fontsource-variable/geist':
specifier: ^5.3.0
version: 5.3.0
- '@fontsource/geist-mono':
- specifier: ^5.3.0
- version: 5.3.0
'@tailwindcss/vite':
specifier: 4.1.18
version: 4.1.18(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))
@@ -124,12 +121,6 @@ importers:
specifier: ^4.132.0
version: 4.132.0(@types/node@22.20.1)
- site:
- devDependencies:
- wrangler:
- specifier: ^4.132.0
- version: 4.132.0(@types/node@22.20.1)
-
packages:
'@babel/code-frame@7.27.1':
@@ -998,9 +989,6 @@ packages:
'@fontsource-variable/geist@5.3.0':
resolution: {integrity: sha512-j0m+vLQuG5XAYoHtGCVu0spvlGreR3EzpECUVzkFmI1mTVnAO38l/NEPDCFgZ177JxzYJCLSmTQibIiYPilGrA==}
- '@fontsource/geist-mono@5.3.0':
- resolution: {integrity: sha512-UtJ1BBBCVpMYdIcW7nEB45UAoAw5M53ZXs2t0ciPW+IokuAAIc56M8+kW5tXbRJCTpDw4XTtU7proT6NdQAHTg==}
-
'@hono/node-server@2.1.1':
resolution: {integrity: sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==}
engines: {node: '>=20'}
@@ -4729,8 +4717,6 @@ snapshots:
'@fontsource-variable/geist@5.3.0': {}
- '@fontsource/geist-mono@5.3.0': {}
-
'@hono/node-server@2.1.1(hono@4.13.5)':
dependencies:
hono: 4.13.5
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index dc80bc2..06a1e5b 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,6 +1,3 @@
-packages:
- - "site"
-
allowBuilds:
better-sqlite3: true
esbuild: true
diff --git a/site/package.json b/site/package.json
deleted file mode 100644
index 5638792..0000000
--- a/site/package.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "loopable-site",
- "private": true,
- "type": "module",
- "scripts": {
- "deploy": "wrangler deploy --config wrangler.jsonc"
- },
- "devDependencies": {
- "wrangler": "^4.132.0"
- }
-}
diff --git a/site/src/redirect.ts b/site/src/redirect.ts
deleted file mode 100644
index c82dbdb..0000000
--- a/site/src/redirect.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * The old marketing site's address. The front page now lives in the app at
- * loop.goodone.si, so anything that still links here is sent there, path and
- * all.
- */
-const TARGET = "https://loop.goodone.si";
-
-export default {
- fetch(request: Request): Response {
- const url = new URL(request.url);
- return Response.redirect(`${TARGET}${url.pathname}${url.search}`, 301);
- },
-};
diff --git a/site/wrangler.jsonc b/site/wrangler.jsonc
deleted file mode 100644
index 9b7d809..0000000
--- a/site/wrangler.jsonc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "loopable-web",
- "main": "src/redirect.ts",
- "compatibility_date": "2026-09-17",
- // Only the old workers.dev address. loop.goodone.si belongs to the app now;
- // see docs/hosting.md for the order of the switch.
- "workers_dev": true,
- "preview_urls": false
-}
diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx
deleted file mode 100644
index 2adaeb6..0000000
--- a/src/components/ui/tabs.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { Tabs as TabsPrimitive } from "@base-ui/react/tabs"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-function Tabs({
- className,
- orientation = "horizontal",
- ...props
-}: TabsPrimitive.Root.Props) {
- return (
-
- )
-}
-
-const tabsListVariants = cva(
- "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
- {
- variants: {
- variant: {
- default: "bg-muted",
- line: "gap-1 bg-transparent",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-function TabsList({
- className,
- variant = "default",
- ...props
-}: TabsPrimitive.List.Props & VariantProps) {
- return (
-
- )
-}
-
-function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {
- return (
-
- )
-}
-
-function TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {
- return (
-
- )
-}
-
-export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }