Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ npack is an independent package manager whose registry metadata will be publishe
npack remove <publisher>/<name> [--user|--system] [--store <path>]
npack inspect <artifact>
npack appstream <artifact> [--output <metainfo.xml>]
npack daemon [--socket <path>]

## Conventions

Expand All @@ -46,3 +47,4 @@ npack is an independent package manager whose registry metadata will be publishe
- `npack update --check` (alias of `install-ref --check`) reports available updates for one or all installed packages without downloading or installing anything, the `apt update` counterpart to `update`'s `apt upgrade`.
- A manifest's optional `app` object (`summary`, `description`, `homepage`, `license`, `categories`, `icon`, `screenshots`, `desktop_file`, `release_date`) carries desktop-store metadata; `icon` and `desktop_file` are package-relative paths validated to exist and, for `desktop_file`, to be a syntactically valid freedesktop.org Desktop Entry file with `Exec` required when `Type=Application`.
- `npack appstream` maps a manifest's `app` metadata to an AppStream `<component>` document per the freedesktop.org AppStream spec: `console-application` when there is no `desktop_file` (advertising `<provides><binary>`), `desktop-application` otherwise (advertising `<launchable type="desktop-id">`). Component IDs are namespaced `io.npack.<publisher>.<name>` since publishers are Nostr pubkeys, not domains.
- `npack daemon` runs npackd, a local JSON-RPC-over-Unix-socket service (newline-delimited JSON requests/responses) exposing `Search`, `GetPackage`, `ListInstalled`, `Install`, `Remove`, `Update`, and `CheckUpdates` so a GUI store or other tool does not need to understand Nostr, Blossom, or `.npk` internals. It defaults to `$XDG_RUNTIME_DIR/npackd.sock`. Connections are handled one at a time (the recursive install future is not `Send`, so it cannot be spawned onto the runtime); transaction/progress-event streaming is future work.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ nostr-sdk = "0.45.2"
semver = "1"
tar = "0.4"
toml = "0.8"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "net", "io-util", "signal"] }
zstd = "0.13"

[dev-dependencies]
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ npack update --user --check # report available updates without installin
# artifact themselves
npack resolve <publisher>/myapp --relay wss://relay.example

# Run npackd, a local JSON-RPC service over a Unix socket for a GUI store or
# other tool that shouldn't need to know about Nostr, Blossom, or .npk
npack daemon --socket $XDG_RUNTIME_DIR/npackd.sock

# Publish an artifact and its Nostr events
npack publish ./myapp.manifest.json \
--secret-key <secret-key> \
Expand Down
3 changes: 3 additions & 0 deletions docs/npack.1
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ Extract the embedded manifest from an .npk archive
npack\-appstream(1)
Generate an AppStream component XML document from an .npk archive\*(Aqs manifest
.TP
npack\-daemon(1)
Run npackd, a local JSON\-RPC service over a Unix socket that exposes Search/GetPackage/ListInstalled/Install/Remove/Update/CheckUpdates to the CLI, GUI store plugins, and other tools without them needing to understand Nostr, Blossom, or .npk internals
.TP
npack\-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
Expand Down
23 changes: 17 additions & 6 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Add first-class AppStream support:
Goal: an npack package can describe itself in the language already understood
by Linux application stores.

## Phase 2: Stable service layer
## Phase 2: Stable service layer (in progress)

Introduce `npackd` as the common local backend for the CLI, GUI store plugins,
and other tools:
Expand All @@ -48,18 +48,29 @@ CLI / GUI plugins / other tools
Keep the API local and narrow. D-Bus is the leading Linux-native option; a
Unix socket API remains an alternative.

Core operations:
Shipped: `npack daemon` runs npackd as a JSON-RPC-over-Unix-socket service
(newline-delimited JSON, defaulting to `$XDG_RUNTIME_DIR/npackd.sock`)
exposing:

```text
Search() GetPackage()
ListInstalled() Install()
Remove() Update()
CheckUpdates() GetTransaction()
CancelTransaction()
CheckUpdates()
```

Expose progress and transaction events. GUI integrations should not need to
understand Nostr, Blossom, or `.npk` internals.
Chose a Unix socket over D-Bus for this first slice: no new system dependency
or session/system bus requirement, so it behaves the same in minimal and
containerized environments. A D-Bus adapter in front of the same handlers
remains possible later if a desktop-store integration phase needs it.

Remaining work:

- `GetTransaction()`/`CancelTransaction()` and streamed progress events for
long-running `Install`/`Update` calls -- npackd currently handles one
connection at a time and responds only once an operation completes.
- Expose progress and transaction events. GUI integrations should not need to
understand Nostr, Blossom, or `.npk` internals.

## Phase 3: Security and privilege separation

Expand Down
41 changes: 41 additions & 0 deletions docs/using-npack.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,46 @@ derivation generator would want to build one `fetchurl`-plus-unpack
derivation per package in the graph, without needing a separate `npack
resolve` invocation for every dependency.

## Running npackd (local service API)

`npack daemon` runs npackd, a common local backend that a GUI store or other
tool can talk to without needing to understand Nostr, Blossom, or `.npk`
internals -- the CLI itself is one possible client:

```bash
npack daemon --socket $XDG_RUNTIME_DIR/npackd.sock
```

`--socket` defaults to `$XDG_RUNTIME_DIR/npackd.sock`. The protocol is
newline-delimited JSON over that Unix socket: one JSON object request per
line, one JSON object response per line, matched by `id`.

```text
--> {"id": 1, "method": "ListInstalled", "params": {"user": true}}
<-- {"id": 1, "result": [{"publisher": "npub1...", "name": "myapp", "version": "1.0.0", ...}]}

--> {"id": 2, "method": "GetPackage", "params": {"package": "npub1.../myapp", "relay": ["wss://relay.example"]}}
<-- {"id": 2, "result": {"publisher": "...", "name": "myapp", "version": "1.2.0", "sha256": "...", ...}}
```

Supported methods, mirroring the CLI operations above:

| Method | Params | Result |
| --- | --- | --- |
| `Search` | `query`, `relay[]`, `trusted_publisher[]`, `pubkey`, `refresh`, `no_cache` | Array of matching releases. |
| `GetPackage` | `package`, `relay[]`, `requirement`, `os`, `arch`, `trusted_publisher[]`, `store`, `user` | The same resolved-metadata object as `npack resolve`. |
| `ListInstalled` | `user`, `store` | Array of installed packages. |
| `Install` | `package`, `requirement`, `relay[]`, `server[]`, `user`, `store`, `allow_capability[]` | The installed package's record. |
| `Remove` | `package`, `user`, `store` | `{"removed": "<package>"}`. |
| `Update` | `package` (omit for all), `relay[]`, `server[]`, `user`, `store`, `allow_capability[]` | Array of per-package update outcomes. |
| `CheckUpdates` | `package` (omit for all), `relay[]`, `trusted_publisher[]`, `user`, `store` | Array of `{reference, current_version, available_version}`. |

An unknown method or a request that fails to deserialize its params returns
`{"id": ..., "error": "..."}` instead of `result`. Connections are handled
one at a time -- npackd does not yet stream install/update progress back to
the client; a client sees the final result once the operation completes.
GetTransaction/CancelTransaction-style progress reporting is future work.

## Configuration

Configuration is stored at the platform's user config path, normally:
Expand Down Expand Up @@ -696,4 +736,5 @@ npack verify-installed [--user|--system]
npack remove <publisher>/<name> [--user|--system]
npack publish <manifest> --secret-key <key> [options]
npack appstream <file.npk> [--output <metainfo.xml>]
npack daemon [--socket <path>]
```
Loading
Loading