@buildinternet/releases-skills 0.50.0 → 0.51.0
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/package.json
CHANGED
|
@@ -193,6 +193,8 @@ For static providers, the adapter automatically uses Cloudflare's crawl API with
|
|
|
193
193
|
|
|
194
194
|
**If a fast fetch returns incomplete content**, the adapter falls back to full rendering automatically. If you notice this happening repeatedly for a source, set `--render` to force headless rendering and note the reason in the playbook.
|
|
195
195
|
|
|
196
|
+
**Rendering can't clear a bot challenge.** If a page sits behind a Cloudflare *Managed Challenge*, browser rendering fails too (symptom: `no_change` / 0 releases on a page that's clearly updating) — `--render` won't fix it. The external **Firecrawl monitoring** backend can fetch these instead; it's enabled per source via the admin API (`POST /v1/sources/:slug/firecrawl/sync { enabled: true }`), backend-only, no CLI verb. See the monorepo's `docs/architecture/firecrawl-monitoring.md`.
|
|
197
|
+
|
|
196
198
|
The agent's role is to evaluate content completeness after the first fetch — check that releases have titles, dates, and content. If they do, the fast path is working. If releases are empty or missing, the page likely needs JS rendering.
|
|
197
199
|
|
|
198
200
|
## Source Selection and Scope
|
|
@@ -15,6 +15,7 @@ Operations can be performed via CLI commands or typed MCP/agent tools. Use which
|
|
|
15
15
|
|-----------|-----|------------|
|
|
16
16
|
| List sources | `releases list [slug] --json [--org <org>] [--query <text>] [--has-feed] [--category <c>] [--compact] [--limit <n>] [--page <n>]` | `list_catalog` (filter `kind: "source"` to exclude products); `list_sources` is a deprecated alias |
|
|
17
17
|
| Add source | `releases admin source create <name> --url <url> [--type <type>] [--org <org>] [--feed-url <url>] [--primary]` | `manage_source` action "add" with name, url, type, organization, feed_url, **is_primary** (type auto-detected if omitted; only pass is_primary=true when the source is the org's primary changelog — see "Primary Sources") |
|
|
18
|
+
| Add App Store source | `releases admin source create-appstore <url-or-id> [--platform ios\|macos] [--org <slug>] [--product <slug>] [--storefront <code>]` | _(no typed tool yet — CLI only)_ |
|
|
18
19
|
| Edit source | `releases admin source update <identifier> [--primary] [--priority <p>]` | `manage_source` action "edit" with identifier, is_primary, fetch_priority, name, url, type (use only when changing an already-added source; prefer setting flags on "add") |
|
|
19
20
|
| Remove source | `releases admin source delete <slug> [--ignore --reason <reason>]` | `manage_source` action "remove" with identifier |
|
|
20
21
|
| Fetch releases | `releases admin source fetch <slug> [--dry-run] [--max <n>]` | `manage_source` action "fetch" with identifier |
|
|
@@ -47,10 +48,29 @@ Use `--json` (CLI) for structured output. Typed tools always return JSON.
|
|
|
47
48
|
|
|
48
49
|
## Adding Sources
|
|
49
50
|
|
|
50
|
-
Required: **name** and **url**. Optional: **type** (github, scrape, feed, agent — auto-detected from URL if omitted), **organization** (org ID or slug to associate with), **feed_url** (direct feed URL if known).
|
|
51
|
+
Required: **name** and **url**. Optional: **type** (github, scrape, feed, agent — auto-detected from URL if omitted), **organization** (org ID or slug to associate with), **feed_url** (direct feed URL if known). App Store apps (`appstore` type) are **not** created this way — use `create-appstore` (below); `source create` rejects `--type appstore` and pasted `apps.apple.com` URLs with a pointer to it.
|
|
51
52
|
|
|
52
53
|
On slug collision the API auto-suffixes (`changelog` → `changelog-2`, `-3`, …) and the created row in the response tells you the resolved slug — no rename-and-retry needed.
|
|
53
54
|
|
|
55
|
+
### App Store sources
|
|
56
|
+
|
|
57
|
+
App Store apps need a dedicated command because the create flow resolves the iTunes listing, mints the current version as the first release, and backfills the product's avatar with the app icon:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
releases admin source create-appstore <url-or-id> [--platform ios|macos] [--org <slug>] [--product <slug>] [--storefront <code>]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- `<url-or-id>` accepts an `apps.apple.com/.../id<trackId>` URL, a bare numeric track ID, or an `appstore:<trackId>` coordinate. `--platform` defaults to `ios` (`macos` = Mac App Store); `--storefront` defaults to `us`.
|
|
64
|
+
- **Pre-create the product for a clean name.** With no `--product`, the endpoint names a *new* product after the (often verbose) App Store title — e.g. "Shopify: Sell online/in person". To control the name, create the product first and reference it:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
releases admin product create "Shopify" --org shopify
|
|
68
|
+
releases admin source create-appstore https://apps.apple.com/us/app/shopify/id719892358 --org shopify --product shopify
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **Keep writes serial.** The endpoint resolves the listing on the fly; concurrent creates for a brand-new org/product race on the org/product slug uniqueness constraint. Add one app at a time.
|
|
72
|
+
- The command is idempotent on the app's track ID — re-running reports the existing source instead of creating a duplicate.
|
|
73
|
+
|
|
54
74
|
### Naming sources and products
|
|
55
75
|
|
|
56
76
|
**Don't prefix names with the org name.** The org is already shown as context on every page — repeating it in each child source produces noise like "Datadog › Datadog dd-trace-py". Pick the bare, recognizable name instead.
|
|
@@ -201,6 +221,8 @@ Use `--render` when you know a source needs JavaScript execution. Use `--no-rend
|
|
|
201
221
|
|
|
202
222
|
After adding a new scrape source with an unknown provider, check the first fetch results. If content is complete, consider setting `--no-render` and noting the provider behavior in the playbook.
|
|
203
223
|
|
|
224
|
+
**Blocked by a Cloudflare Managed Challenge?** `--render`/`--no-render` only choose *how* we fetch — they don't help when the page returns a bot challenge that fails browser rendering itself (symptom: persistent `no_change` / 0 releases on a page that clearly updates, e.g. some vendor help pages). For those, the external **Firecrawl monitoring** backend can fetch the page instead. It's enabled per source via the admin API (`POST /v1/sources/:slug/firecrawl/sync { enabled: true }`), not a CLI verb, and not via `--metadata-set` (which skips monitor creation). See the monorepo's `docs/architecture/firecrawl-monitoring.md`.
|
|
225
|
+
|
|
204
226
|
## Duplicate Detection
|
|
205
227
|
|
|
206
228
|
Before adding sources, search for overlapping URLs.
|
|
@@ -15,6 +15,7 @@ The fetch pipeline follows this priority order:
|
|
|
15
15
|
2. **Markdown fetch** — if `metadata.markdownUrl` is set, fetch raw markdown instead of rendered HTML.
|
|
16
16
|
3. **Fast fetch (static providers)** — for providers known to serve pre-rendered HTML (Docusaurus, VitePress, WordPress, Ghost, Mintlify), fetch without headless browser rendering. Uses Cloudflare crawl API with `render: false`. ~10-30x faster than full rendering. Controlled by provider `staticContent` hint or per-source `renderRequired` metadata.
|
|
17
17
|
4. **Cloudflare rendering** — for JS-heavy pages (React SPAs, Notion, etc.), use Cloudflare's browser rendering API to get the fully-rendered HTML. Fallback when fast fetch returns no content.
|
|
18
|
+
5. **Firecrawl monitoring** — for sources behind a Cloudflare *Managed Challenge* that blocks even browser rendering (some vendor help/docs pages, e.g. OpenAI's), an external Firecrawl monitor scrapes the page on a schedule and POSTs changes to the backend, which extracts them through the same parse pipeline. This is a backend-only fetch backend, not a CLI fetch path: it's enabled per source via `metadata.firecrawl` through the admin API (`POST /v1/sources/:slug/firecrawl/sync { enabled: true }`), **not** via `--metadata-set` (that only patches the DB column and skips monitor creation). There's no `releases` verb for it yet — manage it via the API directly. See the monorepo's `docs/architecture/firecrawl-monitoring.md`.
|
|
18
19
|
|
|
19
20
|
After fetching content, the pipeline parses it:
|
|
20
21
|
- **Incremental parsing** — if the source already has releases in the database, extract only new ones by comparing against known releases. This is the default for subsequent fetches.
|
|
@@ -40,7 +40,7 @@ releases admin source create "Linear" --url https://linear.app/changelog --dry-r
|
|
|
40
40
|
|
|
41
41
|
`--dry-run` still runs the URL dedup and exclusion checks (so you'll see "already exists" or "blocked URL" outcomes), but skips the write — including the auto-create-org side effect when `--org <name>` doesn't resolve.
|
|
42
42
|
|
|
43
|
-
By default, `create` runs automated pre-checks (provider detection, feed discovery, markdown probing). Override with `--type github|scrape|feed|agent`. Batch mode (`--batch`) skips evaluation by default for speed.
|
|
43
|
+
By default, `create` runs automated pre-checks (provider detection, feed discovery, markdown probing). Override with `--type github|scrape|feed|agent`. Batch mode (`--batch`) skips evaluation by default for speed. App Store apps use the dedicated `source create-appstore` verb (below) — `create` rejects `--type appstore` and pasted `apps.apple.com` URLs with a pointer to it.
|
|
44
44
|
|
|
45
45
|
Provide a feed URL explicitly when it isn't easily discoverable:
|
|
46
46
|
|
|
@@ -55,6 +55,27 @@ Evaluate without adding:
|
|
|
55
55
|
releases admin discovery evaluate https://linear.app/changelog
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
### Create App Store
|
|
59
|
+
|
|
60
|
+
App Store apps have a dedicated verb because the create flow resolves the iTunes listing, mints the current version as the first release, and backfills the product's avatar with the app icon:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
releases admin source create-appstore https://apps.apple.com/us/app/slack/id618783545 --org slack --product slack
|
|
64
|
+
releases admin source create-appstore appstore:618783545 --platform ios --org slack
|
|
65
|
+
releases admin source create-appstore 1496833156 --platform macos --dry-run
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The identifier is an `apps.apple.com/.../id<trackId>` URL, a bare numeric track ID, or an `appstore:<trackId>` coordinate. `--platform` defaults to `ios` (`macos` = Mac App Store); `--storefront` defaults to `us`. The verb is idempotent on the track ID — re-running reports the existing source.
|
|
69
|
+
|
|
70
|
+
With no `--product`, the endpoint names a _new_ product after the (often verbose) App Store title — e.g. "Shopify: Sell online/in person". To control the name, create the product first and reference it with `--product`:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
releases admin product create "Shopify" --org shopify
|
|
74
|
+
releases admin source create-appstore https://apps.apple.com/us/app/shopify/id719892358 --org shopify --product shopify
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Add one app at a time — the listing is resolved on the fly, and concurrent creates for a brand-new org/product race on slug uniqueness.
|
|
78
|
+
|
|
58
79
|
### Update
|
|
59
80
|
|
|
60
81
|
```bash
|