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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions