Repository navigation
Description
Audit of jspod's ~900 LOC of wrapper code (index.js + lib/) against the jss 0.0.204 surface, toward the goal: a new jspod-type distribution should be buildable as little more than a pages dir + a defaults object + a banner. No code changes proposed here — this is the map. Sequencing is deliberately slow (jspod is in daily use).
A. Already upstream — jspod side now redundant (delegate when comfortable)
- Install plumbing (~250 LOC) —
runInstall,parseAppSpec,loadBundle/resolveBundleSource, install help. jss 0.0.204 shipsjss installwith the same spec forms (name,org/repo, URL,#ref,=rename),--bundle(JSON-LD, schema:itemListElement), bearer + NIP-98 auth, dual-push. This is Refactor: delegatejspod installtojss install(consolidate install plumbing) #48; its hold conditions (--bundle landed, releases passed) now look satisfied. Keep jspod's policy (bare install →defaultbundle) as a one-liner. - Token-secret management (~30 LOC) — jss now has its own persisted secret (
src/auth/token-secret.js:~/.jss/token.secret, atomic write, 0600,TOKEN_SECRETenv wins). jspod still maintains a parallel implementation at<root>/.token-secretand injectsTOKEN_SECRETinto the child env. Two secret files on disk, duplicated logic. Caution: existing pods have working<root>/.token-secretfiles — any consolidation needs a migration story (e.g. upstream a--token-secret-fileflag so per-pod scoping survives, then delete jspod's copy).
B. Not in jss — generic wrapper machinery that should go upstream
These are the bits every jspod-type thing would otherwise reimplement (verified absent from jss 0.0.204):
- Seed/branding hook — the big one. jss's
seedServerRoot()seeds only its own/index.html(skip-if-exists), with no template-override hook; jspod must overwrite pages after boot (seedPodFiles(), 33 LOC + the race it implies). Upstream proposal:--seed-dir <path>(orcreateServer({seedDir})) taking a directory of pages with an overwrite/skip-if-exists manifest. A distribution then ships pages, not seeding code. - Free-port finding (12 LOC) — jss binds and dies on EADDRINUSE. Upstream
--port-retry N(Vite-style shift-up). - Readiness signal (15 LOC of HTTP polling) — no
/healthendpoint, no structured ready marker on stdout; wrappers must poll. Upstream either a/healthroute or a machine-readable READY line. - First-run bundle bootstrap (20 LOC) — jspod spawns
install --bundle defaultafter first boot. Upstream--bootstrap-bundle <source>onjss startso distros get first-run apps declaratively. - Browser auto-open + TTY/CI/SSH heuristics (24 LOC) — classic dev-server nicety; upstream
--open. - In-process start — jss's
createServer(options)already covers the full feature set (IdP/git/nostr/MCP in-process), so Embeddable in-process start (no spawn) so jspod can wrap JSS on mobile/single-process runtimes #58 is mostly a jspod-side mapping ofjssArgs→ options. The one upstream gap:onReady-style hooks aren't reachable by callers, which matters once seeding (item 3) is composable.
C. jspod product identity — stays in the wrapper (what a new distro would swap)
Banner/help (~150 LOC), opinionated defaults (port 5444, me/me, git on), the pages themselves (756 LOC of HTML/ACL), data-browser assets + CDN version pinning (549 LOC), apps/pilot bundle, choice of default bundle, MCP dev tools.
End state
With A delegated and B upstreamed, jspod's lib/start.js collapses to roughly: defaults → map options → createServer()/spawn → done. A new jspod-type thing = jss dep + seed-dir of pages + defaults + banner ≈ 100 LOC.
Suggested order (low risk first)
- Upstream items 4, 5, 7 (additive jss flags; jspod unchanged until ready)
- Upstream 3 (
--seed-dir), then switch jspod to it and deleteseedPodFiles() - Upstream 6, switch jspod's bootstrap to the flag
- Refactor: delegate
jspod installtojss install(consolidate install plumbing) #48 (install delegation) — already specced - Token-secret consolidation (2) — last, needs migration care
- Embeddable in-process start (no spawn) so jspod can wrap JSS on mobile/single-process runtimes #58 in-process mode — unlocked by the above
Activity