@grimoire-rs/indexer 0.5.3 → 0.5.4
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/CHANGELOG.md +239 -349
- package/README.md +26 -0
- package/dist/cli/ratings.d.ts.map +1 -1
- package/dist/cli/ratings.js +29 -1
- package/dist/cli/ratings.js.map +1 -1
- package/dist/renderer/astro/components/PickerMenu.astro +1 -0
- package/dist/renderer/astro/layouts/Base.astro +6 -0
- package/dist/renderer/astro/lib/catalog.d.ts +8 -1
- package/dist/renderer/astro/lib/catalog.js +10 -1
- package/dist/renderer/astro/lib/catalog.ts +9 -0
- package/dist/renderer/astro/lib/commands.d.ts +7 -0
- package/dist/renderer/astro/lib/commands.js +9 -2
- package/dist/renderer/astro/lib/commands.ts +17 -2
- package/dist/renderer/astro/pages/index.astro +6 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,393 +4,283 @@ All notable changes to `@grimoire-rs/indexer` are recorded here, in
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format. This project
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
> This file starts at `0.5.0`. Releases up to and including `v0.4.4` shipped
|
|
8
|
-
> before it existed and are not reconstructed here — the git tags and
|
|
9
|
-
> `git log v0.4.3..v0.4.4` are the record for those. Every release from the
|
|
10
|
-
> next one on is written down here.
|
|
11
|
-
|
|
12
7
|
Component overrides sit in the **Unstable** tier of the
|
|
13
8
|
[stability table](docs/reference/theme-overlay.md#stability): their file paths
|
|
14
9
|
and props may move in a minor release, and this file is where that is
|
|
15
|
-
announced. Everything in the Contract tier moves only in a major
|
|
10
|
+
announced. Everything in the Contract tier moves only in a major — so a commit
|
|
11
|
+
that moves one says which component and where, old → new, in its subject or
|
|
12
|
+
body, because that is all a reader gets here.
|
|
13
|
+
|
|
14
|
+
## [0.5.4] - 2026-09-01
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
overrider can act on: the component's name, and the move itself as old → new —
|
|
19
|
-
`PackageRow`: `components/PackageRow.tsx` → `components/list/PackageRow.tsx`,
|
|
20
|
-
props `{ pkg }` → `{ pkg, compact }`.
|
|
16
|
+
### Added
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
- Publish the forge host in providers.rating_host *(ratings)*
|
|
19
|
+
- Carry the picked scope into the add-registry link *(renderer)*
|
|
23
20
|
|
|
24
|
-
## [0.5.3] - 2026-
|
|
21
|
+
## [0.5.3] - 2026-08-31
|
|
25
22
|
|
|
26
23
|
### Added
|
|
27
24
|
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
vendor, repository, authors or documentation. A query now splits on spaces
|
|
32
|
-
into terms that are AND-combined and order-independent, and each may land on a
|
|
33
|
-
different key — `astro grimoire` finds a package whose keywords carry one word
|
|
34
|
-
and whose vendor carries the other. The full record set comes from
|
|
35
|
-
`/all.json`, already published and already a frozen public URL, so it costs
|
|
36
|
-
the island no payload: it and the matcher load on the first keystroke and not
|
|
37
|
-
before, as an 8.5 KB gzipped chunk nothing preloads. Until they land, and if
|
|
38
|
-
the fetch fails, the substring pass stands — the field is never dead.
|
|
39
|
-
- **`relevance`, a sort mode**, and the reason the fuzzy pass is worth having:
|
|
40
|
-
it orders by match score. It is offered, stored and server-rendered like every
|
|
41
|
-
other mode, and with no query to rank it answers alphabetically — the order
|
|
42
|
-
the catalog opens on anyway — so a reader can leave it set and have every
|
|
43
|
-
later search come back ranked.
|
|
44
|
-
- **A clear button in the search field.** Chromium and Safari draw one of their
|
|
45
|
-
own, in the UA's styling, in the same corner the `/` hint occupies, and it
|
|
46
|
-
cannot be restyled beyond hiding. So it is hidden and the control is rendered:
|
|
47
|
-
the hint's exact box, carrying an X instead of the key. The two never coexist,
|
|
48
|
-
and clicking it returns focus to the field.
|
|
49
|
-
- **`sitemap.xml`, and a `robots.txt` naming it.** Written by `buildSite` from
|
|
50
|
-
the package list it already holds: every package page stated once, with no
|
|
51
|
-
crawler obliged to render an island or scroll it. This site emitted neither
|
|
52
|
-
before, so the landing page was the only path to a detail page — and the
|
|
53
|
-
windowed catalog below would have made that path a thin one.
|
|
54
|
-
- **A `<noscript>` catalog on the landing page**, listing every package. Without
|
|
55
|
-
JavaScript the island never hydrates, so the reader would otherwise get one
|
|
56
|
-
slice of cards under a toolbar that does nothing.
|
|
25
|
+
- --bulk, to look at the catalog at corporate size *(dev)*
|
|
26
|
+
- Fuzzy search across every field, with a relevance order *(renderer)*
|
|
27
|
+
- Give the search field its own clear button *(renderer)*
|
|
57
28
|
|
|
58
29
|
### Changed
|
|
59
30
|
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
1.5s to switch views; both are now under 50ms, and the landing page goes from
|
|
63
|
-
3.42MB to 795KB. The island builds one viewport's worth and *grows* the slice
|
|
64
|
-
as a sentinel below the list comes into view — a growing slice rather than
|
|
65
|
-
true virtualization, so an item that has been built stays built and find-in-page
|
|
66
|
-
keeps working over everything reached. The keyword rail's two geometry-reading
|
|
67
|
-
layout effects are gated on a signature of the visible chips rather than
|
|
68
|
-
running on every commit, and the filter, sort and rail chain is memoized.
|
|
69
|
-
- **The island is shipped only the fields a card renders**, through a new
|
|
70
|
-
`CardPackage` type and `cardPackage()` projection exported from
|
|
71
|
-
`lib/catalog.ts`. Astro serializes island props into an attribute on
|
|
72
|
-
`<astro-island>`, so every field handed to `<Catalog>` was paid for twice on
|
|
73
|
-
the landing page: at 250 packages the attribute was 323,044 bytes, 17.5% of
|
|
74
|
-
the page, most of it fields no card or row reads. It is 201,554 now (-37.6%).
|
|
75
|
-
Three Unstable-tier components take the narrower type — `PackageCard`,
|
|
76
|
-
`PackageRow` and `CardLogo`, props `{ pkg: CatalogPackage }` →
|
|
77
|
-
`{ pkg: CardPackage }`. An override reading `license`, `authors`, `vendor`,
|
|
78
|
-
`documentation`, `compatibility`, `revision`, `support`, `repository`,
|
|
79
|
-
`title`, `owner`, `schema`, `tags` or an unknown enrichment key off `pkg` now
|
|
80
|
-
fails to compile rather than rendering `undefined` in the browser; the detail
|
|
81
|
-
pages are untouched, and read the full record as before.
|
|
82
|
-
- **The list view's columns are sized for the description.** The two marks are
|
|
83
|
-
`min-content` rather than `auto` and the name is `fit-content(14rem)` rather
|
|
84
|
-
than `minmax(8rem, 14rem)` — that 8rem floor made a list of short names pay a
|
|
85
|
-
fixed 8rem, so the description started after a column of empty space. The
|
|
86
|
-
row's gutter drops a step with them.
|
|
31
|
+
- Ship the island only the fields a card renders *(renderer)*
|
|
32
|
+
- Build a viewport of the catalog, not all of it *(renderer)*
|
|
87
33
|
|
|
88
34
|
### Fixed
|
|
89
35
|
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
was aimed at is held by `loading="lazy"` on the logo and by the window above.
|
|
96
|
-
- **The agent badge cleared WCAG AA.** `--grim-color-kind-agent` was `#b0641a`,
|
|
97
|
-
4.484:1 against the white card and so under AA's 4.5 for the 11.5px badge it
|
|
98
|
-
tints; it is `#a05c17` now, 5.20:1. Its four siblings were audited at the same
|
|
99
|
-
time and clear it unaided, so they are unchanged, and so is the dark palette.
|
|
100
|
-
- **A stored `table` view no longer flips after the first paint.** The pre-paint
|
|
101
|
-
gate listed the sort, dir and deprecated preferences only, so a reader whose
|
|
102
|
-
stored view is the list got the server's cards painted first and the island's
|
|
103
|
-
table a moment later. `?kw=` had the same gap on the other half of the
|
|
104
|
-
condition — the parameter a keyword chip on a package page links to was never
|
|
105
|
-
checked. Both lists are pinned by a test now.
|
|
106
|
-
- **The sort control's focus ring stays off a mouse click.** Chromium matches
|
|
107
|
-
`:focus-visible` on a `<select>` after a plain click, so the accent ring lit on
|
|
108
|
-
click and stayed lit beside the thin neutral chips until the reader clicked
|
|
109
|
-
elsewhere. No selector distinguishes focus that arrived from a pointer, so the
|
|
110
|
-
element marks itself on `pointerdown` and a keypress or a blur clears it. The
|
|
111
|
-
keyboard path keeps both the ring and its focus.
|
|
36
|
+
- Hold the paint for a stored view and a kw deep link *(renderer)*
|
|
37
|
+
- Lift the agent badge to WCAG AA, and ratchet the floors *(renderer)*
|
|
38
|
+
- Verify the pack shape under both npm majors the matrix ships *(ci)*
|
|
39
|
+
- Restore the list view's subgrid columns *(renderer)*
|
|
40
|
+
- Keep the sort ring off a pointer interaction *(renderer)*
|
|
112
41
|
|
|
113
42
|
## [0.5.2] - 2026-08-31
|
|
114
43
|
|
|
115
44
|
### Fixed
|
|
116
45
|
|
|
117
|
-
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
off every bordered control in the toolbar together rather than off the one
|
|
123
|
-
that showed it: the search field, the keyword overflow menu's search, both
|
|
124
|
-
sort halves and both view picks. Keyword chips gain the same ring, having
|
|
125
|
-
taken the browser's default until now.
|
|
126
|
-
- **A long address no longer wraps the card's head onto a second line.** A
|
|
127
|
-
namespace breaks at its own slashes and dots, so a wide one took two rows and
|
|
128
|
-
left the card taller than its neighbours with the tail of the address against
|
|
129
|
-
the padding edge. It stays on one line and the overflow is trimmed from the
|
|
130
|
-
*front* — the registry host is on every address in an index and the
|
|
131
|
-
repository at the tail is what tells two apart — with the whole of it in the
|
|
132
|
-
element's `title`.
|
|
133
|
-
- **Keyword chips could stutter, or stop part-way through the rail's slide.**
|
|
134
|
-
The rail's FLIP pass inverted each chip with an inline `transition: none` and
|
|
135
|
-
a `translate`, then dropped both on the next animation frame; any commit
|
|
136
|
-
landing inside that window left the chip carrying the offset with its
|
|
137
|
-
transition disabled, and nothing else took those off. It also measured seats
|
|
138
|
-
with `getBoundingClientRect`, which reports where a chip is *drawn*, so a
|
|
139
|
-
chip caught mid-slide recorded its animated box and the next inversion
|
|
140
|
-
compounded the error instead of correcting it. Neither window was rare: the
|
|
141
|
-
rail's own fit measurement re-commits whenever a rescore changes how many
|
|
142
|
-
chips fit. Seats now come from `offsetLeft`/`offsetTop`, which ignore
|
|
143
|
-
transforms and scroll, and the slide is a Web Animation — it starts without a
|
|
144
|
-
frame, writes nothing to `style`, and clears itself when it finishes or is
|
|
145
|
-
cancelled. `prefers-reduced-motion` is honoured by the effect rather than by
|
|
146
|
-
the stylesheet, and `--grim-duration-slow` is still its length.
|
|
147
|
-
|
|
148
|
-
## [0.5.1] - 2026-08-31
|
|
46
|
+
- Merge the focus ring onto the control's own border *(renderer)*
|
|
47
|
+
- Trim a long card address from the front *(renderer)*
|
|
48
|
+
- Run the keyword rail's slide as a Web Animation *(renderer)*
|
|
49
|
+
|
|
50
|
+
## [0.5.1] - 2026-08-30
|
|
149
51
|
|
|
150
52
|
### Added
|
|
151
53
|
|
|
152
|
-
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
[Reuse shipped components](docs/how-to/reuse-components.md#code-blocks).
|
|
165
|
-
- **`data-slot="code-block"`**, for it. Contract tier, like every other slot.
|
|
166
|
-
- **A second argument on `registryAddCommand` and `registryScopeChoices`**,
|
|
167
|
-
the registry to build the command for — defaulting to the one in your config,
|
|
168
|
-
so nothing existing changes. It is what lets a setup page draw the "add
|
|
169
|
-
registry" bar for an index *other* than the site's own: a corporate index in
|
|
170
|
-
the hero and the public one further down.
|
|
171
|
-
- **A clear button on the keyword filters**, in the catalog toolbar. Rendered
|
|
172
|
-
only while a keyword is picked, and it lifts the keywords alone — Escape is
|
|
173
|
-
still what clears the search and the kinds with them.
|
|
54
|
+
- Add a --host flag to dev *(cli)*
|
|
55
|
+
- Add CodeBlock, a code block an index's page can use *(renderer)*
|
|
56
|
+
- Let the registry command builders take another index *(renderer)*
|
|
57
|
+
- Add a clear button to the keyword filters *(renderer)*
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- Keep off-screen cards out of layout and paint *(renderer)*
|
|
62
|
+
|
|
63
|
+
### Documentation
|
|
64
|
+
|
|
65
|
+
- Record the unreleased changes *(changelog)*
|
|
174
66
|
|
|
175
67
|
### Fixed
|
|
176
68
|
|
|
177
|
-
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
trigger is a `<button>` rather than a `<summary>`, so the toolbar's arrow-key
|
|
184
|
-
navigation now reaches it.
|
|
185
|
-
- **The detail page's logo drifted down under a long description.** The header
|
|
186
|
-
centred the tile against the text beside it, so the same package's mark sat
|
|
187
|
-
at a different height on every page. It holds against the title now.
|
|
188
|
-
- **Dropped the tinted square behind a package logo**, on the cards, the list
|
|
189
|
-
rows and the detail header alike. A logo is a designed mark already sitting
|
|
190
|
-
on its own ground, so the slot framed it twice — most visibly for the many
|
|
191
|
-
logos that are themselves a rounded square, which then sat inside a slightly
|
|
192
|
-
larger one. The slot still reserves the same box, so nothing shifts. The
|
|
193
|
-
dashed frame the broken-logo state drew goes with it — it read as a fault in
|
|
194
|
-
the layout rather than in the image; the slashed glyph is what says the logo
|
|
195
|
-
failed, and `role="img"` with a label is what announces it. The
|
|
196
|
-
initial-letter tile a package with no logo gets is unchanged: there the
|
|
197
|
-
coloured ground is the mark.
|
|
198
|
-
- **The dev server's URL is a legal URL when the server binds an IPv6
|
|
199
|
-
address.** An unbracketed literal reads its own colons as a port, so
|
|
200
|
-
`http://::1:4321/` threw `ERR_INVALID_URL` at the first `new URL` against it
|
|
201
|
-
and took `dev:smoke` down with a message naming neither the address nor the
|
|
202
|
-
host. Wildcard binds still become `localhost`; anything carrying a colon is
|
|
203
|
-
bracketed.
|
|
204
|
-
- **The detail page's logo tile is a fixed square.** `aspect-ratio: 1` derived
|
|
205
|
-
its width from the height the box had *before* `align-self: stretch` grew it,
|
|
206
|
-
so it rendered 56x93 beside a logo and 56x70 beside a letter — portrait,
|
|
207
|
-
never square, and narrow enough to read as bounding the image rather than
|
|
208
|
-
framing it.
|
|
209
|
-
- **The list row's glyphs sit on the row's centre.** `vertical-align: middle`
|
|
210
|
-
aligns to half the parent's x-height, about 2px under the line's true middle
|
|
211
|
-
at this step, and the upvote arrow's optical nudge added a third pixel the
|
|
212
|
-
same way. The kind and rating cells are flex boxes now and centre their
|
|
213
|
-
contents as boxes.
|
|
214
|
-
- **Keyword chips could freeze part-way through the rail's slide.** The rail
|
|
215
|
-
animates a rescore by inverting each chip with an inline `translate` and
|
|
216
|
-
dropping it on the next animation frame. A rescore that also changes how many
|
|
217
|
-
chips fit commits a second time, and that commit cancelled the frame before
|
|
218
|
-
it ran — leaving every moved chip parked at its offset with transitions
|
|
219
|
-
disabled. Deselecting the last keyword hit it most often, because that
|
|
220
|
-
rescore is the largest. The offsets are now cleared before each measurement
|
|
221
|
-
and on cleanup, so an interrupted slide resolves instead of sticking.
|
|
222
|
-
- **Switching between the cards and list views repainted the whole catalog.**
|
|
223
|
-
Off-screen cards are skipped until they are scrolled to. The two views share
|
|
224
|
-
no element types, so a switch still rebuilds every item — past a few hundred
|
|
225
|
-
packages the answer is windowing the list, and this is not that.
|
|
69
|
+
- Bracket an IPv6 address in the dev server's URL *(renderer)*
|
|
70
|
+
- Make the detail page's logo tile a fixed square *(renderer)*
|
|
71
|
+
- Centre the list row's glyphs on the row, not the x-height *(renderer)*
|
|
72
|
+
- Open the keyword overflow menu in the top layer *(renderer)*
|
|
73
|
+
- Stop keyword chips freezing part-way through the rail's slide *(renderer)*
|
|
74
|
+
- Hold the detail logo against the title, and stop framing it *(renderer)*
|
|
226
75
|
|
|
227
76
|
## [0.5.0] - 2026-08-30
|
|
228
77
|
|
|
229
78
|
### Added
|
|
230
79
|
|
|
231
|
-
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
- **
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- **`@grim/*` import specifier**, resolving to the renderer's sources so an
|
|
245
|
-
added page reaches the layout, components and helpers without a relative
|
|
246
|
-
path that encodes how deep it sits under `pages/`. It resolves *after* the
|
|
247
|
-
overlay, so an index that replaced a component imports its own.
|
|
248
|
-
- **`@grim-original/*`**, the same tree as it was *before* the overlay ran, so
|
|
249
|
-
an override can wrap the file it replaced instead of owning it outright.
|
|
250
|
-
`@grim/*` cannot serve that purpose once the theme has taken the path, and
|
|
251
|
-
the package's `exports` do not publish the Astro sources for a deep import.
|
|
252
|
-
- **One stderr line per overlaid path that replaces a shipped file**, naming
|
|
253
|
-
the path and the indexer version that shipped it. That is what makes the
|
|
254
|
-
Unstable tier below honest without a manifest. A path that only adds a file
|
|
255
|
-
is not logged.
|
|
256
|
-
- **`dev` mirrors `theme/**` edits** into the staged tree, so a page reloads as
|
|
257
|
-
it is saved. It creates `theme/` first if it is absent — a directory added
|
|
258
|
-
after the server started now mirrors instead of 404ing forever — and removes
|
|
259
|
-
it again on shutdown if you left it empty. Deletes are still not mirrored;
|
|
260
|
-
restart for those. A fault in the platform's recursive-watch backend disables
|
|
261
|
-
mirroring with a message rather than taking the server down.
|
|
262
|
-
- **`nav` config key.** An ordered `{label, href}` list that takes the header
|
|
263
|
-
over. Unset, it synthesizes exactly what the header has always shown, so an
|
|
264
|
-
index that predates the key renders unchanged; `[]` leaves the theme toggle
|
|
265
|
-
standing alone.
|
|
266
|
-
- **`notice` config key.** One line above the page content, in the site's own
|
|
267
|
-
width, on every page, carrying `data-slot="site-notice"`. Named `notice`
|
|
268
|
-
rather than `banner` because `--grim-color-banner-*` is the existing amber
|
|
269
|
-
palette for the deprecated-package banner, and a key called `banner` would
|
|
270
|
-
invite an index runner to override that token family by mistake.
|
|
271
|
-
- **`nav[].external` and `footerLinks[].external`.** Optional per entry, and it
|
|
272
|
-
decides only the new-tab affordance — the deployment base prefix is applied
|
|
273
|
-
either way. Unset keeps the old inference from the href's shape. `false` is
|
|
274
|
-
the case that inference cannot express: an absolute URL that is still your
|
|
275
|
-
own site, a staging host or an intranet mirror.
|
|
276
|
-
- **A build-time warning for a `nav` or `footerLinks` href that leads nowhere.**
|
|
277
|
-
A `/`-rooted href matching no emitted route and no `public/` file prints
|
|
278
|
-
`nav[0].href "/setup/": nothing is published at that path — the link will
|
|
279
|
-
404`. It warns and never fails: a path served by something outside the build
|
|
280
|
-
is indistinguishable from a typo, and refusing a whole site over a footer
|
|
281
|
-
typo is worse than the typo. Checked after the build, which is the one moment
|
|
282
|
-
both the emitted routes and every `public/` layer exist at once.
|
|
283
|
-
- **A warning for an unrecognised top-level key in `index.config.json`**,
|
|
284
|
-
naming the key. Without it a typo — or a config predating the `banner` →
|
|
285
|
-
`notice` rename — loaded clean and silently rendered nothing.
|
|
286
|
-
- **`init` scaffolds `theme/README.md` and a `tsconfig.json`** mapping
|
|
287
|
-
`@grim/*` for editors. The README states where a page goes and which parts of
|
|
288
|
-
the overlay are promised, which a `.gitkeep` could not; both reserve `theme/`
|
|
289
|
-
for git equally well. `theme/pages/` is no longer created empty. The build
|
|
290
|
-
does not read that tsconfig.
|
|
291
|
-
- **A documentation site** (MkDocs Material, Diátaxis), built `--strict` as the
|
|
292
|
-
docs' pre-merge gate and published to GitHub Pages. `task docs:build`,
|
|
293
|
-
`docs:serve`, `docs:clean` — deliberately not part of `task check`, which
|
|
294
|
-
must stay runnable with no Python toolchain.
|
|
295
|
-
- **Individually replaceable components**: `SiteHeader`, `SiteFooter`,
|
|
296
|
-
`CommandBar`, `CopyButton`, `CardLogo`, `PackageCard`, `PackageRow`.
|
|
297
|
-
- **This changelog**, which two docs pages already made the sole mitigation for
|
|
298
|
-
the Unstable tier. It ships in the npm tarball, so the copy that matches your
|
|
299
|
-
pinned version is `node_modules/@grimoire-rs/indexer/CHANGELOG.md`.
|
|
300
|
-
- **`npm run typecheck:tests`**, type-checking the `test` tree under its own
|
|
301
|
-
`tsconfig.test.json`. Deliberately not wired into `task check` yet: the tree
|
|
302
|
-
has 95 real type errors, which is its own piece of work.
|
|
80
|
+
- Carry the rating thread URL into the catalog *(renderer)*
|
|
81
|
+
- Redraw the package card, and keep the view across a visit *(renderer)*
|
|
82
|
+
- Give the detail page its right column back *(renderer)*
|
|
83
|
+
- Pick keyword chips by splitting power *(renderer)*
|
|
84
|
+
- Give the catalog a keyword facet and a list view *(renderer)*
|
|
85
|
+
- Ship square, behind one radius knob *(renderer)* **BREAKING**
|
|
86
|
+
- **Migration:** every corner is square by default. `--grim-radius-base` is the whole decision — `0px` now, `4px` restores the rounding of `0.4.x` and earlier in one line. The four measurement steps derive from it and hold their ratios; overriding one step directly still beats the derivation, so a consumer wanting square surfaces and rounded controls sets that step and ignores the knob. Four steps at 4/6/8/10px was a distinction nobody perceived — they were only pickable after their roles were written down, and the package list had already ended up on the wrong one silently. Square reads as the developer tool this is, and `pill` stays off the knob because a chip is a
|
|
87
|
+
- Show the package logo in the list view *(renderer)*
|
|
88
|
+
- Add nav and notice, behind one URL guard for every link value *(config)* **BREAKING**
|
|
89
|
+
- **Migration:** `footerLinks[].href` now accepts a site-root path as well as an absolute URL, and both link keys are validated when the config loads, so a
|
|
90
|
+
- Lay an index repo's theme/ over the shipped sources *(renderer)*
|
|
91
|
+
- Scaffold theme/README.md and an editor tsconfig that loads *(init)* **BREAKING**
|
|
92
|
+
- **Migration:** `init` no longer creates `theme/pages/.gitkeep`. An index scaffolded before this keeps its own copy; nothing removes it.
|
|
303
93
|
|
|
304
94
|
### Changed
|
|
305
95
|
|
|
306
|
-
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
96
|
+
- Name the radius tokens for their role *(renderer)* **BREAKING**
|
|
97
|
+
- **Migration:** `--grim-radius-sm`, `-md`, `-lg` and `-xl` are now `--grim-radius-code`, `-inset`, `-control` and `-surface`. `-pill` is unchanged and no value moved. A `customCss` override under an old name is silently ignored, like any unknown custom property; `README.md` carries the migration note. Every other family in `tokens.css` names the role a value plays rather than its size — that is the rule this sheet states about itself, and the radius scale was the one family breaking it. The cost was not cosmetic: with nothing saying which step a surface should take, the package list ended up on the control step next to cards on the surface step, and the two corners disagreed. That is fixed here too. The contract comment now publishes what each step is for, and warns against picking by eye — the same radius on a shorter box reads as more curve, so two corners that look different are often the same step.
|
|
98
|
+
- Lead the list row with logo, name, then kind *(renderer)*
|
|
99
|
+
- Put the kind mark before the name in the list *(renderer)*
|
|
100
|
+
- Make the header, footer, command bar and cards replaceable *(renderer)* **BREAKING**
|
|
101
|
+
- **Migration:** an `https://` footer link now opens in a new tab. Set
|
|
102
|
+
|
|
103
|
+
### Documentation
|
|
104
|
+
|
|
105
|
+
- Write down the local loop -- direnv, task, and the dev index
|
|
106
|
+
- Publish a documentation site, and start a changelog
|
|
107
|
+
|
|
108
|
+
### Fixed
|
|
109
|
+
|
|
110
|
+
- Hang the kind watermark off the corner by a share of its size *(renderer)*
|
|
111
|
+
- Point the dev fixture at the real extension id *(dev)*
|
|
112
|
+
|
|
113
|
+
## [0.4.4] - 2026-08-29
|
|
114
|
+
|
|
115
|
+
### Fixed
|
|
116
|
+
|
|
117
|
+
- Upload the tally -- a dotfile artifact was silently dropped *(ratings)*
|
|
118
|
+
|
|
119
|
+
## [0.4.3] - 2026-08-28
|
|
120
|
+
|
|
121
|
+
### Fixed
|
|
122
|
+
|
|
123
|
+
- Stop locking threads by default -- a locked one cannot be voted on *(ratings)* **BREAKING**
|
|
124
|
+
|
|
125
|
+
## [0.4.2] - 2026-08-28
|
|
126
|
+
|
|
127
|
+
### Added
|
|
128
|
+
|
|
129
|
+
- Publish zero-vote threads so a first vote can be cast *(ratings)* **BREAKING**
|
|
130
|
+
|
|
131
|
+
## [0.4.1] - 2026-08-28
|
|
132
|
+
|
|
133
|
+
### Added
|
|
134
|
+
|
|
135
|
+
- Make the whole theming surface a token contract *(renderer)* **BREAKING**
|
|
136
|
+
- **Migration:** every CSS custom property is renamed. The unnamespaced tokens (`--accent`, `--bg`, `--fg`, and the rest) are now `--grim-color-*`, and space, type, radius, border width, motion and elevation become overridable for the first time under `--grim-space-*`, `--grim-text-*`, `--grim-radius-*`, `--grim-border-width`, `--grim-duration-*` and `--grim-shadow-*`. A `theme.css` written against 0.4.0 or earlier stops applying silently rather than erroring.
|
|
137
|
+
- Publish a checkpoint, and seed the sidecars from it *(enrich)*
|
|
138
|
+
|
|
139
|
+
### Fixed
|
|
140
|
+
|
|
141
|
+
- Stop reading a large page as a transport failure *(ratings)*
|
|
142
|
+
- Stop every run dying on PAGE_SIZE at import *(ratings)*
|
|
143
|
+
|
|
144
|
+
## [0.4.0] - 2026-08-26
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
|
|
148
|
+
- Publish a stats.json sidecar from the index's own forge (#5) *(ratings)*
|
|
149
|
+
- Carry grim's annotation fields, and date every package *(enrich)*
|
|
150
|
+
- Show provenance and support, and publish the updated signal *(renderer)*
|
|
151
|
+
|
|
152
|
+
### Documentation
|
|
153
|
+
|
|
154
|
+
- Document the second stat, and release 0.4.0
|
|
155
|
+
|
|
156
|
+
## [0.3.1] - 2026-07-30
|
|
157
|
+
|
|
158
|
+
### Documentation
|
|
159
|
+
|
|
160
|
+
- Point at the index template repository
|
|
161
|
+
|
|
162
|
+
## [0.3.0] - 2026-07-30
|
|
163
|
+
|
|
164
|
+
### Added
|
|
165
|
+
|
|
166
|
+
- Own the pipeline in the index repo, and harden the gate *(ci)* **BREAKING**
|
|
167
|
+
- **Migration:** the reusable workflows `grimoire-rs/indexer/.github/workflows/index-{pages,validate}.yml` and the GitLab remote include are gone. An index scaffolded on 0.2.x keeps working on its pinned tag; to move, bump the dependency, add a `ci` block to index.config.json, run `npm run ci`, and delete the old thin callers - `ci --check` reports them as stale.
|
|
168
|
+
|
|
169
|
+
## [0.2.2] - 2026-07-28
|
|
170
|
+
|
|
171
|
+
### Fixed
|
|
172
|
+
|
|
173
|
+
- Stop defaulting the keys that name one specific index *(config)*
|
|
174
|
+
|
|
175
|
+
## [0.2.1] - 2026-07-28
|
|
367
176
|
|
|
368
177
|
### Fixed
|
|
369
178
|
|
|
370
|
-
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
[
|
|
179
|
+
- Stop gitignoring the index's own public/ directory *(init)*
|
|
180
|
+
|
|
181
|
+
## [0.2.0] - 2026-07-28
|
|
182
|
+
|
|
183
|
+
### Added
|
|
184
|
+
|
|
185
|
+
- Write a contents sidecar from the artifact payload *(enrich)*
|
|
186
|
+
- Add a header logo, and let an index drop the attribution *(config)*
|
|
187
|
+
- Rebuild the hero and the package page *(renderer)*
|
|
188
|
+
|
|
189
|
+
## [0.1.9] - 2026-07-28
|
|
190
|
+
|
|
191
|
+
### Added
|
|
192
|
+
|
|
193
|
+
- Offer the index as a one-click VS Code add-registry link *(renderer)*
|
|
194
|
+
|
|
195
|
+
## [0.1.8] - 2026-07-28
|
|
196
|
+
|
|
197
|
+
### Fixed
|
|
198
|
+
|
|
199
|
+
- Hand the gate every changed path, unfiltered *(validate)*
|
|
200
|
+
|
|
201
|
+
## [0.1.7] - 2026-07-28
|
|
202
|
+
|
|
203
|
+
### Added
|
|
204
|
+
|
|
205
|
+
- Read package READMEs, logos and versions from the registry (#1) *(enrich)*
|
|
206
|
+
|
|
207
|
+
## [0.1.6] - 2026-07-28
|
|
208
|
+
|
|
209
|
+
### Fixed
|
|
210
|
+
|
|
211
|
+
- Give the GitLab gate the git it shells out to *(ci)*
|
|
212
|
+
|
|
213
|
+
## [0.1.5] - 2026-07-28
|
|
214
|
+
|
|
215
|
+
### Fixed
|
|
216
|
+
|
|
217
|
+
- Resolve every internal URL against the site's base path *(renderer)*
|
|
218
|
+
|
|
219
|
+
## [0.1.4] - 2026-07-28
|
|
220
|
+
|
|
221
|
+
### Documentation
|
|
222
|
+
|
|
223
|
+
- Say the gate does not cover a first-party announce *(init)*
|
|
224
|
+
- Record what the live end-to-end trial settled
|
|
225
|
+
|
|
226
|
+
### Fixed
|
|
227
|
+
|
|
228
|
+
- Point --with-skills announce at the scaffolded repo *(init)*
|
|
229
|
+
- Name the status check branch protection can require *(init)*
|
|
230
|
+
|
|
231
|
+
## [0.1.3] - 2026-07-28
|
|
232
|
+
|
|
233
|
+
### Fixed
|
|
234
|
+
|
|
235
|
+
- Ship the reusable workflows the scaffold points at *(ci)*
|
|
236
|
+
|
|
237
|
+
## [0.1.2] - 2026-07-28
|
|
238
|
+
|
|
239
|
+
### Fixed
|
|
240
|
+
|
|
241
|
+
- Declare the repository provenance attests to
|
|
242
|
+
|
|
243
|
+
## [0.1.1] - 2026-07-28
|
|
244
|
+
|
|
245
|
+
### Added
|
|
246
|
+
|
|
247
|
+
- Add the grimoire-index renderer, gate and CLI
|
|
248
|
+
|
|
249
|
+
### Changed
|
|
250
|
+
|
|
251
|
+
- Publish as @grimoire-rs/indexer
|
|
252
|
+
- Name the binary grim-indexer
|
|
253
|
+
|
|
254
|
+
### Documentation
|
|
255
|
+
|
|
256
|
+
- State the real status and warn off the broken 0.1.0
|
|
257
|
+
|
|
258
|
+
### Fixed
|
|
259
|
+
|
|
260
|
+
- Declare a bin npm will not silently strip
|
|
261
|
+
|
|
262
|
+
[0.5.4]: https://github.com/grimoire-rs/indexer/compare/v0.5.3...v0.5.4
|
|
393
263
|
[0.5.3]: https://github.com/grimoire-rs/indexer/compare/v0.5.2...v0.5.3
|
|
394
264
|
[0.5.2]: https://github.com/grimoire-rs/indexer/compare/v0.5.1...v0.5.2
|
|
395
265
|
[0.5.1]: https://github.com/grimoire-rs/indexer/compare/v0.5.0...v0.5.1
|
|
396
266
|
[0.5.0]: https://github.com/grimoire-rs/indexer/compare/v0.4.4...v0.5.0
|
|
267
|
+
[0.4.4]: https://github.com/grimoire-rs/indexer/compare/v0.4.3...v0.4.4
|
|
268
|
+
[0.4.3]: https://github.com/grimoire-rs/indexer/compare/v0.4.2...v0.4.3
|
|
269
|
+
[0.4.2]: https://github.com/grimoire-rs/indexer/compare/v0.4.1...v0.4.2
|
|
270
|
+
[0.4.1]: https://github.com/grimoire-rs/indexer/compare/v0.4.0...v0.4.1
|
|
271
|
+
[0.4.0]: https://github.com/grimoire-rs/indexer/compare/v0.3.3...v0.4.0
|
|
272
|
+
[0.3.1]: https://github.com/grimoire-rs/indexer/compare/v0.3.0...v0.3.1
|
|
273
|
+
[0.3.0]: https://github.com/grimoire-rs/indexer/compare/v0.2.2...v0.3.0
|
|
274
|
+
[0.2.2]: https://github.com/grimoire-rs/indexer/compare/v0.2.1...v0.2.2
|
|
275
|
+
[0.2.1]: https://github.com/grimoire-rs/indexer/compare/v0.2.0...v0.2.1
|
|
276
|
+
[0.2.0]: https://github.com/grimoire-rs/indexer/compare/v0.1.9...v0.2.0
|
|
277
|
+
[0.1.9]: https://github.com/grimoire-rs/indexer/compare/v0.1.8...v0.1.9
|
|
278
|
+
[0.1.8]: https://github.com/grimoire-rs/indexer/compare/v0.1.7...v0.1.8
|
|
279
|
+
[0.1.7]: https://github.com/grimoire-rs/indexer/compare/v0.1.6...v0.1.7
|
|
280
|
+
[0.1.6]: https://github.com/grimoire-rs/indexer/compare/v0.1.5...v0.1.6
|
|
281
|
+
[0.1.5]: https://github.com/grimoire-rs/indexer/compare/v0.1.4...v0.1.5
|
|
282
|
+
[0.1.4]: https://github.com/grimoire-rs/indexer/compare/v0.1.3...v0.1.4
|
|
283
|
+
[0.1.3]: https://github.com/grimoire-rs/indexer/compare/v0.1.2...v0.1.3
|
|
284
|
+
[0.1.2]: https://github.com/grimoire-rs/indexer/compare/v0.1.1...v0.1.2
|
|
285
|
+
[0.1.1]: https://github.com/grimoire-rs/indexer/tree/v0.1.1
|
|
286
|
+
|
package/README.md
CHANGED
|
@@ -95,6 +95,32 @@ task dev -- --help
|
|
|
95
95
|
|
|
96
96
|
`task --list` has the rest; `task check` is the whole gate CI runs.
|
|
97
97
|
|
|
98
|
+
### Cutting a release
|
|
99
|
+
|
|
100
|
+
`CHANGELOG.md` is generated from git history by git-cliff and rewritten whole
|
|
101
|
+
on every release, so an entry is only ever as good as the commit subject it
|
|
102
|
+
came from — write the subject for the person reading the changelog. Non-`feat`,
|
|
103
|
+
non-`fix` types are grouped or skipped per `cliff.toml`. `task
|
|
104
|
+
release:changelog:preview` shows what the next release would say.
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
task release:prepare # menu: auto | patch | minor | major
|
|
108
|
+
task release:prepare BUMP=minor # or name the level outright
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`auto` takes the level from those same subjects (`cliff.toml`'s `[bump]` rules:
|
|
112
|
+
a feat is a minor bump, a breaking change is not yet a major one). It is a
|
|
113
|
+
second opinion — a subject that undersells its change bumps too little, and the
|
|
114
|
+
other three levels are for saying so.
|
|
115
|
+
|
|
116
|
+
The task writes the version into `package.json` and the lockfile, regenerates
|
|
117
|
+
`CHANGELOG.md` under the new tag, and runs `task check`. Nothing is committed:
|
|
118
|
+
review the diff, then run the three commands it prints. Pushing the `v*` tag is
|
|
119
|
+
what publishes — see `.github/workflows/release.yml`.
|
|
120
|
+
|
|
121
|
+
`task release:changelog` regenerates the file without releasing, which is what
|
|
122
|
+
a commit landing between releases needs.
|
|
123
|
+
|
|
98
124
|
The docs site is a separate toolchain and deliberately not part of `check` —
|
|
99
125
|
`check` must stay runnable with no Python present. `task docs:serve` previews
|
|
100
126
|
it, `task docs:build` is the strict build the `pages` workflow gates PRs with.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ratings.d.ts","sourceRoot":"","sources":["../../src/cli/ratings.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ratings.d.ts","sourceRoot":"","sources":["../../src/cli/ratings.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAsG1D,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgF7D"}
|
package/dist/cli/ratings.js
CHANGED
|
@@ -50,6 +50,24 @@ function forgeEnv(provider) {
|
|
|
50
50
|
}
|
|
51
51
|
return { api: api ?? "", project, token };
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* The forge host to publish as `providers.rating_host`, derived from the
|
|
55
|
+
* GraphQL endpoint this run actually talked to.
|
|
56
|
+
*
|
|
57
|
+
* Derived rather than configured, so it can never disagree with where the
|
|
58
|
+
* threads were created — and derived per run, so an operator who moves the
|
|
59
|
+
* instance publishes the new host without touching `index.config.json`.
|
|
60
|
+
* `undefined` for an endpoint that does not parse, which drops the key
|
|
61
|
+
* rather than publishing a value no consumer could dial.
|
|
62
|
+
*/
|
|
63
|
+
function ratingHost(api) {
|
|
64
|
+
try {
|
|
65
|
+
return new URL(api).host || undefined;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
53
71
|
/** Every ref in `index/`. The tally runs before `build`, so `all.json` does not exist yet. */
|
|
54
72
|
function desiredRefs(root, findMetadataFiles) {
|
|
55
73
|
const refs = [];
|
|
@@ -129,7 +147,17 @@ export async function ratings(root) {
|
|
|
129
147
|
}
|
|
130
148
|
for (const conflict of result.conflicts)
|
|
131
149
|
console.error(conflictWarning(conflict));
|
|
132
|
-
const
|
|
150
|
+
const merged = mergeStats(seed, "rating", cfg.provider, result.fresh);
|
|
151
|
+
// Replaced or dropped every run, never carried: a seed's `rating_host` is a
|
|
152
|
+
// claim about an endpoint this run may no longer be using, and a consumer
|
|
153
|
+
// sends a credential to it.
|
|
154
|
+
const providers = { ...merged.providers };
|
|
155
|
+
const host = ratingHost(forge.api);
|
|
156
|
+
if (host === undefined)
|
|
157
|
+
delete providers.rating_host;
|
|
158
|
+
else
|
|
159
|
+
providers.rating_host = host;
|
|
160
|
+
const doc = statsDocument({ ...merged, providers });
|
|
133
161
|
fs.writeFileSync(path.join(rootDir, STATS_FILE), JSON.stringify(doc, null, 2) + "\n");
|
|
134
162
|
console.log(logLine(result));
|
|
135
163
|
return EXIT.ok;
|
package/dist/cli/ratings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ratings.js","sourceRoot":"","sources":["../../src/cli/ratings.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ratings.js","sourceRoot":"","sources":["../../src/cli/ratings.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,7 @@ const { choices, label, title } = Astro.props;
|
|
|
48
48
|
aria-checked={i === 0 ? "true" : "false"}
|
|
49
49
|
data-os-pick={choice.command}
|
|
50
50
|
data-os-name={choice.name}
|
|
51
|
+
data-os-href={choice.href}
|
|
51
52
|
>
|
|
52
53
|
{choice.path ? <BrandMark path={choice.path} /> : choice.Icon && <choice.Icon size={16} />}
|
|
53
54
|
<span>{choice.name}</span>
|
|
@@ -104,6 +104,12 @@ const { title, description, image = config.logo ?? config.favicon } = Astro.prop
|
|
|
104
104
|
for (const glyph of bar.querySelectorAll("[data-os-glyph]")) {
|
|
105
105
|
glyph.hidden = glyph.dataset.osGlyph !== pick.dataset.osName;
|
|
106
106
|
}
|
|
107
|
+
// The action segment follows the choice where it has one to follow:
|
|
108
|
+
// the registry bar's VS Code link carries the scope the command names,
|
|
109
|
+
// so picking Global cannot leave the button writing project config.
|
|
110
|
+
// A choice with no href leaves the link alone rather than blanking it.
|
|
111
|
+
const link = bar.querySelector("[data-os-link]");
|
|
112
|
+
if (link && pick.dataset.osHref) link.href = pick.dataset.osHref;
|
|
107
113
|
};
|
|
108
114
|
|
|
109
115
|
// The platform a bar should start on, or null for one this visitor's
|
|
@@ -87,6 +87,13 @@ export declare function vscodeVoteUrl(extension: string | null, ref: string): st
|
|
|
87
87
|
* `vscode://<publisher.extension>/add-registry?index=<url>&alias=<name>` — the
|
|
88
88
|
* one-click counterpart of the `grim config registry add` line beside it.
|
|
89
89
|
*
|
|
90
|
+
* `scope` carries the Scope picker sitting in the same bar, so the button
|
|
91
|
+
* writes where the copyable command says it would. The extension clamps it
|
|
92
|
+
* rather than trusting it — with no folder open the write is global whatever
|
|
93
|
+
* the link asked for — and words its confirmation modal off the RESULT, so a
|
|
94
|
+
* page steering a machine-wide write is what the user reads before agreeing.
|
|
95
|
+
* Omitting it leaves the extension on its own host-derived default.
|
|
96
|
+
*
|
|
90
97
|
* Null unless the link would actually work: the handler takes https only (an
|
|
91
98
|
* index locator is fetched with whatever credentials the user configures for
|
|
92
99
|
* it), refuses embedded credentials, and caps the URL at 2048 characters.
|
|
@@ -96,7 +103,7 @@ export declare function vscodeVoteUrl(extension: string | null, ref: string): st
|
|
|
96
103
|
export declare function addRegistryUrl(extension: string | null, registry: {
|
|
97
104
|
alias: string;
|
|
98
105
|
index: string;
|
|
99
|
-
} | null): string | null;
|
|
106
|
+
} | null, scope?: "global" | "project"): string | null;
|
|
100
107
|
/**
|
|
101
108
|
* A bundle member's `id` resolved to the reference the index stores.
|
|
102
109
|
*
|
|
@@ -183,13 +183,20 @@ const REGISTRY_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/;
|
|
|
183
183
|
* `vscode://<publisher.extension>/add-registry?index=<url>&alias=<name>` — the
|
|
184
184
|
* one-click counterpart of the `grim config registry add` line beside it.
|
|
185
185
|
*
|
|
186
|
+
* `scope` carries the Scope picker sitting in the same bar, so the button
|
|
187
|
+
* writes where the copyable command says it would. The extension clamps it
|
|
188
|
+
* rather than trusting it — with no folder open the write is global whatever
|
|
189
|
+
* the link asked for — and words its confirmation modal off the RESULT, so a
|
|
190
|
+
* page steering a machine-wide write is what the user reads before agreeing.
|
|
191
|
+
* Omitting it leaves the extension on its own host-derived default.
|
|
192
|
+
*
|
|
186
193
|
* Null unless the link would actually work: the handler takes https only (an
|
|
187
194
|
* index locator is fetched with whatever credentials the user configures for
|
|
188
195
|
* it), refuses embedded credentials, and caps the URL at 2048 characters.
|
|
189
196
|
* Checking here keeps a broken button off the page rather than putting the
|
|
190
197
|
* failure in the user's hands.
|
|
191
198
|
*/
|
|
192
|
-
export function addRegistryUrl(extension, registry) {
|
|
199
|
+
export function addRegistryUrl(extension, registry, scope) {
|
|
193
200
|
if (!extension || !registry || !REGISTRY_ALIAS.test(registry.alias))
|
|
194
201
|
return null;
|
|
195
202
|
let url;
|
|
@@ -204,6 +211,8 @@ export function addRegistryUrl(extension, registry) {
|
|
|
204
211
|
if (url.href.length > 2048)
|
|
205
212
|
return null;
|
|
206
213
|
const query = new URLSearchParams({ index: url.href, alias: registry.alias });
|
|
214
|
+
if (scope)
|
|
215
|
+
query.set("scope", scope);
|
|
207
216
|
return `vscode://${extension}/add-registry?${query.toString()}`;
|
|
208
217
|
}
|
|
209
218
|
/**
|
|
@@ -238,6 +238,13 @@ const REGISTRY_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/;
|
|
|
238
238
|
* `vscode://<publisher.extension>/add-registry?index=<url>&alias=<name>` — the
|
|
239
239
|
* one-click counterpart of the `grim config registry add` line beside it.
|
|
240
240
|
*
|
|
241
|
+
* `scope` carries the Scope picker sitting in the same bar, so the button
|
|
242
|
+
* writes where the copyable command says it would. The extension clamps it
|
|
243
|
+
* rather than trusting it — with no folder open the write is global whatever
|
|
244
|
+
* the link asked for — and words its confirmation modal off the RESULT, so a
|
|
245
|
+
* page steering a machine-wide write is what the user reads before agreeing.
|
|
246
|
+
* Omitting it leaves the extension on its own host-derived default.
|
|
247
|
+
*
|
|
241
248
|
* Null unless the link would actually work: the handler takes https only (an
|
|
242
249
|
* index locator is fetched with whatever credentials the user configures for
|
|
243
250
|
* it), refuses embedded credentials, and caps the URL at 2048 characters.
|
|
@@ -247,6 +254,7 @@ const REGISTRY_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/;
|
|
|
247
254
|
export function addRegistryUrl(
|
|
248
255
|
extension: string | null,
|
|
249
256
|
registry: { alias: string; index: string } | null,
|
|
257
|
+
scope?: "global" | "project",
|
|
250
258
|
): string | null {
|
|
251
259
|
if (!extension || !registry || !REGISTRY_ALIAS.test(registry.alias)) return null;
|
|
252
260
|
let url: URL;
|
|
@@ -258,6 +266,7 @@ export function addRegistryUrl(
|
|
|
258
266
|
if (url.protocol !== "https:" || url.username !== "" || url.password !== "") return null;
|
|
259
267
|
if (url.href.length > 2048) return null;
|
|
260
268
|
const query = new URLSearchParams({ index: url.href, alias: registry.alias });
|
|
269
|
+
if (scope) query.set("scope", scope);
|
|
261
270
|
return `vscode://${extension}/add-registry?${query.toString()}`;
|
|
262
271
|
}
|
|
263
272
|
|
|
@@ -20,6 +20,13 @@ export interface Choice {
|
|
|
20
20
|
Icon?: (props: {
|
|
21
21
|
size?: number;
|
|
22
22
|
}) => unknown;
|
|
23
|
+
/**
|
|
24
|
+
* Where the bar's action segment should point once this choice is picked.
|
|
25
|
+
* Only the registry bar has one — a deep link that has to agree with the
|
|
26
|
+
* scope the command beside it names — and a bar whose choices carry none
|
|
27
|
+
* leaves its action link exactly as rendered.
|
|
28
|
+
*/
|
|
29
|
+
href?: string;
|
|
23
30
|
}
|
|
24
31
|
/**
|
|
25
32
|
* The installer choices, one per platform rather than one per config row.
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// <CommandBar choices={installChoices(data.config)} noun="install command" … />
|
|
15
15
|
import { FolderRoot, Globe } from "lucide-preact";
|
|
16
16
|
import { mdiApple, mdiConsole, mdiMicrosoftWindows, mdiPenguin, } from "@mdi/js";
|
|
17
|
+
import { addRegistryUrl } from "./catalog.js";
|
|
17
18
|
/**
|
|
18
19
|
* `mdiPenguin`, not `mdiLinux`: Tux's own silhouette is a solid mass that
|
|
19
20
|
* reads as an indistinct blob at 16px, where the plainer penguin keeps its
|
|
@@ -74,9 +75,15 @@ export function registryScopeChoices(config, registry = config.registry) {
|
|
|
74
75
|
const add = registryAddCommand(config, registry);
|
|
75
76
|
if (!add)
|
|
76
77
|
return [];
|
|
78
|
+
const link = (scope) => addRegistryUrl(config.vscodeExtension, registry, scope) ?? undefined;
|
|
77
79
|
return [
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
+
{
|
|
81
|
+
name: "Global",
|
|
82
|
+
command: `grim --global ${add.slice("grim ".length)}`,
|
|
83
|
+
Icon: Globe,
|
|
84
|
+
href: link("global"),
|
|
85
|
+
},
|
|
86
|
+
{ name: "Project", command: add, Icon: FolderRoot, href: link("project") },
|
|
80
87
|
];
|
|
81
88
|
}
|
|
82
89
|
/**
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
mdiPenguin,
|
|
22
22
|
} from "@mdi/js";
|
|
23
23
|
import type { RegistryHint, ResolvedSiteConfig } from "../../../config.js";
|
|
24
|
+
import { addRegistryUrl } from "./catalog.js";
|
|
24
25
|
|
|
25
26
|
// Re-exported so an index's own page can name the shape it passes to the two
|
|
26
27
|
// functions below without reaching past `@grim/lib/*` into the package's
|
|
@@ -45,6 +46,13 @@ export interface Choice {
|
|
|
45
46
|
path?: string;
|
|
46
47
|
/** Lucide component, taking a `size` prop. */
|
|
47
48
|
Icon?: (props: { size?: number }) => unknown;
|
|
49
|
+
/**
|
|
50
|
+
* Where the bar's action segment should point once this choice is picked.
|
|
51
|
+
* Only the registry bar has one — a deep link that has to agree with the
|
|
52
|
+
* scope the command beside it names — and a bar whose choices carry none
|
|
53
|
+
* leaves its action link exactly as rendered.
|
|
54
|
+
*/
|
|
55
|
+
href?: string;
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
/**
|
|
@@ -115,9 +123,16 @@ export function registryScopeChoices(
|
|
|
115
123
|
): Choice[] {
|
|
116
124
|
const add = registryAddCommand(config, registry);
|
|
117
125
|
if (!add) return [];
|
|
126
|
+
const link = (scope: "global" | "project") =>
|
|
127
|
+
addRegistryUrl(config.vscodeExtension, registry, scope) ?? undefined;
|
|
118
128
|
return [
|
|
119
|
-
{
|
|
120
|
-
|
|
129
|
+
{
|
|
130
|
+
name: "Global",
|
|
131
|
+
command: `grim --global ${add.slice("grim ".length)}`,
|
|
132
|
+
Icon: Globe,
|
|
133
|
+
href: link("global"),
|
|
134
|
+
},
|
|
135
|
+
{ name: "Project", command: add, Icon: FolderRoot, href: link("project") },
|
|
121
136
|
];
|
|
122
137
|
}
|
|
123
138
|
|
|
@@ -14,7 +14,11 @@ const { config, packages } = data;
|
|
|
14
14
|
// One-click counterpart of the `grim config registry add` line: the VS Code
|
|
15
15
|
// extension registers a URI handler that writes the registry after a modal
|
|
16
16
|
// confirmation. Null whenever the link would not work — see `addRegistryUrl`.
|
|
17
|
-
|
|
17
|
+
//
|
|
18
|
+
// Scoped `global` because that is the choice the picker beside it starts on;
|
|
19
|
+
// picking Project rewrites this href from `data-os-href` (see `__grimPick`),
|
|
20
|
+
// so the two halves of the bar never disagree about where the write lands.
|
|
21
|
+
const addRegistry = addRegistryUrl(config.vscodeExtension, config.registry, "global");
|
|
18
22
|
|
|
19
23
|
// The extension's own marketplace page — the one thing on this page that
|
|
20
24
|
// helps a visitor who does not have it installed yet.
|
|
@@ -91,6 +95,7 @@ const scopeChoices = registryScopeChoices(config);
|
|
|
91
95
|
<a
|
|
92
96
|
slot="action"
|
|
93
97
|
class="seg brand-link"
|
|
98
|
+
data-os-link
|
|
94
99
|
href={addRegistry}
|
|
95
100
|
title="Add this index via VS Code"
|
|
96
101
|
aria-label="Add this index via VS Code"
|