Skip to content

jss install --bundle <source> — apt-style meta-packages (Phase 6 of #464) #485

Description

@melvincarvalho

Phase 6 of the phased install plan (#464 comment). The atom (`jss install `, shipped in #479) makes single-app installs cheap; `--bundle` is the composition primitive that turns that atom into "install my entire stack from one URL."

CLI

```
jss install --bundle # install everything in the bundle
jss install --bundle chrome vellum # bundle + ad-hoc additions
jss install --bundle media --pod http://other:4443 # same auth + target flags as bare install
jss install --bundle media --nostr-privkey # NIP-98 auth works too
```

`` resolution

Mirrors the install spec parser, plus local paths:

Input Resolves to
`--bundle media` `https://raw.githubusercontent.com/solid-apps/bundles/main/media.jsonld\` (default registry convention)
`--bundle /` `https://raw.githubusercontent.com///main/bundle.jsonld`
`--bundle https://...` fetch as-is
`--bundle ./my-stack.jsonld` read from filesystem
`--bundle /abs/path.jsonld` read from filesystem

Bundle JSON-LD shape

```json
{
"@context": {
"schema": "https://schema.org/",
"app": "urn:jss:app:"
},
"@id": "#bundle",
"@type": "schema:ItemList",
"schema:name": "Media stack",
"schema:description": "Audio, video, PDF apps",
"schema:itemListElement": [
"playlist",
"pdf",
"mp3url",
{ "app:spec": "JavaScriptSolidServer/git", "app:label": "Git viewer" }
]
}
```

Each item is either:

  • A bare string — any valid Phase 1+2 spec (`chrome`, `org/repo`, `org/repo#ref`, `org/repo=rename`, full URL)
  • An object with required `app:spec` + optional `app:label` / `app:description` for human-readable display

Behavior

  • Bundle header printed once (name + description) before the per-app status lines
  • Per-app output identical to bare `jss install` (`✓` / `⊘` / `✗` lines)
  • Continue-on-error per app (same as multi-arg install)
  • Final summary `N/M installed`, exit non-zero if any failed
  • Auth flags inherited — `--pod`, `--user`, `--password`, `--nostr-privkey` work identically; same auth used for every install in the bundle

Scope (~50 LoC)

  • Add `--bundle ` flag to the install subcommand
  • New helper `parseBundle(input)` that resolves the source to a URL/path
  • New helper `fetchBundle(resolvedSource)` that GETs (or reads from disk) and parses the JSON-LD
  • Iterate items, normalize each (string → `{app:spec: str}` object), pass through the existing `parseAppSpec` + `installOne` machinery
  • Validate item shape; reject items missing `app:spec` (or non-string strings)

Acceptance criteria

```bash

Suppose solid-apps/bundles/main has a media.jsonld file

$ jss install --bundle media

Installing 3 apps from bundle "Media stack" → http://localhost:4443

✓ playlist → http://localhost:4443/public/apps/playlist/
✓ pdf → http://localhost:4443/public/apps/pdf/
✓ mp3url → http://localhost:4443/public/apps/mp3url/

3/3 installed.
```

Tests

  • Bundle from a local JSON-LD file
  • Bundle from a remote URL
  • Bundle from `--bundle ` shorthand against the default registry
  • Bundle items as strings (`"chrome"`)
  • Bundle items as objects (`{ "app:spec": "chrome" }`)
  • Bundle items with rename / ref suffix (`"foo/bar=mybar"`, `"chrome#v1"`)
  • Mixed: `--bundle media chrome` installs the bundle + chrome
  • Invalid bundle (missing items, non-array, malformed JSON) → clear error, exit 1
  • Partial failure (3/4 apps install) → still prints all results, exit 1

Followups (not this PR)

  • Phase 6.5: pod-self-recording. After each `jss install X`, write/update `/.installed.jsonld` (a bundle of what's installed). `jss install --restore ` re-installs from another pod's `.installed.jsonld` for cross-server migration or post-wipe recovery. ~50 more LoC, separate issue once Phase 6 lands.

Parent

#464 — phased plan in the comment thread

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