@grimoire-rs/indexer 0.4.4 → 0.5.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +270 -0
  2. package/NOTICE +30 -0
  3. package/README.md +76 -331
  4. package/dist/cli/dev.d.ts +14 -0
  5. package/dist/cli/dev.d.ts.map +1 -1
  6. package/dist/cli/dev.js +22 -1
  7. package/dist/cli/dev.js.map +1 -1
  8. package/dist/cli/init.d.ts.map +1 -1
  9. package/dist/cli/init.js +35 -4
  10. package/dist/cli/init.js.map +1 -1
  11. package/dist/cli/main.d.ts.map +1 -1
  12. package/dist/cli/main.js +5 -0
  13. package/dist/cli/main.js.map +1 -1
  14. package/dist/config.d.ts +107 -7
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/config.js +181 -36
  17. package/dist/config.js.map +1 -1
  18. package/dist/renderer/astro/components/CardLogo.d.ts +5 -0
  19. package/dist/renderer/astro/components/CardLogo.js +58 -0
  20. package/dist/renderer/astro/components/CardLogo.tsx +96 -0
  21. package/dist/renderer/astro/components/Catalog.d.ts +14 -1
  22. package/dist/renderer/astro/components/Catalog.js +573 -108
  23. package/dist/renderer/astro/components/Catalog.tsx +903 -349
  24. package/dist/renderer/astro/components/CodeBlock.astro +74 -0
  25. package/dist/renderer/astro/components/CommandBar.astro +66 -0
  26. package/dist/renderer/astro/components/CopyButton.d.ts +7 -0
  27. package/dist/renderer/astro/components/CopyButton.js +28 -0
  28. package/dist/renderer/astro/components/CopyButton.tsx +56 -0
  29. package/dist/renderer/astro/components/KindMark.d.ts +69 -0
  30. package/dist/renderer/astro/components/KindMark.js +66 -0
  31. package/dist/renderer/astro/components/KindMark.tsx +141 -0
  32. package/dist/renderer/astro/components/PackageCard.d.ts +18 -0
  33. package/dist/renderer/astro/components/PackageCard.js +50 -0
  34. package/dist/renderer/astro/components/PackageCard.tsx +273 -0
  35. package/dist/renderer/astro/components/PackageRow.d.ts +10 -0
  36. package/dist/renderer/astro/components/PackageRow.js +32 -0
  37. package/dist/renderer/astro/components/PackageRow.tsx +126 -0
  38. package/dist/renderer/astro/components/PickerMenu.astro +5 -14
  39. package/dist/renderer/astro/components/SiteFooter.astro +64 -0
  40. package/dist/renderer/astro/components/SiteHeader.astro +74 -0
  41. package/dist/renderer/astro/components/VersionMenu.astro +2 -2
  42. package/dist/renderer/astro/layouts/Base.astro +970 -227
  43. package/dist/renderer/astro/lib/base.d.ts +25 -0
  44. package/dist/renderer/astro/lib/base.js +23 -0
  45. package/dist/renderer/astro/lib/base.ts +27 -0
  46. package/dist/renderer/astro/lib/catalog.d.ts +24 -0
  47. package/dist/renderer/astro/lib/catalog.js +36 -0
  48. package/dist/renderer/astro/lib/catalog.ts +37 -0
  49. package/dist/renderer/astro/lib/code.d.ts +2 -2
  50. package/dist/renderer/astro/lib/code.js +2 -2
  51. package/dist/renderer/astro/lib/code.ts +2 -2
  52. package/dist/renderer/astro/lib/commands.d.ts +64 -0
  53. package/dist/renderer/astro/lib/commands.js +91 -0
  54. package/dist/renderer/astro/lib/commands.ts +133 -0
  55. package/dist/renderer/astro/lib/keywordRail.d.ts +44 -0
  56. package/dist/renderer/astro/lib/keywordRail.js +99 -0
  57. package/dist/renderer/astro/lib/keywordRail.ts +110 -0
  58. package/dist/renderer/astro/pages/index.astro +40 -87
  59. package/dist/renderer/astro/pages/p/[...slug].astro +349 -198
  60. package/dist/renderer/astro/styles/tokens.css +40 -5
  61. package/dist/renderer/index.d.ts +77 -0
  62. package/dist/renderer/index.d.ts.map +1 -1
  63. package/dist/renderer/index.js +565 -7
  64. package/dist/renderer/index.js.map +1 -1
  65. package/dist/renderer/types.d.ts +9 -0
  66. package/dist/renderer/types.d.ts.map +1 -1
  67. package/package.json +9 -4
  68. package/templates/README.md +6 -0
  69. package/templates/gitignore +4 -1
  70. package/templates/theme/README.md +38 -0
  71. package/templates/tsconfig.json +47 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,270 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@grimoire-rs/indexer` are recorded here, in
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format. This project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
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
+ Component overrides sit in the **Unstable** tier of the
13
+ [stability table](docs/reference/theme-overlay.md#stability): their file paths
14
+ 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.
16
+
17
+ An entry for such a move carries both halves or it announces nothing an
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 }`.
21
+
22
+ ## [Unreleased]
23
+
24
+ ## [0.5.1] - 2026-08-31
25
+
26
+ ### Added
27
+
28
+ - **`grim-indexer dev --host [addr]`.** Bare, it binds every interface; with a
29
+ value, that address. Without it the server binds loopback only — Astro's own
30
+ default — which is unreachable from a dev container, a VM or a WSL guest,
31
+ where the port forwards and the connection then hangs against a socket that
32
+ is not listening for it. `npm run dev -- --host` takes the same two forms.
33
+ Bare `--host` puts the preview on your network; the CLI reference says so.
34
+ - **`CodeBlock.astro`**, a reusable code block: the site's own frame, the same
35
+ Shiki theme pair every rendered README uses, the same copy button and toast,
36
+ and an optional VS Code button. Props
37
+ `{ code, lang?, name?, vscodeHref?, vscodeLabel? }`; `vscodeHref` is a plain
38
+ URL, so `vscodeUrl`, `vscodeVoteUrl`, `addRegistryUrl` and a hand-written
39
+ deep link all work. Worked example in
40
+ [Reuse shipped components](docs/how-to/reuse-components.md#code-blocks).
41
+ - **`data-slot="code-block"`**, for it. Contract tier, like every other slot.
42
+ - **A second argument on `registryAddCommand` and `registryScopeChoices`**,
43
+ the registry to build the command for — defaulting to the one in your config,
44
+ so nothing existing changes. It is what lets a setup page draw the "add
45
+ registry" bar for an index *other* than the site's own: a corporate index in
46
+ the hero and the public one further down.
47
+ - **A clear button on the keyword filters**, in the catalog toolbar. Rendered
48
+ only while a keyword is picked, and it lifts the keywords alone — Escape is
49
+ still what clears the search and the kinds with them.
50
+
51
+ ### Fixed
52
+
53
+ - **The keyword overflow menu opened invisibly.** Its panel was an absolutely
54
+ positioned child of the toolbar's filter row, which is a scroll container, so
55
+ the panel was cropped to the row and stretched the row's scroll extent — a
56
+ menu nobody could see, with a stray horizontal and vertical scrollbar to show
57
+ for it. It is a popover now, which puts it in the top layer, outside every
58
+ ancestor's `overflow`, and brings Escape and light dismiss with it. The
59
+ trigger is a `<button>` rather than a `<summary>`, so the toolbar's arrow-key
60
+ navigation now reaches it.
61
+ - **The detail page's logo drifted down under a long description.** The header
62
+ centred the tile against the text beside it, so the same package's mark sat
63
+ at a different height on every page. It holds against the title now.
64
+ - **Dropped the tinted square behind a package logo**, on the cards, the list
65
+ rows and the detail header alike. A logo is a designed mark already sitting
66
+ on its own ground, so the slot framed it twice — most visibly for the many
67
+ logos that are themselves a rounded square, which then sat inside a slightly
68
+ larger one. The slot still reserves the same box, so nothing shifts. The
69
+ dashed frame the broken-logo state drew goes with it — it read as a fault in
70
+ the layout rather than in the image; the slashed glyph is what says the logo
71
+ failed, and `role="img"` with a label is what announces it. The
72
+ initial-letter tile a package with no logo gets is unchanged: there the
73
+ coloured ground is the mark.
74
+ - **The dev server's URL is a legal URL when the server binds an IPv6
75
+ address.** An unbracketed literal reads its own colons as a port, so
76
+ `http://::1:4321/` threw `ERR_INVALID_URL` at the first `new URL` against it
77
+ and took `dev:smoke` down with a message naming neither the address nor the
78
+ host. Wildcard binds still become `localhost`; anything carrying a colon is
79
+ bracketed.
80
+ - **The detail page's logo tile is a fixed square.** `aspect-ratio: 1` derived
81
+ its width from the height the box had *before* `align-self: stretch` grew it,
82
+ so it rendered 56x93 beside a logo and 56x70 beside a letter — portrait,
83
+ never square, and narrow enough to read as bounding the image rather than
84
+ framing it.
85
+ - **The list row's glyphs sit on the row's centre.** `vertical-align: middle`
86
+ aligns to half the parent's x-height, about 2px under the line's true middle
87
+ at this step, and the upvote arrow's optical nudge added a third pixel the
88
+ same way. The kind and rating cells are flex boxes now and centre their
89
+ contents as boxes.
90
+ - **Keyword chips could freeze part-way through the rail's slide.** The rail
91
+ animates a rescore by inverting each chip with an inline `translate` and
92
+ dropping it on the next animation frame. A rescore that also changes how many
93
+ chips fit commits a second time, and that commit cancelled the frame before
94
+ it ran — leaving every moved chip parked at its offset with transitions
95
+ disabled. Deselecting the last keyword hit it most often, because that
96
+ rescore is the largest. The offsets are now cleared before each measurement
97
+ and on cleanup, so an interrupted slide resolves instead of sticking.
98
+ - **Switching between the cards and list views repainted the whole catalog.**
99
+ Off-screen cards are skipped until they are scrolled to. The two views share
100
+ no element types, so a switch still rebuilds every item — past a few hundred
101
+ packages the answer is windowing the list, and this is not that.
102
+
103
+ ## [0.5.0] - 2026-08-30
104
+
105
+ ### Added
106
+
107
+ - **Theme overlay.** A `theme/` directory in an index repo is copied over the
108
+ renderer's staged sources before every build. A file at a path the renderer
109
+ does not ship adds one — `theme/pages/setup.astro` becomes `/setup/` — and a
110
+ file at a path it does ship replaces it. Structure is customizable now, not
111
+ just CSS. Only on the staged-copy path: a caller-supplied `srcDir` is left
112
+ alone.
113
+ - **Two paths the overlay refuses**, `theme/lib/**` and a root
114
+ `theme/content.config.ts`, so the renderer stays free to move its own helpers
115
+ and its one content-collection entrypoint. Each prints a line to stderr and
116
+ the build still succeeds. The same rule applies to `dev`'s mirror, because a
117
+ deny-list only one of the two writers honours lets an author develop against
118
+ a file the build then drops in silence. It is a compatibility guard, not a
119
+ security boundary: the copy does not follow symlinks either way.
120
+ - **`@grim/*` import specifier**, resolving to the renderer's sources so an
121
+ added page reaches the layout, components and helpers without a relative
122
+ path that encodes how deep it sits under `pages/`. It resolves *after* the
123
+ overlay, so an index that replaced a component imports its own.
124
+ - **`@grim-original/*`**, the same tree as it was *before* the overlay ran, so
125
+ an override can wrap the file it replaced instead of owning it outright.
126
+ `@grim/*` cannot serve that purpose once the theme has taken the path, and
127
+ the package's `exports` do not publish the Astro sources for a deep import.
128
+ - **One stderr line per overlaid path that replaces a shipped file**, naming
129
+ the path and the indexer version that shipped it. That is what makes the
130
+ Unstable tier below honest without a manifest. A path that only adds a file
131
+ is not logged.
132
+ - **`dev` mirrors `theme/**` edits** into the staged tree, so a page reloads as
133
+ it is saved. It creates `theme/` first if it is absent — a directory added
134
+ after the server started now mirrors instead of 404ing forever — and removes
135
+ it again on shutdown if you left it empty. Deletes are still not mirrored;
136
+ restart for those. A fault in the platform's recursive-watch backend disables
137
+ mirroring with a message rather than taking the server down.
138
+ - **`nav` config key.** An ordered `{label, href}` list that takes the header
139
+ over. Unset, it synthesizes exactly what the header has always shown, so an
140
+ index that predates the key renders unchanged; `[]` leaves the theme toggle
141
+ standing alone.
142
+ - **`notice` config key.** One line above the page content, in the site's own
143
+ width, on every page, carrying `data-slot="site-notice"`. Named `notice`
144
+ rather than `banner` because `--grim-color-banner-*` is the existing amber
145
+ palette for the deprecated-package banner, and a key called `banner` would
146
+ invite an index runner to override that token family by mistake.
147
+ - **`nav[].external` and `footerLinks[].external`.** Optional per entry, and it
148
+ decides only the new-tab affordance — the deployment base prefix is applied
149
+ either way. Unset keeps the old inference from the href's shape. `false` is
150
+ the case that inference cannot express: an absolute URL that is still your
151
+ own site, a staging host or an intranet mirror.
152
+ - **A build-time warning for a `nav` or `footerLinks` href that leads nowhere.**
153
+ A `/`-rooted href matching no emitted route and no `public/` file prints
154
+ `nav[0].href "/setup/": nothing is published at that path — the link will
155
+ 404`. It warns and never fails: a path served by something outside the build
156
+ is indistinguishable from a typo, and refusing a whole site over a footer
157
+ typo is worse than the typo. Checked after the build, which is the one moment
158
+ both the emitted routes and every `public/` layer exist at once.
159
+ - **A warning for an unrecognised top-level key in `index.config.json`**,
160
+ naming the key. Without it a typo — or a config predating the `banner` →
161
+ `notice` rename — loaded clean and silently rendered nothing.
162
+ - **`init` scaffolds `theme/README.md` and a `tsconfig.json`** mapping
163
+ `@grim/*` for editors. The README states where a page goes and which parts of
164
+ the overlay are promised, which a `.gitkeep` could not; both reserve `theme/`
165
+ for git equally well. `theme/pages/` is no longer created empty. The build
166
+ does not read that tsconfig.
167
+ - **A documentation site** (MkDocs Material, Diátaxis), built `--strict` as the
168
+ docs' pre-merge gate and published to GitHub Pages. `task docs:build`,
169
+ `docs:serve`, `docs:clean` — deliberately not part of `task check`, which
170
+ must stay runnable with no Python toolchain.
171
+ - **Individually replaceable components**: `SiteHeader`, `SiteFooter`,
172
+ `CommandBar`, `CopyButton`, `CardLogo`, `PackageCard`, `PackageRow`.
173
+ - **This changelog**, which two docs pages already made the sole mitigation for
174
+ the Unstable tier. It ships in the npm tarball, so the copy that matches your
175
+ pinned version is `node_modules/@grimoire-rs/indexer/CHANGELOG.md`.
176
+ - **`npm run typecheck:tests`**, type-checking the `test` tree under its own
177
+ `tsconfig.test.json`. Deliberately not wired into `task check` yet: the tree
178
+ has 95 real type errors, which is its own piece of work.
179
+
180
+ ### Changed
181
+
182
+ - **`footerLinks[].href` now accepts a site-root path** (`/setup/`) as well as
183
+ an absolute `http(s)` URL — previously `http(s)` only. `nav` takes the same
184
+ rule from one shared validator, and so now do `logo` and `favicon`, which had
185
+ three different answers between them and one that validated nothing. Both
186
+ link keys are checked when the config *loads*, so a `javascript:` or
187
+ protocol-relative href fails the build with the key that carried it, rather
188
+ than reaching a rendered anchor. A bare relative path is still refused: it
189
+ would resolve against whichever page carries the link, and the detail pages
190
+ sit two levels deep.
191
+ - **`/\host/x` and userinfo are refused everywhere a config value becomes a
192
+ URL.** Browsers read `/\host/x` the way they read `//host/x`, and
193
+ `https://good.test@evil.test/` resolves to `evil.test` while reading as
194
+ `good.test`. Two of the four validators already rejected userinfo; all four
195
+ do now.
196
+ - **Footer links go through the deployment base prefix, and honour the same
197
+ new-tab rule as the header.** They did neither before. **This changes an
198
+ existing site:** an `https://` footer link now opens in a new tab. Set
199
+ `"external": false` on the entry to keep it in the same tab.
200
+ - **`Base.astro` no longer contains the header and footer markup** — they are
201
+ `SiteHeader.astro` and `SiteFooter.astro`. Neither takes props: everything
202
+ they draw is build-time config. The head, the centered `main`, the copy toast
203
+ and every default style still come from the layout.
204
+ - **The platform-preselect loop moved into `Base.astro`**, so a `<CommandBar
205
+ detect />` on a page you added under `theme/pages/` preselects the visitor's
206
+ own platform. It used to run only on the shipped landing page, so the same
207
+ markup elsewhere silently showed the configured first choice instead.
208
+ - **`Catalog.tsx` no longer contains the card and row markup** — they are
209
+ `PackageCard.tsx` and `PackageRow.tsx`, and they *do* take props, because a
210
+ component that hydrates in the browser cannot read the build-time payload.
211
+ Those props are the contract the Unstable tier is about.
212
+ - **The install/registry/package command boxes are one `CommandBar`**, with
213
+ their choices derived in `@grim/lib/commands` — so a page an index adds can
214
+ draw the site's real install bar from the site's own config instead of
215
+ restating the command in a code block that drifts.
216
+ - **The renderer ships square.** `--grim-radius-base` is `0px`; set it to `4px`
217
+ to restore the rounding of `0.4.x` and earlier in one line.
218
+ - **Radius tokens are named for their role**: `--grim-radius-sm`/`-md`/`-lg`/
219
+ `-xl` are now `-code`, `-inset`, `-control` and `-surface`, and they derive
220
+ from `--grim-radius-base` rather than carrying their own values. `-pill` is
221
+ unchanged and off the knob. An override under an old name is silently
222
+ ignored, like any unknown property.
223
+ - **The list view leads with the package logo**, then the name, then the kind
224
+ mark.
225
+ - **The README is a pointer to the docs site.** The theming contract, the stats
226
+ sidecar schema and the CLI reference moved into `docs/`.
227
+ - **The scaffolded `tsconfig.json` sets `module` and `moduleResolution`** —
228
+ `esnext`/`bundler`, what actually reads those specifiers — and no longer sets
229
+ `baseUrl`, which is deprecated on the pinned TypeScript and made the file
230
+ fail to load. It stays free of `extends` on purpose.
231
+ - **The docs workflow splits `configure-pages` into its own job**, so the job
232
+ that resolves and executes unpinned transitive PyPI packages holds
233
+ `contents: read` and nothing else — `id-token: write` is a job-wide grant.
234
+ lychee now checks the external links `mkdocs --strict` never resolves and,
235
+ with `--include-fragments`, the `#anchor` half of the internal ones, which
236
+ `--strict` logs at INFO and exits 0 on.
237
+ - **eslint and vitest skip `.agents/worktrees/`.** Both tools walk the tree
238
+ themselves rather than asking git, and neither knew about a path `.gitignore`
239
+ had carried all along: eslint found a `tsconfig.json` per worktree and
240
+ reported a parse error on every file in the repo, and vitest collected and
241
+ ran each worktree's whole suite. A `.gitignore` entry and a tool's own ignore
242
+ list are two independent claims.
243
+
244
+ ### Fixed
245
+
246
+ - **Scaffold → `npm install` → build was broken end to end.** An index repo has
247
+ its own `node_modules`, and the staged root Astro builds in sits inside it,
248
+ so `preact-render-to-string` resolved to a second copy of preact. The first
249
+ hook rendered died with `Cannot read properties of undefined (reading
250
+ 'context')`, in a stack naming preact and lucide and nothing that leads back
251
+ to dependency resolution. Every preact-touching module is pinned to one copy
252
+ now, and `preact-render-to-string` is a declared dependency so it resolves
253
+ under an isolated install layout too.
254
+ - **A replaced header with no theme toggle no longer breaks the rest of the
255
+ page.** The `#theme-toggle` lookup in `Base.astro` is null-safe, so the copy
256
+ buttons, the picker wiring and the toast still run.
257
+ - **A `tsconfig.json` in the index repo that cannot be parsed is now named.**
258
+ It made the build fail while rendering a page with an error about preact; the
259
+ usual cause is an `extends` pointing into a `node_modules` that has not been
260
+ installed yet.
261
+ - **`dev` cleans up after itself.** Stopping the server is idempotent, and a
262
+ failure part-way through staging removes the scratch directory rather than
263
+ leaving it in the index repo. One case is not fixable from inside shutdown
264
+ and is written up in the docs: interrupting `dev` within about a second of
265
+ boot can leave a `.index-*` holding Vite's `deps_temp_<hash>`, which the
266
+ dependency optimizer recreates after the removal has already returned.
267
+
268
+ [Unreleased]: https://github.com/grimoire-rs/indexer/compare/v0.5.1...HEAD
269
+ [0.5.1]: https://github.com/grimoire-rs/indexer/compare/v0.5.0...v0.5.1
270
+ [0.5.0]: https://github.com/grimoire-rs/indexer/compare/v0.4.4...v0.5.0
package/NOTICE ADDED
@@ -0,0 +1,30 @@
1
+ grim-indexer
2
+ Copyright 2026 The Grimoire Authors
3
+
4
+ This product includes software developed by The Grimoire Authors, licensed
5
+ under the Apache License, Version 2.0. See LICENSE.
6
+
7
+ --------------------------------------------------------------------------
8
+ Third-party assets bundled in the rendered site
9
+ --------------------------------------------------------------------------
10
+
11
+ codicons
12
+ https://github.com/microsoft/vscode-codicons
13
+ Copyright (c) Microsoft Corporation
14
+ Licensed under CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/
15
+
16
+ Six glyphs (sparkle, law, agent, mcp, package, warning) are inlined as SVG
17
+ path data in `src/renderer/astro/components/KindMark.tsx` and rendered into
18
+ every built index. Extracted from @vscode/codicons 0.0.45, unmodified. They
19
+ are the same marks the Grimoire VS Code extension shows for each artifact
20
+ kind, so one catalogue reads the same on both surfaces.
21
+
22
+ Lucide
23
+ https://github.com/lucide-icons/lucide
24
+ Copyright (c) Lucide Contributors
25
+ Licensed under the ISC License.
26
+
27
+ Material Design Icons (@mdi/js)
28
+ https://github.com/Templarian/MaterialDesign
29
+ Licensed under the Apache License, Version 2.0.
30
+ Used only for brand marks Lucide does not carry.