Skip to content

Commit 804ddcb

Browse files
committed
feat(api): let a package carry guidance about whether to choose it
A blurb says what a package does. It has no room for the other thing a reader needs, which is whether to pick it at all — and @imqueue/sequelize is the case that forces the question: it is locked to Sequelize v6 because upstream has sat in v7-alpha for years and is asking for maintainers, so it is maintained and still evolving for services already on Sequelize, while new development should start with @imqueue/pg-prisma. Optional `note` field, rendered under the blurb on /api/ as a rule-marked aside and carried into llms.txt. The llms.txt half matters more than it looks: an agent reading that file to recommend a package sees only the blurb otherwise, and would recommend the wrong one with complete confidence. The two ORM packages already both carry the exclusive `ORM` tag, so the page said "pick at most one of these" without saying which. Now it says which. Verified end to end by temporarily attaching a note to a shipped package — sequelize is still `planned`, so its own note appears when Wave 6 ships — and checked in both themes.
1 parent 0bbf6c1 commit 804ddcb

5 files changed

Lines changed: 24 additions & 4 deletions

File tree

scripts/lib/api-packages.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
// are hand-written and the owner decided that block stays as it is.
3131
// blurb One line on /api/. Seeded from the package's own npm description
3232
// so it starts out true; revise it when the package's wave ships.
33+
// note Optional. Guidance about CHOOSING the package rather than about what
34+
// it does — "locked to an upstream that has stalled, prefer X for new
35+
// work" is the case it exists for. Rendered under the blurb on /api/
36+
// and carried into llms.txt, because an agent recommending a package
37+
// needs it more than a human browsing does. Keep it to one or two
38+
// sentences and keep it about the choice: anything describing behaviour
39+
// belongs in the blurb or in the package's own documentation.
3340
// cliId Matching id in the CLI's package catalog, or null when the package
3441
// has no catalog entry. `catalog.json` ships with the CLI and is
3542
// mirrored in the templates repo — it does NOT live in this repo, so
@@ -154,7 +161,12 @@ const PACKAGES = [
154161
tier: 2,
155162
group: 'Data & events',
156163
tags: ['ORM'],
157-
blurb: 'Turns GraphQL input — filters, paging, ordering and the selected field set — into efficient Sequelize queries, with database views as models.',
164+
blurb: 'Turns a query described as data — filters, paging, ordering and the '
165+
+ 'requested fields — into one efficient Sequelize statement, with database '
166+
+ 'views as models.',
167+
note: 'Locked to Sequelize v6, which upstream has left in v7-alpha for years. '
168+
+ 'Maintained and still evolving for services already on it; new development '
169+
+ 'should start with @imqueue/pg-prisma.',
158170
cliId: 'sequelize',
159171
latestOnly: true,
160172
status: 'planned',

src/_data/apiPackages.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const idOf = (group) =>
2424
group.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
2525

2626
module.exports = () => ({
27-
// [{ group, id, packages: [{ name, scoped, url, repo, blurb, tags: [{ label, exclusive }] }] }]
27+
// [{ group, id, packages: [{ name, scoped, url, repo, blurb, note, tags: [{ label, exclusive }] }] }]
2828
groups: shippedGroups().map(({ group, packages }) => ({
2929
group,
3030
id: idOf(group),
@@ -34,6 +34,9 @@ module.exports = () => ({
3434
url: `/api/${p.name}/latest/`,
3535
repo: repoOf(p.name),
3636
blurb: p.blurb,
37+
// Absent on almost every package, so `|| null` rather than undefined —
38+
// Liquid treats both as falsy, but null survives a JSON dump readably.
39+
note: p.note || null,
3740
tags: p.tags.map(label => ({ label, exclusive: TAGS[label].exclusive })),
3841
})),
3942
})),

src/_shared/css/prose.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@
149149
no "Older versions" list to sit beside it. */
150150
.prose .api-pkg-ver { margin-left: auto; }
151151
.prose .api-pkg-blurb { flex: 1 1 100%; font-size: 15px; color: var(--muted); line-height: 1.6; }
152+
/* Choosing guidance, not behaviour — "prefer this other package for new work". Set
153+
apart by a rule rather than by colour so it still reads as an aside when the card
154+
is the accent-tinted hover state, and kept smaller than the blurb because it is
155+
about the decision rather than about what the package does. */
156+
.prose .api-pkg-note { flex: 1 1 100%; font-size: 14px; color: var(--muted); line-height: 1.55; padding-left: 10px; border-left: 2px solid var(--line); }
152157
@media (max-width: 620px) { .prose .api-ref-cards { grid-template-columns: 1fr; } }
153158

154159
/* FAQ accordion */

src/llms.liquid

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ generate. A group with nothing shipped yet emits no heading.
8484

8585
### Reference — {{ group.group }}
8686
{%- for pkg in group.packages %}
87-
- [{{ pkg.scoped }} API reference]({{ siteUrl }}{{ pkg.url }}): Every exported symbol of {{ pkg.scoped }}, generated from {{ apiVersions[pkg.name].latest }} — this URL always serves the current major. {{ pkg.blurb }}{% if pkg.tags.size > 0 %} Tagged {% for tag in pkg.tags %}`{{ tag.label }}`{% unless forloop.last %}, {% endunless %}{% endfor %}{% for tag in pkg.tags %}{% if tag.exclusive %} (pick at most one package with this tag){% endif %}{% endfor %}.{% endif %} — [markdown]({{ siteUrl }}{{ pkg.url }}index.md)
87+
- [{{ pkg.scoped }} API reference]({{ siteUrl }}{{ pkg.url }}): Every exported symbol of {{ pkg.scoped }}, generated from {{ apiVersions[pkg.name].latest }} — this URL always serves the current major. {{ pkg.blurb }}{% if pkg.note %} {{ pkg.note }}{% endif %}{% if pkg.tags.size > 0 %} Tagged {% for tag in pkg.tags %}`{{ tag.label }}`{% unless forloop.last %}, {% endunless %}{% endfor %}{% for tag in pkg.tags %}{% if tag.exclusive %} (pick at most one package with this tag){% endif %}{% endfor %}.{% endif %} — [markdown]({{ siteUrl }}{{ pkg.url }}index.md)
8888
{%- endfor %}
8989
{%- endfor %}
9090

src/org/api/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ Browse the complete generated reference for the latest release — every class,
136136

137137
<ul class="api-pkg-list">
138138
{%- for pkg in group.packages %}
139-
<li class="api-pkg"><a class="api-pkg-link" href="{{ pkg.url }}"><span class="api-pkg-name">{{ pkg.scoped | escape }}</span>{% if pkg.tags.size > 0 %} <span class="api-pkg-tags">{% for tag in pkg.tags %}<span class="topic-chip topic-chip--flat"{% if tag.exclusive %} title="Exclusive — pick at most one package carrying this tag"{% endif %}>{{ tag.label | escape }}</span>{% endfor %}</span>{% endif %}{% if apiVersions[pkg.name].latest %}<span class="api-ref-ver api-pkg-ver">v{{ apiVersions[pkg.name].latest }}</span>{% endif %}<span class="api-pkg-blurb">{{ pkg.blurb | escape }}</span></a></li>
139+
<li class="api-pkg"><a class="api-pkg-link" href="{{ pkg.url }}"><span class="api-pkg-name">{{ pkg.scoped | escape }}</span>{% if pkg.tags.size > 0 %} <span class="api-pkg-tags">{% for tag in pkg.tags %}<span class="topic-chip topic-chip--flat"{% if tag.exclusive %} title="Exclusive — pick at most one package carrying this tag"{% endif %}>{{ tag.label | escape }}</span>{% endfor %}</span>{% endif %}{% if apiVersions[pkg.name].latest %}<span class="api-ref-ver api-pkg-ver">v{{ apiVersions[pkg.name].latest }}</span>{% endif %}<span class="api-pkg-blurb">{{ pkg.blurb | escape }}</span>{% if pkg.note %}<span class="api-pkg-note">{{ pkg.note | escape }}</span>{% endif %}</a></li>
140140
{%- endfor %}
141141
</ul>
142142

0 commit comments

Comments
 (0)