@buildinternet/releases-skills 0.49.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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildinternet/releases-skills",
3
- "version": "0.49.0",
3
+ "version": "0.51.0",
4
4
  "description": "Agent skills bundled with the Releases CLI. Markdown playbooks for changelog ingest, discovery, and analysis.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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