Skip to content

Add jspod install <app> subcommand #36

Description

@melvincarvalho

Why

Installing apps on a fresh jspod is a 5-line shell recipe today:

```bash
TOKEN=$(curl -s -X POST -H 'Content-Type: application/x-www-form-urlencoded'
-d 'username=me&password=me'
http://localhost:5444/idp/credentials | jq -r .access_token)
git clone https://github.com/solid-apps/ /tmp/
git -C /tmp/ -c http.extraHeader="Authorization: Bearer $TOKEN"
push http://localhost:5444/public/apps/ HEAD:main
```

It works, but it has at least three sharp edges:

  1. No `--depth=1` — shallow clones are rejected on push (`shallow update not allowed`). New users hit this immediately because shallow is the obvious "save bandwidth" instinct.
  2. `HEAD:main`, not `HEAD:gh-pages` — JSS 0.0.197+ pins auto-init to `-b main` (#471). Pushing to `HEAD:gh-pages` creates a ref but doesn't trigger `updateInstead`, so the directory is created but empty. Confusing silent failure.
  3. Pilot is already bundled — `/public/apps/pilot/` is non-empty from jspod's seeding, so auto-init refuses. Need to know to skip it.

A wrapper hides all three.

Proposed UX

```bash
jspod install chrome
jspod install chrome vellum win98 pdf hub # multi-arg
jspod install # curated default set
jspod install --from solid-apps chrome # registry override (default: solid-apps)
jspod install --pod http://localhost:5444 chrome # target override (default: this jspod)
```

Behavior:

  • Fetch a token from the local pod's `/idp/credentials` (or accept `JSS_SINGLE_USER_PASSWORD` env / a `--token` flag)
  • For each app:
    • `git clone --bare` (full history) into a tmp dir
    • HEAD-probe the target path: if non-empty and not a valid auto-init candidate, skip with a clear message ("pilot is bundled — already at /public/apps/pilot/")
    • `git push --mirror-style` to `/public/apps/` with the correct ref name (probe target's `info/refs` to pick the right branch, default `main`)
    • Clean up the tmp dir
  • Report per-app status (`✓ chrome installed`, `⊘ pilot skipped (already present)`, `✗ vellum failed: …`)

Implementation

~80-120 lines in `index.js`. New `install` arg handler that branches before the existing JSS startup logic so the command can run without spawning a server (it talks to a running jspod). If no pod is reachable, error out with a clear message.

Curated default set

`chrome vellum win98 pdf hub` for v1 — anything else can come from `--from ` or a future `install-all` flag with a remote manifest. Open to a different default set.

Test plan

  • `jspod install chrome` from a clean pod → files visible at `/public/apps/chrome/`
  • `jspod install pilot` → `⊘ skipped (already present)`, exit 0
  • `jspod install nonexistent` → `✗ clone failed`, exit non-zero
  • `jspod install` (no args) → installs the curated set, prints per-app status
  • Works with `--pod` pointing at a remote pod (with a token)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions