@grove-dev/astro 0.2.20 → 0.3.2

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -75
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +11 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/display.d.ts +1 -26
  7. package/dist/lib/display.d.ts.map +1 -1
  8. package/dist/lib/display.js +1 -103
  9. package/dist/lib/display.js.map +1 -1
  10. package/dist/lib/format.d.ts +1 -28
  11. package/dist/lib/format.d.ts.map +1 -1
  12. package/dist/lib/format.js +1 -71
  13. package/dist/lib/format.js.map +1 -1
  14. package/dist/lib/lenses.d.ts +1 -57
  15. package/dist/lib/lenses.d.ts.map +1 -1
  16. package/dist/lib/lenses.js +1 -198
  17. package/dist/lib/lenses.js.map +1 -1
  18. package/dist/lib/repo.d.ts +1 -19
  19. package/dist/lib/repo.d.ts.map +1 -1
  20. package/dist/lib/repo.js +1 -30
  21. package/dist/lib/repo.js.map +1 -1
  22. package/dist/lib/scores.d.ts +1 -36
  23. package/dist/lib/scores.d.ts.map +1 -1
  24. package/dist/lib/scores.js +1 -75
  25. package/dist/lib/scores.js.map +1 -1
  26. package/dist/lib/search.d.ts +1 -113
  27. package/dist/lib/search.d.ts.map +1 -1
  28. package/dist/lib/search.js +1 -379
  29. package/dist/lib/search.js.map +1 -1
  30. package/dist/lib/taxonomy-counts.d.ts +1 -10
  31. package/dist/lib/taxonomy-counts.d.ts.map +1 -1
  32. package/dist/lib/taxonomy-counts.js +1 -21
  33. package/dist/lib/taxonomy-counts.js.map +1 -1
  34. package/package.json +22 -10
  35. package/src/components/ContributorsGrid.astro +3 -3
  36. package/src/components/CurationGrid.astro +2 -2
  37. package/src/components/DirectoryIndexClient.astro +240 -0
  38. package/src/components/FilterGroupMenu.astro +8 -4
  39. package/src/components/FinalCta.astro +41 -0
  40. package/src/components/Hero.astro +15 -18
  41. package/src/components/Icon.astro +99 -27
  42. package/src/components/RefinePanel.astro +7 -7
  43. package/src/components/SmartLensTabs.astro +5 -4
  44. package/src/components/StackGrid.astro +1 -1
  45. package/src/components/SubmissionClient.astro +133 -0
  46. package/src/index.ts +11 -1
  47. package/src/layouts/BaseLayout.astro +19 -1
  48. package/src/layouts/Footer.astro +25 -56
  49. package/src/layouts/Header.astro +33 -15
  50. package/src/layouts/ThemeToggle.astro +7 -3
  51. package/src/lib/display.ts +1 -111
  52. package/src/lib/format.ts +1 -64
  53. package/src/lib/lenses.ts +1 -220
  54. package/src/lib/repo.ts +1 -32
  55. package/src/lib/scores.ts +1 -90
  56. package/src/lib/search.ts +1 -418
  57. package/src/lib/taxonomy-counts.ts +1 -26
  58. package/{templates/default/src/data/records.ts → src/server/directory.ts} +90 -8
  59. package/src/server/index.ts +2 -0
  60. package/src/server/models.ts +432 -0
  61. package/dist/theme.test.d.ts +0 -2
  62. package/dist/theme.test.d.ts.map +0 -1
  63. package/dist/theme.test.js +0 -55
  64. package/dist/theme.test.js.map +0 -1
  65. package/src/theme.test.ts +0 -67
  66. package/templates/default/.github/ISSUE_TEMPLATE/bug_report.md +0 -33
  67. package/templates/default/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  68. package/templates/default/.github/ISSUE_TEMPLATE/record_submission.md +0 -48
  69. package/templates/default/.github/pull_request_template.md +0 -27
  70. package/templates/default/.github/workflows/build.yml +0 -55
  71. package/templates/default/.github/workflows/cleanup-stale-records.yml +0 -48
  72. package/templates/default/.github/workflows/daily-refresh.yml +0 -53
  73. package/templates/default/.github/workflows/sync-contributors.yml +0 -53
  74. package/templates/default/.github/workflows/sync-github-metadata.yml +0 -58
  75. package/templates/default/.github/workflows/validate-data.yml +0 -35
  76. package/templates/default/astro.config.mjs +0 -25
  77. package/templates/default/content/pages/about.md +0 -66
  78. package/templates/default/content/pages/methodology.md +0 -103
  79. package/templates/default/data/records/.gitkeep +0 -0
  80. package/templates/default/data/records/coolify.yml +0 -46
  81. package/templates/default/data/records/gitea.yml +0 -46
  82. package/templates/default/data/records/hoppscotch.yml +0 -47
  83. package/templates/default/data/records/inventree.yml +0 -47
  84. package/templates/default/data/records/label-studio.yml +0 -46
  85. package/templates/default/data/records/logseq.yml +0 -48
  86. package/templates/default/data/records/private-gpt.yml +0 -47
  87. package/templates/default/data/records/wakapi.yml +0 -44
  88. package/templates/default/data/taxonomy/categories.yml +0 -47
  89. package/templates/default/data/taxonomy/distribution-channels.yml +0 -43
  90. package/templates/default/data/taxonomy/platforms.yml +0 -27
  91. package/templates/default/data/taxonomy/stacks.yml +0 -41
  92. package/templates/default/grove.config.ts +0 -36
  93. package/templates/default/package.json +0 -38
  94. package/templates/default/public/icons/platforms/android.svg +0 -1
  95. package/templates/default/public/icons/platforms/apple-dark.svg +0 -1
  96. package/templates/default/public/icons/platforms/apple-light.svg +0 -1
  97. package/templates/default/public/icons/platforms/chrome.svg +0 -1
  98. package/templates/default/public/icons/platforms/chromeos.svg +0 -5
  99. package/templates/default/public/icons/platforms/desktop.svg +0 -4
  100. package/templates/default/public/icons/platforms/embedded.svg +0 -5
  101. package/templates/default/public/icons/platforms/ios.svg +0 -1
  102. package/templates/default/public/icons/platforms/linux.svg +0 -1
  103. package/templates/default/public/icons/platforms/macos.svg +0 -1
  104. package/templates/default/public/icons/platforms/ubuntu.svg +0 -1
  105. package/templates/default/public/icons/platforms/web.svg +0 -5
  106. package/templates/default/public/icons/platforms/windows.svg +0 -6
  107. package/templates/default/public/icons/stacks/android.svg +0 -1
  108. package/templates/default/public/icons/stacks/apple-dark.svg +0 -1
  109. package/templates/default/public/icons/stacks/apple-light.svg +0 -1
  110. package/templates/default/public/icons/stacks/bun.svg +0 -1
  111. package/templates/default/public/icons/stacks/capacitor.svg +0 -14
  112. package/templates/default/public/icons/stacks/clojure.svg +0 -1
  113. package/templates/default/public/icons/stacks/clojurescript.svg +0 -1
  114. package/templates/default/public/icons/stacks/dart.svg +0 -1
  115. package/templates/default/public/icons/stacks/deno.svg +0 -1
  116. package/templates/default/public/icons/stacks/django.svg +0 -1
  117. package/templates/default/public/icons/stacks/docker.svg +0 -1
  118. package/templates/default/public/icons/stacks/firebase.svg +0 -1
  119. package/templates/default/public/icons/stacks/flutter.svg +0 -1
  120. package/templates/default/public/icons/stacks/go.svg +0 -1
  121. package/templates/default/public/icons/stacks/graphql.svg +0 -1
  122. package/templates/default/public/icons/stacks/ionic.svg +0 -4
  123. package/templates/default/public/icons/stacks/java.svg +0 -1
  124. package/templates/default/public/icons/stacks/javascript.svg +0 -1
  125. package/templates/default/public/icons/stacks/kotlin.svg +0 -1
  126. package/templates/default/public/icons/stacks/llm.svg +0 -1
  127. package/templates/default/public/icons/stacks/mongodb.svg +0 -1
  128. package/templates/default/public/icons/stacks/node.js.svg +0 -1
  129. package/templates/default/public/icons/stacks/nodejs.svg +0 -1
  130. package/templates/default/public/icons/stacks/python.svg +0 -1
  131. package/templates/default/public/icons/stacks/rag.svg +0 -7
  132. package/templates/default/public/icons/stacks/react-native.svg +0 -1
  133. package/templates/default/public/icons/stacks/react.svg +0 -1
  134. package/templates/default/public/icons/stacks/rust.svg +0 -1
  135. package/templates/default/public/icons/stacks/solidity.svg +0 -1
  136. package/templates/default/public/icons/stacks/sveltekit.svg +0 -1
  137. package/templates/default/public/icons/stacks/swift.svg +0 -1
  138. package/templates/default/public/icons/stacks/tensorflow.svg +0 -1
  139. package/templates/default/public/icons/stacks/typescript.svg +0 -1
  140. package/templates/default/public/icons/stacks/vue.svg +0 -1
  141. package/templates/default/public/llms-full.txt +0 -206
  142. package/templates/default/public/llms.txt +0 -112
  143. package/templates/default/public/og-image.svg +0 -48
  144. package/templates/default/public/robots.txt +0 -53
  145. package/templates/default/public/sitemap.xml +0 -63
  146. package/templates/default/scripts/build-llms.mjs +0 -123
  147. package/templates/default/scripts/build-records-json.mjs +0 -27
  148. package/templates/default/scripts/build-sitemap.mjs +0 -20
  149. package/templates/default/scripts/cleanup-stale-records.mjs +0 -20
  150. package/templates/default/scripts/enrich-github-metadata.mjs +0 -99
  151. package/templates/default/scripts/fetch-icons.mjs +0 -137
  152. package/templates/default/scripts/migrate-legacy-to-schema-v1.mjs +0 -86
  153. package/templates/default/scripts/parse-legacy-readme.mjs +0 -59
  154. package/templates/default/scripts/refresh-records-activity.mjs +0 -24
  155. package/templates/default/scripts/repair-license-format.mjs +0 -72
  156. package/templates/default/scripts/report-cleanup-candidates.mjs +0 -21
  157. package/templates/default/scripts/seed-from-github.mjs +0 -62
  158. package/templates/default/scripts/sync-contributors.mjs +0 -145
  159. package/templates/default/scripts/sync-github-metadata.mjs +0 -28
  160. package/templates/default/scripts/validate-records.mjs +0 -27
  161. package/templates/default/src/pages/404.astro +0 -64
  162. package/templates/default/src/pages/[slug]/[recordSlug].astro +0 -689
  163. package/templates/default/src/pages/[slug]/index.astro +0 -278
  164. package/templates/default/src/pages/about.astro +0 -182
  165. package/templates/default/src/pages/apps/[recordSlug].astro +0 -33
  166. package/templates/default/src/pages/contributors.astro +0 -175
  167. package/templates/default/src/pages/index.astro +0 -225
  168. package/templates/default/src/pages/sitemap.xml.ts +0 -89
  169. package/templates/default/src/pages/submit.astro +0 -281
  170. package/templates/default/src/styles/global.css +0 -33
  171. package/templates/default/wrangler.jsonc +0 -28
@@ -1,27 +0,0 @@
1
- ## What this PR does
2
-
3
- A short summary of the change. One or two sentences. If it closes an
4
- issue, write "Closes #123" so it auto-links.
5
-
6
- ## Why
7
-
8
- The motivation. Link to any relevant issues or discussions. If this
9
- is a UI change, attach a before/after screenshot.
10
-
11
- ## How to verify
12
-
13
- Steps for a reviewer to follow:
14
-
15
- 1. `pnpm install`
16
- 2. `pnpm exec grove validate`
17
- 3. `pnpm grove:dev` and open `…`
18
- 4. Confirm that `…`
19
-
20
- ## Checklist
21
-
22
- - [ ] `pnpm exec grove validate` passes
23
- - [ ] `pnpm run build` succeeds locally
24
- - [ ] For record changes: the `slug` is unique and matches the
25
- filename (`data/records/<slug>.yml`)
26
- - [ ] For new categories / stacks / platforms: the field appears
27
- sensibly in `Browse by category` and `Browse by stack`
@@ -1,55 +0,0 @@
1
- name: Build
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- workflow_dispatch:
7
-
8
- jobs:
9
- build:
10
- name: grove build
11
- runs-on: ubuntu-latest
12
- timeout-minutes: 15
13
- permissions:
14
- contents: read
15
- pages: write
16
- id-token: write
17
- steps:
18
- - uses: actions/checkout@v4
19
-
20
- - uses: pnpm/action-setup@v4
21
- with:
22
- version: 10
23
-
24
- - uses: actions/setup-node@v4
25
- with:
26
- node-version: 20
27
- cache: pnpm
28
-
29
- - name: Install dependencies
30
- run: pnpm install --frozen-lockfile
31
-
32
- # `build` chains build:data + build:sitemap + build:llms + astro build.
33
- # Site URL is overridden so sitemap/OG/canonical links resolve to
34
- # the deployed URL rather than the placeholder in grove.config.ts.
35
- - name: Build site
36
- env:
37
- SITE_URL: ${{ vars.SITE_URL || github.pages.custom_domain || format('https://{0}.github.io/{1}', github.repository_owner, github.event.repository.name) }}
38
- run: pnpm run build
39
-
40
- - name: Setup Pages
41
- uses: actions/configure-pages@v5
42
-
43
- - name: Upload artifact
44
- uses: actions/upload-pages-artifact@v3
45
- with:
46
- path: ./dist
47
-
48
- - name: Deploy to GitHub Pages
49
- id: deployment
50
- uses: actions/deploy-pages@v4
51
-
52
- - name: Summary
53
- if: success()
54
- run: |
55
- echo "✅ Deployed to ${{ steps.deployment.outputs.page_url }}"
@@ -1,48 +0,0 @@
1
- name: Cleanup stale records
2
-
3
- on:
4
- schedule:
5
- # Monthly — first Monday 05:00 UTC. Cheap enough to run daily
6
- # if you want, but most repos don't change status that often.
7
- - cron: "0 5 1-7 * 1"
8
- workflow_dispatch:
9
-
10
- jobs:
11
- cleanup:
12
- name: grove cleanup stale
13
- runs-on: ubuntu-latest
14
- timeout-minutes: 10
15
- permissions:
16
- contents: read
17
- issues: write
18
- steps:
19
- - uses: actions/checkout@v4
20
-
21
- - uses: pnpm/action-setup@v4
22
- with:
23
- version: 10
24
-
25
- - uses: actions/setup-node@v4
26
- with:
27
- node-version: 20
28
- cache: pnpm
29
-
30
- - name: Install dependencies
31
- run: pnpm install --frozen-lockfile
32
-
33
- # `grove cleanup stale` lists records whose health signals say
34
- # they need human review (archived, no commits in 12+ months,
35
- # unparseable repo, etc). The report is rendered as a Markdown
36
- # summary in the workflow run.
37
- - name: Run cleanup report
38
- id: report
39
- run: pnpm exec grove cleanup stale --report > cleanup-report.md
40
-
41
- - name: Summarise
42
- run: |
43
- if [ -s cleanup-report.md ]; then
44
- echo "## Cleanup candidates" >> $GITHUB_STEP_SUMMARY
45
- cat cleanup-report.md >> $GITHUB_STEP_SUMMARY
46
- else
47
- echo "✅ No records need cleanup." >> $GITHUB_STEP_SUMMARY
48
- fi
@@ -1,53 +0,0 @@
1
- name: Daily records refresh
2
-
3
- on:
4
- schedule:
5
- # Daily — 06:00 UTC. Refreshes stars, forks, and the most
6
- # recent commit date for every record so the home page and
7
- # /apps filters stay accurate.
8
- - cron: "0 6 * * *"
9
- workflow_dispatch:
10
-
11
- jobs:
12
- refresh:
13
- name: refresh activity
14
- runs-on: ubuntu-latest
15
- timeout-minutes: 15
16
- permissions:
17
- contents: write
18
- pull-requests: write
19
- steps:
20
- - uses: actions/checkout@v4
21
-
22
- - uses: pnpm/action-setup@v4
23
- with:
24
- version: 10
25
-
26
- - uses: actions/setup-node@v4
27
- with:
28
- node-version: 20
29
- cache: pnpm
30
-
31
- - name: Install dependencies
32
- run: pnpm install --frozen-lockfile
33
-
34
- - name: Refresh activity
35
- env:
36
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37
- # `grove sync github` walks every record, fetches the
38
- # latest stars/forks/pushed_at, and writes back to the
39
- # corresponding yml file. Idempotent — no change if the
40
- # record is already up to date.
41
- run: pnpm exec grove sync github
42
-
43
- - name: Open PR if records changed
44
- uses: peter-evans/create-pull-request@v6
45
- with:
46
- commit-message: "chore(data): daily records refresh"
47
- title: "Daily records refresh"
48
- body: |
49
- Automated daily refresh of stars, forks, and last-commit
50
- timestamps for every record. Generated by the
51
- `daily-refresh` workflow.
52
- branch: chore/daily-refresh
53
- delete-branch: true
@@ -1,53 +0,0 @@
1
- name: Sync contributors
2
-
3
- on:
4
- schedule:
5
- # Weekly — Sunday 04:00 UTC (after the metadata sync).
6
- - cron: "0 4 * * 0"
7
- workflow_dispatch:
8
-
9
- jobs:
10
- sync:
11
- name: sync contributors
12
- runs-on: ubuntu-latest
13
- timeout-minutes: 10
14
- permissions:
15
- contents: read
16
- steps:
17
- - uses: actions/checkout@v4
18
-
19
- - uses: pnpm/action-setup@v4
20
- with:
21
- version: 10
22
-
23
- - uses: actions/setup-node@v4
24
- with:
25
- node-version: 20
26
- cache: pnpm
27
-
28
- - name: Install dependencies
29
- run: pnpm install --frozen-lockfile
30
-
31
- # Walk the records' repoUrl fields, fetch each repo's
32
- # /contributors endpoint, and write a single
33
- # `data/generated/contributors.json` (consumed by the home
34
- # page and /contributors page). The script lives at the root
35
- # of the project — it's not a CLI command because contributor
36
- # fan-in is tightly coupled to this directory's git history
37
- # and doesn't generalise across forks.
38
- - name: Sync contributors from GitHub
39
- env:
40
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41
- run: node scripts/sync-contributors.mjs
42
-
43
- - name: Commit contributors.json
44
- run: |
45
- git config user.name "github-actions[bot]"
46
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
47
- if git diff --quiet data/generated/contributors.json; then
48
- echo "No changes to contributors.json"
49
- else
50
- git add data/generated/contributors.json
51
- git commit -m "chore(data): refresh contributors"
52
- git push
53
- fi
@@ -1,58 +0,0 @@
1
- name: Sync GitHub metadata
2
-
3
- on:
4
- schedule:
5
- # Weekly — Sunday 03:00 UTC. Off-hours so PR validation has the
6
- # freshest metadata by Monday morning.
7
- - cron: "0 3 * * 0"
8
- workflow_dispatch:
9
- # Run on push to data/records/** so curators see fresh stars/forks
10
- # without waiting for the weekly cron.
11
- push:
12
- branches: [main]
13
- paths:
14
- - "data/records/**"
15
-
16
- jobs:
17
- sync:
18
- name: grove sync github
19
- runs-on: ubuntu-latest
20
- timeout-minutes: 20
21
- permissions:
22
- contents: write
23
- pull-requests: write
24
- steps:
25
- - uses: actions/checkout@v4
26
-
27
- - uses: pnpm/action-setup@v4
28
- with:
29
- version: 10
30
-
31
- - uses: actions/setup-node@v4
32
- with:
33
- node-version: 20
34
- cache: pnpm
35
-
36
- - name: Install dependencies
37
- run: pnpm install --frozen-lockfile
38
-
39
- - name: Sync GitHub metadata
40
- env:
41
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42
- # `grove sync github` walks every record, fetches stars/forks/
43
- # activity from the GitHub API, and writes a `github` block
44
- # back into each record's YAML. Falls back to HTML scraping
45
- # when the API rate-limits.
46
- run: pnpm exec grove sync github
47
-
48
- - name: Open PR if records changed
49
- uses: peter-evans/create-pull-request@v6
50
- with:
51
- commit-message: "chore(data): sync GitHub metadata"
52
- title: "Weekly GitHub metadata sync"
53
- body: |
54
- Automated weekly sync of stars, forks, activity, and topics
55
- for every record. Generated by the `sync-github-metadata`
56
- workflow.
57
- branch: chore/sync-github-metadata
58
- delete-branch: true
@@ -1,35 +0,0 @@
1
- name: Validate data
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
9
- jobs:
10
- validate:
11
- name: grove validate
12
- runs-on: ubuntu-latest
13
- timeout-minutes: 5
14
- steps:
15
- - uses: actions/checkout@v4
16
-
17
- - uses: pnpm/action-setup@v4
18
- with:
19
- version: 10
20
-
21
- - uses: actions/setup-node@v4
22
- with:
23
- node-version: 20
24
- cache: pnpm
25
-
26
- - name: Install dependencies
27
- run: pnpm install --frozen-lockfile
28
-
29
- - name: Validate records
30
- # `grove validate` checks every records/*.yml against the
31
- # blueprint schema, plus decisions.yml, taxonomy, and the
32
- # health block. --strict fails on warnings, used on the
33
- # main branch but not on PRs (where external contributors
34
- # may have minor warnings we'd rather flag than block).
35
- run: pnpm exec grove validate
@@ -1,25 +0,0 @@
1
- // @ts-check
2
- // SPDX-License-Identifier: MIT
3
- import { defineConfig } from 'astro/config';
4
- import tailwindcss from '@tailwindcss/vite';
5
- import groveAstro from '@grove-dev/astro';
6
-
7
- // `site` is the canonical URL the build uses for absolute links
8
- // (sitemap, OpenGraph, canonical tags, JSON-LD). The CLI injects
9
- // `grove.config.ts` → `site.url` at scaffold time, but it can also
10
- // be overridden per-build via the `SITE_URL` env var.
11
- //
12
- // The sitemap is generated by the CLI's `grove sitemap` command
13
- // into `public/sitemap.xml`; the public URL is exactly `/sitemap.xml`
14
- // (no `-index.xml` suffix).
15
- export default defineConfig({
16
- site: process.env.SITE_URL || 'https://example.com',
17
- trailingSlash: 'ignore',
18
- integrations: [groveAstro()],
19
- vite: {
20
- plugins: [tailwindcss()],
21
- },
22
- build: {
23
- format: 'directory',
24
- },
25
- });
@@ -1,66 +0,0 @@
1
- ---
2
- title: "About"
3
- description: "What this directory is, who it's for, and how it works."
4
- ---
5
-
6
- # About this directory
7
-
8
- This site is a small, hand-curated index of useful open-source work
9
- relevant to a specific community. The framing is deliberately
10
- narrow: we list *one* project per record, with a hand-written
11
- "why listed" note for each, and we surface the things that matter
12
- in practice (recent activity, install friction, license, etc.)
13
- rather than the things that look impressive on a GitHub profile.
14
-
15
- ## How it works
16
-
17
- Records live as YAML files in `data/records/`. Each record carries:
18
-
19
- - A `kind` (`project`, `resource`, or `entity` — picked by the
20
- blueprint in `grove.config.ts`).
21
- - A `slug` (URL-safe identifier; becomes the path on
22
- `/<kind>/<slug>`).
23
- - A `name` and a one-line `description`.
24
- - Cross-links (`links.github`, `links.website`, etc.) and free-form
25
- tags.
26
- - An optional `curation` block with `labels`, `reviewedAt`,
27
- `bestFor`, `whyListed`, `caveats`, and `scores`.
28
- - An optional `github` block with the live repository signals
29
- (stars, forks, latest release, languages, pushed-at).
30
-
31
- At build time:
32
-
33
- 1. `grove validate` checks every record against the JSON schema.
34
- 2. `grove generate` writes `data/generated/records.{full,index}.json`
35
- and `data/generated/site-config.json`.
36
- 3. `grove sitemap` writes `public/sitemap.xml`.
37
- 4. `grove llms` writes `public/llms.txt` and `llms-full.txt`.
38
- 5. `astro build` produces the static output.
39
-
40
- The whole pipeline is reproducible. The records are the source of
41
- truth; everything else is derived.
42
-
43
- ## Why a static site
44
-
45
- The directory is a *reference*, not an *app*. Static HTML is the
46
- right tool:
47
-
48
- - Every page is a single round-trip. No client-side data layer.
49
- - The output is auditable: open the deployed HTML and you can see
50
- the full markup, no hidden hydration.
51
- - Hosting is cheap (or free, on GitHub Pages / Cloudflare Pages).
52
- - AI crawlers can read the full content. The `llms.txt` /
53
- `llms-full.txt` files give them a single fetch to land on.
54
-
55
- ## Contributing
56
-
57
- To add a record, open a submission issue. The maintainer will
58
- review and, if accepted, open a PR that adds the new YAML file.
59
- See `/submit` for the issue form and a minimal record template.
60
-
61
- ## License
62
-
63
- The site's source code is MIT. The records are released under CC-BY
64
- 4.0 unless a record's `license` field says otherwise. A record's
65
- `license` field is the license of the *project it describes*, not
66
- the license of the directory entry.
@@ -1,103 +0,0 @@
1
- ---
2
- title: "Methodology"
3
- description: "How records are picked, scored, and surfaced in this directory."
4
- ---
5
-
6
- # Methodology
7
-
8
- This page describes how entries in the directory are chosen, how the
9
- curation signals are computed, and what we do (and don't) promise about
10
- the data. The intent is to make the directory's logic auditable — every
11
- number on a detail page is reproducible from the record's YAML.
12
-
13
- ## Selection
14
-
15
- A record is included if it is:
16
-
17
- 1. **Open source.** Source is public under an OSI-approved license
18
- (or public-domain dedication).
19
- 2. **Actively maintained.** A pushed commit within the last 18 months
20
- OR a declared maintenance status of `maintained` / `passive`.
21
- 3. **Useful to a curious developer.** A working build, a real user
22
- base (or a credible path to one), and a clear description of what
23
- the project does.
24
-
25
- We exclude: abandoned experiments, vapourware, projects whose entire
26
- purpose is to sell a hosted plan, and any record that has not been
27
- hand-checked by a maintainer.
28
-
29
- ## Curation labels
30
-
31
- The `curation.labels` field is a small, hand-set list. The supported
32
- labels are:
33
-
34
- - `hot` — high recent activity or attention (≥ 1 000 stars or a
35
- commit within the last 30 days).
36
- - `new` — added to the directory in the last 7 days.
37
- - `mature` — long-running curated project, pushed > 365 days ago,
38
- but still maintained.
39
- - `featured` — editor's pick for the front page.
40
- - `needs-review` — open submission awaiting a second maintainer
41
- look.
42
-
43
- These labels are mutually additive, not exclusive. A `new` record
44
- can also be `hot`; a `mature` record can also be `featured`.
45
-
46
- ## Scoring
47
-
48
- The detail page surfaces a five-dimension score block. The five
49
- dimensions are:
50
-
51
- - **Documentation** — is the README / docs site enough to onboard
52
- without reading the source?
53
- - **Onboarding** — install in < 5 min, first useful result in < 1 h.
54
- - **Maintenance** — recent commits, issue close rate, release cadence.
55
- - **Community** — issues answered, discussions active, contributors
56
- per release.
57
- - **Production-readiness** — CI, tests, security policy, releases
58
- with semver.
59
-
60
- Each dimension is scored 0-5. The overall score on the detail page
61
- is the mean. Scores are stored on the record, not computed at build
62
- time, so we can deliberately disagree with the raw signals (a 1-line
63
- toy that happens to be wildly popular can still score low on
64
- documentation).
65
-
66
- ## Health signals
67
-
68
- The `health` block on each record tracks four state machines:
69
-
70
- - `status` — `healthy` / `slowing` / `stale` / `archived`.
71
- - `tier` — `curated` / `community` / `experimental`.
72
- - `issue_close_rate` — moving 90-day average.
73
- - `last_release` — most recent semver tag.
74
-
75
- A record's `status` transitions are time-boxed: a project with no
76
- commits in 365 days flips from `slowing` to `stale`; 730 days flips
77
- to `archived`. The transition is mechanical; the recovery is
78
- manual (a maintainer sets `tier` back to `community` after review).
79
-
80
- ## Lenses
81
-
82
- The directory's home page surfaces three curated lenses:
83
-
84
- - **Hot** — `curation.labels` includes `hot`, OR `github.stars` ≥
85
- 1 000, OR `pushedAt` within 30 days.
86
- - **New** — `pushedAt` within 7 days, OR `curation.labels` includes
87
- `new`.
88
- - **Mature** — `health.tier === "curated"` AND `pushedAt` > 365 days
89
- ago.
90
-
91
- Each lens caps at 6 items on the home page; the full filtered list
92
- is reachable via the lens tab on `/projects`.
93
-
94
- ## What we don't promise
95
-
96
- - **Real-time data.** The site is rebuilt on a schedule, not on
97
- every push. Counts and dates can lag by up to one build cycle.
98
- - **Verdict-free scores.** A high overall score means "useful to a
99
- curious developer", not "best in class" — judgement calls are
100
- documented per record, not baked into the score.
101
- - **Causal claims.** The "best for" / "why listed" / "caveats"
102
- blocks are editorial notes, not derived signals. They reflect
103
- what a maintainer thought at review time.
File without changes
@@ -1,46 +0,0 @@
1
- kind: project
2
- name: Coolify
3
- slug: coolify
4
- description: Open-source, self-hostable Heroku / Netlify / Vercel alternative — deploy apps and databases from a single dashboard.
5
- category: DevOps
6
- tags:
7
- - self-host
8
- - paas
9
- - deployment
10
- - svelte
11
- stack: SvelteKit
12
- stacks:
13
- - SvelteKit
14
- - Node.js
15
- - Docker
16
- platforms:
17
- - linux
18
- - self-host
19
- projectType: real-app
20
- difficulty: intermediate
21
- codebaseSize: large
22
- repoUrl: https://github.com/coollabsio/coolify
23
- links:
24
- github: https://github.com/coollabsio/coolify
25
- website: https://coolify.io
26
- bestFor:
27
- - Self-hosted PaaS
28
- - VPS deployments
29
- - Docker-based stacks
30
- whyListed:
31
- - One-click app + DB deploys
32
- - Active dev
33
- - Clear upgrade path from manual Docker
34
- caveats: []
35
- distribution:
36
- channels: []
37
- source:
38
- type: manual
39
- curation:
40
- reviewed: true
41
- reviewedBy: grove-bot
42
- reviewedAt: "2026-06-13"
43
- labels:
44
- - hot
45
- lenses: []
46
- visibility: keep
@@ -1,46 +0,0 @@
1
- kind: project
2
- name: Gitea
3
- slug: gitea
4
- description: Lightweight, self-hosted Git service — painless, single-binary, low-resource alternative to GitHub.
5
- category: DevOps
6
- tags:
7
- - git
8
- - forge
9
- - self-host
10
- - go
11
- stack: Go
12
- stacks:
13
- - Go
14
- - Vue
15
- platforms:
16
- - linux
17
- - self-host
18
- - docker
19
- projectType: real-app
20
- difficulty: intermediate
21
- codebaseSize: large
22
- repoUrl: https://github.com/go-gitea/gitea
23
- links:
24
- github: https://github.com/go-gitea/gitea
25
- website: https://about.gitea.com
26
- bestFor:
27
- - Self-hosted Git hosting
28
- - Lightweight CI/CD integration
29
- - Internal team forges
30
- whyListed:
31
- - Single binary, easy install
32
- - Mature, stable releases
33
- - Active community
34
- caveats: []
35
- distribution:
36
- channels: []
37
- source:
38
- type: manual
39
- curation:
40
- reviewed: true
41
- reviewedBy: grove-bot
42
- reviewedAt: "2026-06-13"
43
- labels:
44
- - mature
45
- lenses: []
46
- visibility: keep
@@ -1,47 +0,0 @@
1
- kind: project
2
- name: Hoppscotch
3
- slug: hoppscotch
4
- description: Open-source API development ecosystem — design, test, and debug APIs faster from a single interface.
5
- category: Web
6
- tags:
7
- - api
8
- - testing
9
- - developer-tools
10
- - vue
11
- stack: Vue
12
- stacks:
13
- - Vue
14
- - TypeScript
15
- - GraphQL
16
- platforms:
17
- - web
18
- - desktop
19
- - self-host
20
- projectType: real-app
21
- difficulty: beginner
22
- codebaseSize: large
23
- repoUrl: https://github.com/hoppscotch/hoppscotch
24
- links:
25
- github: https://github.com/hoppscotch/hoppscotch
26
- website: https://hoppscotch.io
27
- bestFor:
28
- - API exploration
29
- - REST/GraphQL/WebSocket testing
30
- - Self-hosted team workflows
31
- whyListed:
32
- - Lightweight, fast UI
33
- - PWA + desktop builds
34
- - Open-source Postman/Insomnia alternative
35
- caveats: []
36
- distribution:
37
- channels: []
38
- source:
39
- type: manual
40
- curation:
41
- reviewed: true
42
- reviewedBy: grove-bot
43
- reviewedAt: "2026-06-13"
44
- labels:
45
- - hot
46
- lenses: []
47
- visibility: keep