@ai-ecoverse/wasi-ntfy 0.0.0 → 2.32.0-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,130 @@
1
1
  # @ai-ecoverse/wasi-ntfy
2
2
 
3
- 🐣 This package name has been claimed with [fledgling](https://github.com/dmno-dev/fledgling) for [https://github.com/ai-ecoverse/homescoop](https://github.com/ai-ecoverse/homescoop), and a real release will land here soon.
3
+ The [ntfy](https://ntfy.sh) 2.32.0 client as a WASI preview1 command for
4
+ SLICC: `ntfy`, with `ntfy publish` (`pub`) and `ntfy subscribe` (`sub`). It is
5
+ seven's replacement for six's webhooks. A webhook, a phone or another agent
6
+ publishes to a topic, and `ntfy sub <topic> '<command>'` runs the command in
7
+ seven for each message. The connection is outbound only, because a tab can't
8
+ listen. It works against [ntfy.sh](https://ntfy.sh), any ntfy server, and the
9
+ ntfy gateway at `https://ntfy.sliccy.ai` (ai-ecoverse/sliccy-ai, "The ntfy
10
+ gateway").
4
11
 
5
- This is a placeholder — there is nothing to install yet.
12
+ On `@ai-ecoverse/slicc-kernel` ≥ 1.125.4, `host/ntfy-host.mjs` (loaded through
13
+ `slicc.commands.ntfy.imports`) sends ntfy's HTTP requests through the kernel's
14
+ network (`net-request`, `net-read`) and starts the commands `ntfy sub` runs.
6
15
 
7
- ---
16
+ `bin/ntfy.wasm` is built by homescoop from ntfy's source (tag v2.32.0, commit
17
+ `9d0b6d9`). It uses Go 1.27.1 with `GOOS=wasip1 GOARCH=wasm CGO_ENABLED=0
18
+ -trimpath -tags noserver`, which is upstream's `make cli-client` build: the
19
+ client only, with no server, no SQLite and no web app. Two patches are
20
+ applied (see [Patches](#patches)), so this isn't an upstream ntfy release.
21
+ The build is reproducible.
8
22
 
9
- Want to claim a name of your own? Run `npx fledgling add <name> --new --yes` — it reserves the name on npm and can set up token-less (OIDC trusted) publishing for when you are ready.
23
+ ## Seven usage
24
+
25
+ The gateway's owner mints a `tk_` token per consumer (`scopes`: `subscribe`,
26
+ `publish`, `hooks`; optional `topics`). Keep the token in the vault and pass
27
+ it as `NTFY_TOKEN` or `--token`. Prefer that over `?auth=`, which puts the
28
+ token in URLs.
29
+
30
+ Subscribe, and turn every message into a `webhook` lick for the cone:
31
+
32
+ ```sh
33
+ NTFY_TOKEN=tk_… ntfy sub https://ntfy.sliccy.ai/github \
34
+ 'agent send cone --lick=webhook --source github "$NTFY_RAW"'
35
+ ```
36
+
37
+ Publish (needs a token with `publish`):
38
+
39
+ ```sh
40
+ NTFY_TOKEN=tk_… ntfy pub --title 'Build' https://ntfy.sliccy.ai/alerts 'deploy finished'
41
+ echo 'from stdin' | ntfy pub https://ntfy.sliccy.ai/alerts
42
+ ```
43
+
44
+ Poll once and exit, instead of streaming:
45
+
46
+ ```sh
47
+ ntfy sub --poll --since 10m https://ntfy.sliccy.ai/github
48
+ ```
49
+
50
+ Or put the defaults in `~/.config/ntfy/client.yml`
51
+ (`$XDG_CONFIG_HOME/ntfy/client.yml` when that is set):
52
+
53
+ ```yaml
54
+ default-host: https://ntfy.sliccy.ai
55
+ default-token: tk_…
56
+ subscribe:
57
+ - topic: github
58
+ command: 'agent send cone --lick=webhook --source github "$NTFY_RAW"'
59
+ ```
60
+
61
+ Then use `ntfy pub alerts hi`, `ntfy sub github '<command>'`, or
62
+ `ntfy sub --from-config`. With `--from-config`, an auth error on any one
63
+ subscription ends the command.
64
+
65
+ The command runs as `sh -c '<command>'`, once per message, in order, one at a
66
+ time. Its stdin, stdout and stderr are ntfy's own. It gets ntfy's own
67
+ environment plus `NTFY_ID`, `NTFY_TIME`, `NTFY_TOPIC`, `NTFY_MESSAGE`,
68
+ `NTFY_TITLE`, `NTFY_PRIORITY`, `NTFY_TAGS` and `NTFY_RAW`, with upstream's
69
+ short aliases (`$m`, `$t`, `$raw`, …). `NTFY_RAW` is the message's JSON line
70
+ as the server sent it, so the fields the gateway adds (`headers`, `verified`,
71
+ `hook`, `attachment.url` for bodies it stores as attachments) reach the
72
+ command. `NTFY_TITLE`, `NTFY_MESSAGE`, `NTFY_TAGS`, `NTFY_PRIORITY` and
73
+ `NTFY_TOPIC` are also flags of `ntfy pub`, so a command that publishes again
74
+ should `unset ${!NTFY_*}` first. Otherwise its `ntfy pub` takes the incoming
75
+ message's topic and fields.
76
+
77
+ The command runs as the user who started `ntfy sub`, with that user's
78
+ privileges, files and environment. Treat everything in a message (`NTFY_*`)
79
+ as untrusted input: anyone who can publish to the topic, or post to a hook
80
+ URL of it, chooses those values. They arrive as data in the environment, so a
81
+ message's `$(…)` or backticks are not run unless the command itself `eval`s
82
+ them. Quote them (`"$NTFY_MESSAGE"`), and never paste them into a shell
83
+ command line. `--token` is not passed to the command's environment;
84
+ `NTFY_TOKEN` is, if you set it in ntfy's own.
85
+
86
+ ## The gateway's contract
87
+
88
+ | The gateway | What the client does |
89
+ | --- | --- |
90
+ | `tk_` tokens are scoped. A subscribe-only token's publish gets 403; no token or a forged one gets 401. | `ntfy pub` prints the server's error and exits 1 (upstream). `ntfy sub` exits 1 on 401 or 403 instead of retrying every 10 s (patched). |
91
+ | 429 with `retry-after: 60` past 10 claims a minute per IP, or 300 messages or deliveries a minute per home. | `ntfy sub` waits for the longer of `Retry-After` and its usual 10 s before it reconnects. `ntfy pub` waits `Retry-After` and sends the message (or the `--file` upload) again, at most twice. It fails at once, naming the wait, when the wait is over 5 minutes or the body can't be sent again (`--file -`) (patched). |
92
+ | At most 8 open streams per token. A subscriber more than 1 MiB behind is dropped. | After any drop, `ntfy sub` reconnects after 10 s with `since=<last message id>` and skips a repeat of that message, so nothing is lost or run twice. Before the first message it resumes from the time of the stream's `open` event (patched). A ninth stream is refused by the gateway; use one `ntfy sub` with several topics (`a,b`) or `--from-config`. |
93
+ | A JSON publish (`POST /`) is capped at 1 MiB. | The CLI never sends a JSON publish; it posts the message to `/<topic>`. A message over 1 MiB, from arguments, `--message` or stdin, is refused before any request (`message is over the 1 MiB limit (1048576 bytes); send it as an attachment with --file instead`). Upstream cut stdin at 1 MiB without a word (patched). `--file` uploads aren't capped by the client; the gateway takes bodies up to 25 MiB. |
94
+ | Message lines stay under 60 KiB; larger bodies become `attachment`s. | Lines up to 4 MiB are read (upstream: 64 KiB) (patched). |
95
+ | Revoking a token answers `{ revoked, hooks }` and ends its streams. | That's the owner's API, not the CLI's. A `ntfy sub` on the revoked token reconnects, gets 401 and exits 1. |
96
+
97
+ ## Patches
98
+
99
+ - `0001-wasip1-slicc-host.patch`: the wasip1 build files upstream lacks
100
+ (`cmd/*_unix.go` and `client/config_unix.go` exclude wasip1), and
101
+ `slicchost`, which talks to `host/ntfy-host.mjs` through the `ntfy_host`
102
+ imports. `http.DefaultTransport` sends requests there and reads each
103
+ response chunk as it arrives. Before each blocking read it yields to the
104
+ other goroutines, so a message's command runs as soon as its line arrives,
105
+ not when the next one does (wasip1 Go has one thread, and a host call
106
+ blocks all of it). The `ntfy sub` command and `pub --wait-cmd` run through
107
+ the host's spawn. `--wait-pid` fails with a clear error.
108
+ - `0002-gateway-contract.patch`: resuming with `since=`, `Retry-After`, auth
109
+ errors ending `ntfy sub`, the 1 MiB refusal and the longer line limit
110
+ described above. Upstream's own reconnect waits 10 s and resubscribes with
111
+ the original options ("may lose messages").
112
+
113
+ ## What does not work
114
+
115
+ - In a runtime without this host module, every request fails with
116
+ `this runtime cannot start commands or open network connections for ntfy (it needs slicc-kernel with @ai-ecoverse/wasi-ntfy's host module)`.
117
+ - `ntfy serve` and the server's admin commands (`user`, `access`, `token`,
118
+ `tier`, `webpush`): this is the client build.
119
+ - Desktop notifications. `ntfy sub` without a command prints each message's
120
+ JSON line, as upstream does on Linux.
121
+ - `ntfy pub --wait-pid`: there's no process table to watch.
122
+ - A password prompt (`--user name` without `:password`) needs a terminal.
123
+ Pass `--user name:password` or a token.
124
+
125
+ ## Licence
126
+
127
+ ntfy is dual-licensed, Apache-2.0 or GPL-2.0-only, at your choice. This
128
+ package is distributed under both, like upstream (`LICENSE`, `LICENSE.GPLv2`).
129
+ Homescoop's patches are under the same terms. `THIRD-PARTY-NOTICES.md` lists
130
+ the Go runtime and every module `ntfy.wasm` links, with their licences.