@buildinternet/releases-skills 0.18.0 → 0.19.1

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.18.0",
3
+ "version": "0.19.1",
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",
@@ -18,7 +18,7 @@ Turn changelog data into competitive intelligence by analyzing release patterns
18
18
  | Operation | CLI | Typed tool |
19
19
  |-----------|-----|------------|
20
20
  | Check existing sources | `releases list --query <company> --json` | `list_sources` with query param |
21
- | Fetch releases | `releases admin source fetch <slug> --max 50` | `fetch_source` with identifier (ID or slug) |
21
+ | Fetch releases | `releases admin source fetch <slug> --max 50` | `manage_source` action "fetch" with identifier (ID or slug) |
22
22
  | Get latest releases | `releases tail <slug> --json` | `get_latest_releases` with source/org and limit |
23
23
  | Search releases | `releases search <query> --json` | `search_releases` with query |
24
24
  | Summarize | `releases summary <slug> --json` | (not available as typed tool) |
@@ -154,7 +154,7 @@ If evaluation returns `confidence: low` or `recommendedMethod: scrape`, you may
154
154
 
155
155
  When evaluating multiple changelog sources for an org, identify which one is the company's **primary changelog** — the top-level, platform-wide changelog that covers the product as a whole. This is typically a website changelog page (e.g., `example.com/changelog`) rather than individual GitHub repos or product-specific pages.
156
156
 
157
- After adding sources, mark the primary one. CLI: `releases admin source edit <identifier> --primary`. Typed tool: `edit_source` with identifier (ID or slug) and is_primary: true. Only one source per org should be primary. If there's no clear top-level changelog, don't mark any as primary.
157
+ After adding sources, mark the primary one. CLI: `releases admin source edit <identifier> --primary`. Typed tool: `manage_source` action "edit" with identifier (ID or slug) and is_primary: true. Only one source per org should be primary. If there's no clear top-level changelog, don't mark any as primary.
158
158
 
159
159
  ## When to Use Crawl
160
160
 
@@ -229,7 +229,7 @@ When in doubt, add and pause rather than skip entirely. A focused index with 3 c
229
229
 
230
230
  When you find a source that matches the staleness or ecosystem criteria above, **still add it to the database** but immediately set it to `--priority paused`. This prevents future onboard runs from rediscovering the same source and re-evaluating it. The source record serves as documentation that "we know about this, and we decided not to track it."
231
231
 
232
- Add the source and immediately set it to paused priority. CLI: `releases admin source add <name> --url <url> --org <org> --type github` then `releases admin source edit <identifier> --priority paused`. Typed tools: `add_source` then `edit_source` with identifier (ID or slug) and fetch_priority: "paused".
232
+ Add the source and immediately set it to paused priority. CLI: `releases admin source add <name> --url <url> --org <org> --type github` then `releases admin source edit <identifier> --priority paused`. Typed tools: `manage_source` action "add" then `manage_source` action "edit" with identifier (ID or slug) and fetch_priority: "paused".
233
233
 
234
234
  Do the same for ecosystem plugins, deprecated products, and low-value repos. The goal is to capture the discovery decision, not to lose the knowledge.
235
235
 
@@ -237,6 +237,6 @@ Do the same for ecosystem plugins, deprecated products, and low-value repos. The
237
237
 
238
238
  Organizations can have multiple distinct products (e.g., Vercel → Next.js, Turborepo, v0). When discovering sources for an org, consider whether they belong to separate products.
239
239
 
240
- Use product and org management operations to organize what you find. CLI: `releases admin product add`, `releases admin org tag add`, `releases categories`. Typed tools: `manage_product`, `manage_org`, `list_categories`. The full list of valid categories is provided in your system prompt.
240
+ Use product and org management operations to organize what you find. CLI: `releases admin product add`, `releases admin org tag add`, `releases categories`. Typed tools: `manage_product`, `manage_org` each carries the valid category list in its description (also provided in your system prompt).
241
241
 
242
242
  Don't force product groupings when sources are ambiguous — leave them at the org level and note suggestions in the state file.
@@ -14,10 +14,10 @@ Operations can be performed via CLI commands or typed MCP/agent tools. Use which
14
14
  | Operation | CLI | Typed tool |
15
15
  |-----------|-----|------------|
16
16
  | List sources | `releases list [slug] --json [--org <org>] [--query <text>] [--has-feed] [--category <c>] [--compact] [--limit <n>] [--page <n>]` | `list_sources` with query, organization, category, has_feed params |
17
- | Add source | `releases admin source add <name> --url <url> [--type <type>] [--org <org>] [--feed-url <url>]` | `add_source` with name, url, type, organization, feed_url params |
18
- | Edit source | `releases admin source edit <identifier> [--primary] [--priority <p>]` | `edit_source` with identifier (ID or slug), is_primary, fetch_priority params |
19
- | Remove source | `releases admin source remove <slug> [--ignore --reason <reason>]` | `remove_source` with identifier (ID or slug) param |
20
- | Fetch releases | `releases admin source fetch <slug> [--dry-run] [--max <n>]` | `fetch_source` with identifier (ID or slug) param |
17
+ | Add source | `releases admin source add <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
+ | Edit source | `releases admin source edit <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
+ | Remove source | `releases admin source remove <slug> [--ignore --reason <reason>]` | `manage_source` action "remove" with identifier |
20
+ | Fetch releases | `releases admin source fetch <slug> [--dry-run] [--max <n>]` | `manage_source` action "fetch" with identifier |
21
21
  | Get latest releases | `releases tail [slug] --json [--org <org>]` | `get_latest_releases` with source, organization, limit params |
22
22
  | Search releases | `releases search <query> --json` | `search_releases` with query, limit params |
23
23
  | Evaluate URL | `releases admin discovery evaluate <url> --json` | `evaluate_url` with url param |
@@ -29,9 +29,10 @@ Operations can be performed via CLI commands or typed MCP/agent tools. Use which
29
29
  | Add product | `releases admin product add <name> --org <org> [--category <c>] [--tags <t>]` | `manage_product` action "add" with name, organization, category, tags |
30
30
  | Ignore URL | `releases admin policy ignore add --org <org> <url>` | `exclude_url` action "ignore" with url, organization |
31
31
  | Block URL | `releases admin policy block add <url>` | `exclude_url` action "block" with url |
32
- | List categories | `releases categories --json` | `list_categories` |
33
- | Get playbook | `releases admin content playbook <org>` | `get_playbook` with organization param |
34
- | Update playbook notes | `releases admin content playbook <org> --notes "..."` | `update_playbook_notes` with organization, notes params |
32
+ | Get playbook | `releases admin playbook <org>` | `manage_playbook` action "get" with organization |
33
+ | Update playbook notes | `releases admin playbook <org> --notes "..."` | `manage_playbook` action "update_notes" with organization, notes |
34
+
35
+ Valid categories (pass to `manage_org`/`manage_product`): see the enum in those tool descriptions or your system prompt. `list_categories` (now retired) has been folded into the two tool descriptions.
35
36
 
36
37
  ## Listing Sources
37
38
 
@@ -48,6 +49,8 @@ Use `--json` (CLI) for structured output. Typed tools always return JSON.
48
49
 
49
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).
50
51
 
52
+ 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
+
51
54
  ### Naming sources and products
52
55
 
53
56
  **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.
@@ -72,7 +75,7 @@ Adding or editing an org, product, or source triggers an entity embedding into t
72
75
 
73
76
  ## Removing Sources
74
77
 
75
- When removing discovery results, also ignore the URL to prevent re-discovery. In CLI: `releases admin source remove <slug> --ignore --reason "..."`. With typed tools: call `remove_source` then `exclude_url` with action "ignore".
78
+ When removing discovery results, also ignore the URL to prevent re-discovery. In CLI: `releases admin source remove <slug> --ignore --reason "..."`. With typed tools: call `manage_source` action "remove" then `exclude_url` action "ignore".
76
79
 
77
80
  ## Ignored URLs (org-scoped)
78
81
 
@@ -87,25 +90,41 @@ For spam domains and known-bad URLs that should never be added for any org. Use
87
90
  After adding a source, validate it:
88
91
 
89
92
  1. **Add the source** — provide name and URL
90
- 2. **Fetch** — trigger a fetch (CLI: `--dry-run` for preview, then real fetch; typed tools: `fetch_source`)
93
+ 2. **Fetch** — trigger a fetch (CLI: `--dry-run` for preview, then real fetch; typed tools: `manage_source` action "fetch")
91
94
  3. **Check results** — get latest releases and verify they have titles, dates, content
92
95
  4. **If bad:** remove the source and ignore the URL
93
96
  5. **If good:** the source is ready for production fetches
94
97
 
95
98
  ## Primary Sources
96
99
 
97
- An org can have one source marked as its **primary changelog** — the main, company-wide changelog. Mark it with `--primary` (CLI) or `is_primary: true` (typed tool).
100
+ An org can have one source marked as its **primary changelog** — the main, company-wide changelog.
101
+
102
+ `is_primary` is conditional, not default. Only set it when the source you are adding is clearly the org's primary changelog:
103
+
104
+ - Onboarding a new org with a single top-level changelog (e.g. `example.com/changelog`) — set `is_primary=true` on the add.
105
+ - Adding a supplementary or secondary source to an existing org (an engineering blog, a per-product changelog, an RSS feed alongside an already-primary page) — **do not** set `is_primary`. Leave the existing primary alone.
106
+ - The task prompt doesn't mention "primary" or similar — default to not setting it.
98
107
 
99
- When onboarding an org, if you find a single top-level changelog alongside product-specific or GitHub sources, mark the top-level one as primary.
108
+ When it does apply, set it on the `add` call in one step, not via a follow-up edit:
109
+
110
+ ```
111
+ manage_source(action="add", name="Changelog", url="https://example.com/changelog", organization="example-corp", is_primary=true)
112
+ ```
113
+
114
+ The same applies on CLI: pass `--primary` to `releases admin source add`, not a follow-up `source edit`.
115
+
116
+ Use `manage_source(action="edit", is_primary=true)` only when promoting a source you added in a prior session — never in the same flow as the add.
100
117
 
101
118
  ## Playbooks
102
119
 
103
- Each org has a **playbook** a README that tells any agent how to efficiently work with that org's changelog sources. The playbook has two layers:
120
+ **A playbook is a per-org skill for fetching that org's releases.** Same mental model as the global skills in this corpus, scoped to one organization. Agents load the playbook into context alongside global skills whenever they fetch from this org — the playbook overrides general rules with the org's specific behavior (naming conventions, what counts as a release, cross-source dedup, rollup cadence).
121
+
122
+ Each playbook has two layers:
104
123
 
105
124
  - **Header** — auto-generated from source metadata. Shows source types, URLs, priorities, parseInstructions, and product groupings. Regenerates automatically on every source mutation. You never edit this directly.
106
- - **Agent notes** — free-form markdown that you fully control. This is the most important part of the playbook. Write it like a README for a teammate who needs to fetch releases from this org without asking questions.
125
+ - **Agent notes** — free-form markdown that you fully control. This is the most important part of the playbook. Write it like a skill an agent will follow imperative, action-oriented, concise not like human documentation.
107
126
 
108
- **Always read the playbook before fetching or working with an org's sources.** Typed tool: `get_playbook` with organization param. CLI: `releases admin content playbook <org>`. If no playbook exists yet, one will be auto-generated on the next source mutation (add/edit/remove).
127
+ **Always read the playbook before fetching or working with an org's sources.** Typed tool: `manage_playbook` action "get" with organization param. CLI: `releases admin playbook <org>`. If no playbook exists yet, one will be auto-generated on the next source mutation (add/edit/remove).
109
128
 
110
129
  ### Writing good agent notes
111
130
 
@@ -151,9 +170,9 @@ Use the verified approach for high-value orgs, when onboarding new orgs with scr
151
170
 
152
171
  Write notes during onboarding after you've fetched and validated sources. Update them when you discover new quirks or when source behavior changes. If notes are empty or stale, write them before doing fetch work — future agents (including yourself in later sessions) will benefit.
153
172
 
154
- **Updating notes:** Use `update_playbook_notes` with the complete notes content — it replaces the entire notes section. You can rewrite, reorganize, or clear notes at any time.
173
+ **Updating notes:** Use `manage_playbook` action "update_notes" with the complete notes content — it replaces the entire notes section. You can rewrite, reorganize, or clear notes at any time.
155
174
 
156
- **Changing source configuration:** The header reflects current source metadata. To change things like `parseInstructions`, `fetchPriority`, or `crawlEnabled`, use `edit_source` with metadata — the header updates automatically.
175
+ **Changing source configuration:** The header reflects current source metadata. To change things like `parseInstructions`, `fetchPriority`, or `crawlEnabled`, use `manage_source` action "edit" with metadata — the header updates automatically.
157
176
 
158
177
  **Product context:** Playbooks group sources by product when products are configured. Some sources (like an org's engineering blog) aren't tied to a specific product but may contain content relevant to any product under that org — the playbook calls these out as "Organization-Level Sources" with a note about which products they may cover.
159
178
 
@@ -22,7 +22,7 @@ After fetching content, the pipeline parses it:
22
22
 
23
23
  ## Fetching
24
24
 
25
- Trigger a fetch for a source by ID or slug. CLI: `releases admin source fetch <slug> [--dry-run] [--max <n>]`. Typed tool: `fetch_source` with identifier (ID or slug) param.
25
+ Trigger a fetch for a source by ID or slug. CLI: `releases admin source fetch <slug> [--dry-run] [--max <n>]`. Typed tool: `manage_source` action "fetch" with identifier (ID or slug) param.
26
26
 
27
27
  Key CLI flags (not available via typed tool — the typed tool always does a full server-side fetch):
28
28
  - `--dry-run` — parse but don't persist. Essential for validation.
@@ -72,8 +72,8 @@ Do NOT fetch release URLs in the parent agent — always delegate to a subagent
72
72
  **What to do based on the result:**
73
73
 
74
74
  If pages are richer than feed content (more text, images, videos, or code examples):
75
- 1. Record the assessment and enable crawl mode. CLI: `releases admin source edit <identifier> --metadata '{"feedContentDepth":"summary-only","crawlEnabled":true}'`. Typed tool: `edit_source` with the same metadata. Subsequent fetches will follow links to per-release pages and extract full content in one pass.
76
- 2. Re-fetch the source once to backfill. CLI: `releases admin source fetch <slug> --full`. Typed tool: `fetch_source`.
75
+ 1. Record the assessment and enable crawl mode. CLI: `releases admin source edit <identifier> --metadata '{"feedContentDepth":"summary-only","crawlEnabled":true}'`. Typed tool: `manage_source` action "edit" with the same metadata. Subsequent fetches will follow links to per-release pages and extract full content in one pass.
76
+ 2. Re-fetch the source once to backfill. CLI: `releases admin source fetch <slug> --full`. Typed tool: `manage_source` action "fetch".
77
77
  3. Verify results. CLI: `releases list <slug> --json` or `releases tail <slug>`. Typed tool: `get_latest_releases` — check content is richer after the re-fetch.
78
78
 
79
79
  If feed already provides full content with no meaningful additions on the page:
@@ -87,7 +87,7 @@ Once `feedContentDepth` is set, skip the sampling step on future encounters. Cra
87
87
 
88
88
  Engineering blogs and news pages mix product announcements with educational content, opinion pieces, and corporate news. They can be useful supplementary sources but require aggressive filtering via `parseInstructions` to avoid noise.
89
89
 
90
- **Before working with blog sources:** Check the org's playbook (`releases admin content playbook <org>`) for notes about how existing blog sources perform, what filtering works, and which products they cover.
90
+ **Before working with blog sources:** Check the org's playbook (`releases admin playbook <org>`) for notes about how existing blog sources perform, what filtering works, and which products they cover.
91
91
 
92
92
  **When to add a blog source:**
93
93
  - The org's primary changelogs don't cover major product announcements (new models, new services)
@@ -160,7 +160,7 @@ Most releases are **features** — individual version bumps, single product anno
160
160
 
161
161
  **How to recognize rollup sources:**
162
162
 
163
- Before parsing, **always read the playbook** (CLI: `releases admin content playbook <org>`, typed tool: `get_playbook` with organization param). If a company publishes rollups as its primary cadence — quarterly, seasonal, "every few months" — the playbook notes should say so explicitly. Example notes:
163
+ Before parsing, **always read the playbook** (CLI: `releases admin playbook <org>`, typed tool: `manage_playbook` action "get" with organization param). If a company publishes rollups as its primary cadence — quarterly, seasonal, "every few months" — the playbook notes should say so explicitly. Example notes:
164
164
 
165
165
  - "Brex publishes quarterly seasonal rollup pages at `/product-announcements/{fall,spring,summer,winter}-release-YYYY`. Treat each as `type: rollup`."
166
166
  - "Ramp's blog series `/blog/new-on-ramp-*-edition` and `/new-on-ramp-q*-*` are quarterly/monthly rollups. Classify as `type: rollup`; individual features within are not separately indexed."
@@ -174,7 +174,7 @@ When you encounter a new rollup source during discovery or fetch, update the pla
174
174
 
175
175
  When adding a new source, always validate before committing:
176
176
 
177
- 1. **Fetch** — CLI: `releases admin source fetch <slug> --dry-run` then `releases admin source fetch <slug>`. Typed tool: `fetch_source` with identifier (ID or slug).
177
+ 1. **Fetch** — CLI: `releases admin source fetch <slug> --dry-run` then `releases admin source fetch <slug>`. Typed tool: `manage_source` action "fetch" with identifier (ID or slug).
178
178
  2. **Verify** — CLI: `releases tail <slug> --json` or `releases admin source fetch-log <slug>`. Typed tool: `get_latest_releases` with source identifier.
179
- 3. **If poor results** — try a different URL or type. CLI: `releases admin source edit <identifier> --type feed`. Typed tool: `edit_source` with identifier.
180
- 4. **If no usable releases** — remove the source. CLI: `releases admin source remove <slug> --ignore --reason "..."`. Typed tool: `remove_source` with identifier, then `exclude_url`.
179
+ 3. **If poor results** — try a different URL or type. CLI: `releases admin source edit <identifier> --type feed`. Typed tool: `manage_source` action "edit" with identifier.
180
+ 4. **If no usable releases** — remove the source. CLI: `releases admin source remove <slug> --ignore --reason "..."`. Typed tool: `manage_source` action "remove" with identifier, then `exclude_url`.
@@ -7,6 +7,14 @@ description: Coordinate bulk playbook writing using parallel sub-agents — cove
7
7
 
8
8
  Coordinate bulk creation or enrichment of playbook agent notes across many orgs using parallel sub-agents.
9
9
 
10
+ ## What a playbook is
11
+
12
+ **A playbook is a per-org skill for fetching that org's releases.** Same mental model as the global skills in this corpus (`parsing-changelogs`, `managing-sources`, etc.) — but scoped to one organization. It tells a future agent (managed or local) how to pull updates from _this_ org: extraction quirks, naming conventions, which sources are canonical, what to skip, where rollups hide.
13
+
14
+ Global skills teach general patterns; per-source `parseInstructions` teach source-specific hints; the playbook is the org-level layer between them. When agents fetch any of an org's sources, they should load that org's playbook into context alongside the global skills — the playbook overrides general rules with specific org behavior.
15
+
16
+ Write notes as instructions to an LLM, not as human documentation. Imperative voice ("Set version=null", "Parse `<h2>` as version boundaries"), concrete examples from real data, and only observations that change future fetch behavior.
17
+
10
18
  **Local-only**: This skill requires Claude Code's Agent tool to dispatch sub-agents. Managed agents (discovery worker, Haiku worker) cannot spawn sub-agents — that capability is behind a private beta and not yet available. When sub-agent support ships for managed agents, this skill can be adapted into a managed session mode.
11
19
 
12
20
  ## When to Use
@@ -24,7 +32,7 @@ bun -e "
24
32
  const orgs = JSON.parse(Bun.spawnSync(['bun', 'src/index.ts', 'admin', 'org', 'list', '--json'], { stderr: 'ignore' }).stdout.toString());
25
33
  const active = orgs.filter(o => o.sourceCount > 0).sort((a,b) => b.releaseCount - a.releaseCount);
26
34
  for (const org of active) {
27
- const playbook = JSON.parse(Bun.spawnSync(['bun', 'src/index.ts', 'admin', 'content', 'playbook', org.slug, '--json'], { stderr: 'ignore' }).stdout.toString());
35
+ const playbook = JSON.parse(Bun.spawnSync(['bun', 'src/index.ts', 'admin', 'playbook', org.slug, '--json'], { stderr: 'ignore' }).stdout.toString());
28
36
  const status = playbook.notes?.length > 100 ? 'has notes (' + playbook.notes.length + ' chars)' : 'NEEDS PLAYBOOK';
29
37
  console.log(org.slug.padEnd(25) + ' sources=' + String(org.sourceCount).padStart(2) + ' ' + status);
30
38
  }
@@ -101,15 +109,16 @@ Products: {product list or "none"}
101
109
  **Coverage**: 2-3 sentences. Which sources are canonical, whether there are gaps.
102
110
 
103
111
  Save by running:
104
- bun src/index.ts admin content playbook {slug} --regenerate 2>/dev/null
105
- bun src/index.ts admin content playbook {slug} --notes "$(cat <<'NOTES'
112
+ releases admin playbook {slug} --notes "$(cat <<'NOTES'
106
113
  YOUR NOTES HERE
107
114
  NOTES
108
115
  )" 2>/dev/null
109
116
 
110
- Verify with: bun src/index.ts admin content playbook {slug} 2>/dev/null | tail -20
117
+ Verify with: releases admin playbook {slug} 2>/dev/null | tail -20
111
118
  ```
112
119
 
120
+ The playbook header regenerates automatically after any source add/edit/remove, and the `--notes` PATCH seeds a fresh header on first write — no separate regenerate step needed.
121
+
113
122
  ### Verified prompt template
114
123
 
115
124
  ```
@@ -147,13 +156,12 @@ Every claim must cite observed data. If uncertain, say so explicitly.
147
156
 
148
157
  ## Step 4: Save
149
158
 
150
- bun src/index.ts admin content playbook {slug} --regenerate 2>/dev/null
151
- bun src/index.ts admin content playbook {slug} --notes "$(cat <<'NOTES'
159
+ releases admin playbook {slug} --notes "$(cat <<'NOTES'
152
160
  YOUR NOTES HERE
153
161
  NOTES
154
162
  )" 2>/dev/null
155
163
 
156
- Verify with: bun src/index.ts admin content playbook {slug} 2>/dev/null | tail -20
164
+ Verify with: releases admin playbook {slug} 2>/dev/null | tail -20
157
165
  ```
158
166
 
159
167
  ### Dispatch pattern
@@ -176,8 +184,7 @@ Sub-agents may be blocked from saving notes via Bash (heredoc permission issues)
176
184
  2. The parent agent (you) saves the notes manually:
177
185
 
178
186
  ```bash
179
- bun src/index.ts admin content playbook {slug} --regenerate 2>/dev/null
180
- bun src/index.ts admin content playbook {slug} --notes "$(cat <<'NOTES'
187
+ releases admin playbook {slug} --notes "$(cat <<'NOTES'
181
188
  {paste notes from agent result}
182
189
  NOTES
183
190
  )" 2>/dev/null
@@ -193,7 +200,7 @@ After all agents complete, verify coverage in bulk:
193
200
  bun -e "
194
201
  const orgs = [{target slugs}];
195
202
  for (const org of orgs) {
196
- const proc = Bun.spawnSync(['bun', 'src/index.ts', 'admin', 'content', 'playbook', org, '--json'], { stderr: 'ignore' });
203
+ const proc = Bun.spawnSync(['releases', 'admin', 'playbook', org, '--json'], { stderr: 'ignore' });
197
204
  try {
198
205
  const d = JSON.parse(proc.stdout.toString());
199
206
  const len = d.notes?.length ?? 0;