backburner joins TODO_STATUSES and the board's columns; the three items in the backburner theme move onto the status, so parked is now a lane rather than a folder you have to remember to open. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
102 lines
5.0 KiB
Markdown
102 lines
5.0 KiB
Markdown
---
|
|
id: backburner/resurrect-projects-apps
|
|
title: "Resurrect Projects/Apps"
|
|
theme: backburner
|
|
status: backburner
|
|
created: 2026-08-25
|
|
date_source: stated
|
|
order: 3
|
|
---
|
|
|
|
**Resurrect Projects/Apps.** The idea is not settled — this card exists so the archaeology is not done
|
|
twice. Everything below was read out of git on 2026-08-25.
|
|
|
|
## What existed
|
|
|
|
Two features, one cluster, removed a day apart.
|
|
|
|
**User apps — born `fd4d77a3`, 2026-02-27:** *"user app publishing system — build, serve, and use
|
|
personal apps in workspace panels."* You wrote an app, published it, and it appeared as a **first-class
|
|
workspace panel** beside Terminal and Chat. `/api/apps` (298 lines) built and served it; `/api/app-serve`
|
|
served the built output; `/api/dev-server` (314 lines) plus a websocket proxy ran it live; a shared
|
|
`html-rewrite.ts` made both viewable through the platform's own origin.
|
|
|
|
**`/projects` — the authoring surface.** A list screen and a project screen, a 244-line list panel, a
|
|
**612-line preview panel**, a publish dialog. Projects had a *type*, a *template*, and
|
|
`hasBackend` / `hasAuth` flags — so it was scaffolding as well as hosting. A `projects` table, and
|
|
`proj-meta` / `proj-layout` / `proj-terminals` / `proj-host-terminals` branches in the dashboards
|
|
endpoint.
|
|
|
|
## Why each went
|
|
|
|
**`/projects`, `5a1e3d7e`, 2026-07-30.** Not a design failure — a scheduling one:
|
|
|
|
> Being retired, so it is deleted rather than fixed — it had both defects dashboards just had (edit
|
|
> dropping `?selected=`, an abandoned edit following you onto the next item) and repairing them was
|
|
> work for something on its way out.
|
|
|
|
**Apps, `188b45c1`, 2026-07-31.** The rest of the cluster, **1,440 deletions**: `/api/apps`,
|
|
`/api/app-serve`, `/api/dev-server` and its websocket proxy, `html-rewrite`, the Preview panel, the
|
|
UserApp panel and header, `useUserApps`, `/settings/apps`, `getUserProjectsDir`, `getUserAppsDir`, the
|
|
`ProjectType` and `ProjectDefinition` types, and the `dev-server` websocket provider.
|
|
|
|
**Nothing on disk was touched.** Both commits say so explicitly. Whatever was under `Projects/` is still
|
|
there.
|
|
|
|
## The interesting part: the App Registry used to be dynamic
|
|
|
|
This is the piece worth understanding before rebuilding anything. Alongside the compiled-in apps:
|
|
|
|
```tsx
|
|
const { registerApp } = useAppRegistry(apps);
|
|
const { apps: userApps, email } = useUserApps();
|
|
|
|
registerApp(`${email}/${app.slug}`, {
|
|
name: app.name,
|
|
icon: resolveIcon(app.icon),
|
|
component: createUserAppPanel(app.slug),
|
|
header: createUserAppHeader(app.name, resolveIcon(app.icon)),
|
|
});
|
|
```
|
|
|
|
Keyed per user, with the icon resolved from a **string name** at runtime (`utils/resolve-icon.ts`, 116
|
|
lines — also deleted).
|
|
|
|
**That capability is gone, and the argument against it is good.** The note left where it stood:
|
|
|
|
> there is no `registerApp` any more because nothing ever called one, and a registry that can be added
|
|
> to at runtime is a registry whose contents depend on what has mounted so far.
|
|
|
|
Today `seedAppRegistry` writes the registry once, before anything renders, from 17 static meta lists.
|
|
|
|
**So the constraint to design around, rather than re-litigate: user apps need to reach the registry
|
|
without making it mutable at runtime.** The plugin system — which arrived *after* this was deleted —
|
|
already solved a version of exactly this by generating `Plugins.gen` at build time and mounting plugin
|
|
routers at boot. Any resurrection should start by asking whether a user app is just a plugin with a
|
|
different author, rather than a second mechanism beside it.
|
|
|
|
## What survived, and is still working
|
|
|
|
**`dev-proxy`** (`/api/dev-proxy/5173/…` → `127.0.0.1:5173`). The reasoning in its header is worth
|
|
reading before rebuilding the dev-server half — it explains why neither obvious approach works:
|
|
`http://localhost:5173` resolves on the *viewer's* machine, and `http://<server>:5173` is mixed content
|
|
inside an https page. So the bytes must arrive over the platform's own origin. It costs no certificate,
|
|
no proxy-host entry, and no open port, and it lets a dev server stay bound to loopback.
|
|
|
|
Its stated limit: the app believes it is at `/` and is not. Absolute paths are rewritten on the way out,
|
|
which covers Bun's dev server and ordinary relative assets, but not an app that builds URLs in ways the
|
|
rewrite cannot see.
|
|
|
|
## Open questions, if this is picked up
|
|
|
|
1. **Is a user app a plugin?** The app store, the plugin manifest, `ownerOnly`, sidecars and
|
|
`Plugins.gen` all landed after this was removed. Rebuilding a parallel mechanism would be the
|
|
expensive mistake.
|
|
2. **What is the scaffolding half worth?** Templates, `hasBackend`, `hasAuth` — the agent can now write
|
|
an app from a prompt, which may make a template picker the least valuable part of what was lost.
|
|
3. **Multi-user changes the shape.** The old key was `${email}/${slug}`, written when the platform was
|
|
effectively single-user. Whose apps appear in whose dock is now a permissions question, not a
|
|
namespacing one.
|
|
4. **Does it need its own theme?** It is in `backburner` because the idea is not settled. If it becomes
|
|
real it is bigger than one card.
|