@grove-dev/astro 0.2.19 → 0.3.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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/dist/template-routes.test.d.ts +2 -0
  3. package/dist/template-routes.test.d.ts.map +1 -0
  4. package/dist/template-routes.test.js +63 -0
  5. package/dist/template-routes.test.js.map +1 -0
  6. package/dist/theme.test.js +19 -0
  7. package/dist/theme.test.js.map +1 -1
  8. package/package.json +4 -4
  9. package/src/components/CategoryGrid.astro +2 -11
  10. package/src/components/ContributorsGrid.astro +2 -11
  11. package/src/components/CurationGrid.astro +1 -1
  12. package/src/components/DecisionRow.astro +1 -1
  13. package/src/components/ExploreByCategory.astro +3 -3
  14. package/src/components/ExploreByStack.astro +3 -3
  15. package/src/components/FilterGroupMenu.astro +5 -5
  16. package/src/components/Hero.astro +8 -8
  17. package/src/components/Icon.astro +56 -53
  18. package/src/components/IndexRow.astro +5 -5
  19. package/src/components/ItemCard.astro +5 -16
  20. package/src/components/MinimalAbout.astro +2 -2
  21. package/src/components/OriginalCollection.astro +4 -4
  22. package/src/components/Pagination.astro +2 -2
  23. package/src/components/RecordSection.astro +1 -1
  24. package/src/components/RefinePanel.astro +1 -1
  25. package/src/components/SmartLensTabs.astro +3 -3
  26. package/src/components/StackGrid.astro +6 -15
  27. package/src/components/WhyThisExists.astro +3 -3
  28. package/src/layouts/Container.astro +4 -4
  29. package/src/layouts/Footer.astro +3 -3
  30. package/src/layouts/Header.astro +5 -5
  31. package/src/layouts/ThemeToggle.astro +1 -1
  32. package/src/styles.css +33 -339
  33. package/src/template-routes.test.ts +103 -0
  34. package/src/theme.test.ts +24 -0
  35. package/templates/default/.github/workflows/build.yml +1 -3
  36. package/templates/default/.github/workflows/cleanup-stale-records.yml +1 -3
  37. package/templates/default/.github/workflows/daily-refresh.yml +1 -3
  38. package/templates/default/.github/workflows/sync-contributors.yml +2 -4
  39. package/templates/default/.github/workflows/sync-github-metadata.yml +1 -3
  40. package/templates/default/.github/workflows/validate-data.yml +1 -3
  41. package/templates/default/grove.config.ts +1 -1
  42. package/templates/default/package.json +9 -4
  43. package/templates/default/public/icons/stacks/rag.svg +7 -0
  44. package/templates/default/public/llms-full.txt +63 -186
  45. package/templates/default/public/llms.txt +6 -107
  46. package/templates/default/public/sitemap.xml +10 -10
  47. package/templates/default/src/data/records.ts +80 -2
  48. package/templates/default/src/pages/404.astro +5 -5
  49. package/templates/default/src/pages/[slug]/[recordSlug].astro +36 -38
  50. package/templates/default/src/pages/[slug]/index.astro +223 -19
  51. package/templates/default/src/pages/about.astro +17 -10
  52. package/templates/default/src/pages/apps/[recordSlug].astro +2 -1
  53. package/templates/default/src/pages/contributors.astro +8 -17
  54. package/templates/default/src/pages/index.astro +11 -3
  55. package/templates/default/src/pages/sitemap.xml.ts +3 -3
  56. package/templates/default/src/pages/submit.astro +28 -36
  57. package/templates/default/tsconfig.json +9 -0
  58. package/templates/default/scripts/build-llms.mjs +0 -123
  59. package/templates/default/scripts/build-records-json.mjs +0 -27
  60. package/templates/default/scripts/build-sitemap.mjs +0 -20
  61. package/templates/default/scripts/cleanup-stale-records.mjs +0 -20
  62. package/templates/default/scripts/enrich-github-metadata.mjs +0 -99
  63. package/templates/default/scripts/fetch-icons.mjs +0 -137
  64. package/templates/default/scripts/migrate-legacy-to-schema-v1.mjs +0 -86
  65. package/templates/default/scripts/parse-legacy-readme.mjs +0 -59
  66. package/templates/default/scripts/refresh-records-activity.mjs +0 -24
  67. package/templates/default/scripts/repair-license-format.mjs +0 -72
  68. package/templates/default/scripts/report-cleanup-candidates.mjs +0 -21
  69. package/templates/default/scripts/seed-from-github.mjs +0 -62
  70. package/templates/default/scripts/sync-contributors.mjs +0 -145
  71. package/templates/default/scripts/sync-github-metadata.mjs +0 -28
  72. package/templates/default/scripts/validate-records.mjs +0 -27
@@ -0,0 +1,103 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { readFile, stat } from "node:fs/promises";
3
+ import { resolve } from "node:path";
4
+
5
+ const pagesDir = resolve(import.meta.dirname, "../templates/default/src/pages");
6
+
7
+ describe("default Astro route configuration", () => {
8
+ it("ships TypeScript settings that resolve package exports and Node built-ins", async () => {
9
+ const templateRoot = resolve(pagesDir, "../..");
10
+ const tsconfig = JSON.parse(
11
+ await readFile(resolve(templateRoot, "tsconfig.json"), "utf8"),
12
+ ) as {
13
+ extends?: string;
14
+ compilerOptions?: {
15
+ moduleResolution?: string;
16
+ types?: string[];
17
+ };
18
+ };
19
+ const manifest = JSON.parse(
20
+ await readFile(resolve(templateRoot, "package.json"), "utf8"),
21
+ ) as { devDependencies?: Record<string, string> };
22
+
23
+ expect(tsconfig.extends).toBe("astro/tsconfigs/base");
24
+ expect(tsconfig.compilerOptions?.moduleResolution).toBe("Bundler");
25
+ expect(tsconfig.compilerOptions?.types).toContain("node");
26
+ expect(manifest.devDependencies?.["@types/node"]).toMatch(/^\^/);
27
+ });
28
+
29
+ it("treats generated JSON as an untyped boundary before applying payload types", async () => {
30
+ const recordsModule = await readFile(
31
+ resolve(pagesDir, "../data/records.ts"),
32
+ "utf8",
33
+ );
34
+
35
+ expect(recordsModule).toContain(
36
+ "fullPayload as unknown as FullPayload",
37
+ );
38
+ });
39
+
40
+ it("derives the directory route from generated site config", async () => {
41
+ const listPage = await readFile(resolve(pagesDir, "[slug]/index.astro"), "utf8");
42
+
43
+ expect(listPage).toContain("siteConfig.blueprintConfig?.routeSlug");
44
+ });
45
+
46
+ it("does not generate the legacy apps alias when apps is canonical", async () => {
47
+ const aliasPage = await readFile(resolve(pagesDir, "apps/[recordSlug].astro"), "utf8");
48
+
49
+ expect(aliasPage).toContain('if (indexSlug() === "apps")');
50
+ expect(aliasPage).toContain("return []");
51
+ });
52
+
53
+ it("renders consumer-authored about Markdown through the default page", async () => {
54
+ const aboutPage = await readFile(resolve(pagesDir, "about.astro"), "utf8");
55
+
56
+ expect(aboutPage).toContain('getPageContentHtml("about")');
57
+ });
58
+
59
+ it("generates submission drafts accepted by the Grove record schema", async () => {
60
+ const submitPage = await readFile(resolve(pagesDir, "submit.astro"), "utf8");
61
+
62
+ expect(submitPage).toContain('" type: manual"');
63
+ expect(submitPage).not.toContain('" type: github"');
64
+ });
65
+
66
+ it("keeps generic maintenance behavior in Grove instead of consumer scripts", async () => {
67
+ const templateRoot = resolve(pagesDir, "../..");
68
+ const manifest = JSON.parse(
69
+ await readFile(resolve(templateRoot, "package.json"), "utf8"),
70
+ ) as { scripts?: Record<string, string> };
71
+ const scriptsDirExists = await stat(resolve(templateRoot, "scripts"))
72
+ .then(() => true)
73
+ .catch(() => false);
74
+
75
+ expect(manifest.scripts?.["build:llms"]).toBe("grove llms");
76
+ expect(manifest.scripts?.["sync:contributors"]).toBe(
77
+ "grove sync contributors",
78
+ );
79
+ expect(scriptsDirExists).toBe(false);
80
+ });
81
+
82
+ it("hydrates static list pages with URL-driven search and pagination", async () => {
83
+ const listPage = await readFile(resolve(pagesDir, "[slug]/index.astro"), "utf8");
84
+
85
+ expect(listPage).toContain('id="grove-index-data"');
86
+ expect(listPage).toContain("function applyClientFilters()");
87
+ expect(listPage).toContain("const PAGE_SIZE = 20");
88
+ });
89
+
90
+ it("uses generated taxonomy names as display labels", async () => {
91
+ const recordsModule = await readFile(
92
+ resolve(pagesDir, "../data/records.ts"),
93
+ "utf8",
94
+ );
95
+ const homePage = await readFile(resolve(pagesDir, "index.astro"), "utf8");
96
+ const listPage = await readFile(resolve(pagesDir, "[slug]/index.astro"), "utf8");
97
+
98
+ expect(recordsModule).toContain("export function taxonomyLabel");
99
+ expect(recordsModule).toContain("?? prettySlug(id)");
100
+ expect(homePage).toContain('taxonomyLabel("categories"');
101
+ expect(listPage).toContain("labelFacetsWithTaxonomy");
102
+ });
103
+ });
package/src/theme.test.ts CHANGED
@@ -7,6 +7,15 @@ const scaffoldTheme = readFileSync(
7
7
  resolve(import.meta.dirname, "../templates/default/src/styles/global.css"),
8
8
  "utf8",
9
9
  );
10
+ const tailwindMarkup = [
11
+ "components/ItemCard.astro",
12
+ "layouts/Header.astro",
13
+ "../templates/default/src/pages/submit.astro",
14
+ ].map((file) => readFileSync(resolve(import.meta.dirname, file), "utf8")).join("\n");
15
+ const iconMarkup = readFileSync(
16
+ resolve(import.meta.dirname, "components/Icon.astro"),
17
+ "utf8",
18
+ );
10
19
 
11
20
  describe("Astro theme contract", () => {
12
21
  it("keeps Starlight's light and dark foundation values", () => {
@@ -49,4 +58,19 @@ describe("Astro theme contract", () => {
49
58
  expect(scaffoldTheme).not.toContain("font-family:");
50
59
  expect(scaffoldTheme).not.toContain("color-scheme:");
51
60
  });
61
+
62
+ it("styles components in HTML with Starlight-aligned Tailwind utilities", () => {
63
+ expect(tailwindMarkup).toContain("rounded-[calc(var(--radius)+0.25rem)]");
64
+ expect(tailwindMarkup).toContain("rounded-full");
65
+ expect(tailwindMarkup).toContain("min-h-5");
66
+ expect(tailwindMarkup).toContain("h-8");
67
+ expect(tailwindMarkup).toContain("focus-visible:ring-3");
68
+ expect(astroTheme).not.toContain(".grove-card");
69
+ expect(astroTheme).not.toContain(".grove-btn");
70
+ });
71
+
72
+ it("falls back to initials when a consumer has no matching icon asset", () => {
73
+ expect(iconMarkup).toContain("data-grove-icon-fallback-initials");
74
+ expect(iconMarkup).toContain("onerror=");
75
+ });
52
76
  });
@@ -18,12 +18,10 @@ jobs:
18
18
  - uses: actions/checkout@v4
19
19
 
20
20
  - uses: pnpm/action-setup@v4
21
- with:
22
- version: 10
23
21
 
24
22
  - uses: actions/setup-node@v4
25
23
  with:
26
- node-version: 20
24
+ node-version: "24"
27
25
  cache: pnpm
28
26
 
29
27
  - name: Install dependencies
@@ -19,12 +19,10 @@ jobs:
19
19
  - uses: actions/checkout@v4
20
20
 
21
21
  - uses: pnpm/action-setup@v4
22
- with:
23
- version: 10
24
22
 
25
23
  - uses: actions/setup-node@v4
26
24
  with:
27
- node-version: 20
25
+ node-version: "24"
28
26
  cache: pnpm
29
27
 
30
28
  - name: Install dependencies
@@ -20,12 +20,10 @@ jobs:
20
20
  - uses: actions/checkout@v4
21
21
 
22
22
  - uses: pnpm/action-setup@v4
23
- with:
24
- version: 10
25
23
 
26
24
  - uses: actions/setup-node@v4
27
25
  with:
28
- node-version: 20
26
+ node-version: "24"
29
27
  cache: pnpm
30
28
 
31
29
  - name: Install dependencies
@@ -17,12 +17,10 @@ jobs:
17
17
  - uses: actions/checkout@v4
18
18
 
19
19
  - uses: pnpm/action-setup@v4
20
- with:
21
- version: 10
22
20
 
23
21
  - uses: actions/setup-node@v4
24
22
  with:
25
- node-version: 20
23
+ node-version: "24"
26
24
  cache: pnpm
27
25
 
28
26
  - name: Install dependencies
@@ -38,7 +36,7 @@ jobs:
38
36
  - name: Sync contributors from GitHub
39
37
  env:
40
38
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41
- run: node scripts/sync-contributors.mjs
39
+ run: pnpm exec grove sync contributors
42
40
 
43
41
  - name: Commit contributors.json
44
42
  run: |
@@ -25,12 +25,10 @@ jobs:
25
25
  - uses: actions/checkout@v4
26
26
 
27
27
  - uses: pnpm/action-setup@v4
28
- with:
29
- version: 10
30
28
 
31
29
  - uses: actions/setup-node@v4
32
30
  with:
33
- node-version: 20
31
+ node-version: "24"
34
32
  cache: pnpm
35
33
 
36
34
  - name: Install dependencies
@@ -15,12 +15,10 @@ jobs:
15
15
  - uses: actions/checkout@v4
16
16
 
17
17
  - uses: pnpm/action-setup@v4
18
- with:
19
- version: 10
20
18
 
21
19
  - uses: actions/setup-node@v4
22
20
  with:
23
- node-version: 20
21
+ node-version: "24"
24
22
  cache: pnpm
25
23
 
26
24
  - name: Install dependencies
@@ -25,7 +25,7 @@ export default defineConfig({
25
25
 
26
26
  facets: ["category", "stacks", "platforms", "tags"],
27
27
 
28
- integrations: {},
28
+ integrations: { github: false },
29
29
 
30
30
  theme: {
31
31
  primaryColor: "#1f6feb",
@@ -13,7 +13,7 @@
13
13
  "validate:data": "grove validate",
14
14
  "build:data": "grove generate",
15
15
  "build:sitemap": "grove sitemap",
16
- "build:llms": "node scripts/build-llms.mjs",
16
+ "build:llms": "grove llms",
17
17
  "build": "pnpm run build:data && pnpm run build:sitemap && pnpm run build:llms && astro build",
18
18
  "dev": "pnpm run build:data && astro dev",
19
19
  "start": "astro dev",
@@ -21,18 +21,23 @@
21
21
  "astro": "astro",
22
22
  "check": "astro check",
23
23
  "sync:github": "grove sync github",
24
+ "sync:contributors": "grove sync contributors",
24
25
  "cleanup": "grove cleanup stale"
25
26
  },
26
27
  "dependencies": {
27
28
  "@astrojs/check": "^0.9.9",
28
- "@grove-dev/astro": "0.2.18",
29
- "@grove-dev/cli": "0.2.16",
30
- "@grove-dev/core": "0.2.16",
29
+ "@grove-dev/astro": "workspace:*",
30
+ "@grove-dev/cli": "workspace:*",
31
+ "@grove-dev/core": "workspace:*",
31
32
  "@tailwindcss/vite": "^4.3.0",
32
33
  "astro": "^6.4.4",
33
34
  "marked": "^18.0.0",
34
35
  "sanitize-html": "^2.17.5",
35
36
  "tailwindcss": "^4.3.0",
36
37
  "yaml": "^2.9.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^25.9.2",
41
+ "@types/sanitize-html": "^2.16.0"
37
42
  }
38
43
  }
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none">
2
+ <rect width="100" height="100" rx="18" fill="#0F172A"/>
3
+ <path d="M29 28h42v13H29zM29 59h42v13H29z" stroke="#38BDF8" stroke-width="4" stroke-linejoin="round"/>
4
+ <path d="M50 41v18M42 50h16" stroke="#A78BFA" stroke-width="4" stroke-linecap="round"/>
5
+ <circle cx="36" cy="34.5" r="2.5" fill="#38BDF8"/>
6
+ <circle cx="36" cy="65.5" r="2.5" fill="#38BDF8"/>
7
+ </svg>
@@ -1,206 +1,83 @@
1
- # example.com — full directory
1
+ # Grove Directory — full directory
2
2
 
3
- Generated: 2026-06-22T14:50:54.564Z
4
- Records: 8
3
+ > Generated 2026-07-01T16:50:32.236Z from 8 records.
4
+ > Source: https://example.com/projects · Regenerate with `grove generate`.
5
5
 
6
- ---
6
+ Each section below mirrors one record detail page.
7
7
 
8
- ## Coolify
8
+ ## Index
9
9
 
10
- Open-source, self-hostable Heroku / Netlify / Vercel alternative — deploy apps and databases from a single dashboard.
11
-
12
- - **URL**: https://example.com/coolify
13
- - **Repository**: https://github.com/coollabsio/coolify
14
- - **Stack**: SvelteKit
15
- - **Platforms**: linux, self-host
16
- - **Category**: DevOps
17
- - **Tags**: self-host, paas, deployment, svelte
18
- - **Stars**: 0
19
- - **Last commit**: —
20
-
21
- **Best for:**
22
- - Self-hosted PaaS
23
- - VPS deployments
24
- - Docker-based stacks
10
+ - [Coolify](#coolify) — DevOps · SvelteKit · 0★ — Open-source, self-hostable Heroku / Netlify / Vercel alternative — deploy apps and databases from a single dashboard.
11
+ - [Gitea](#gitea) — DevOps · Go · 0★ — Lightweight, self-hosted Git service — painless, single-binary, low-resource alternative to GitHub.
12
+ - [Hoppscotch](#hoppscotch) — Web · Vue · 0★ — Open-source API development ecosystem — design, test, and debug APIs faster from a single interface.
13
+ - [InvenTree](#inventree) — Mobile · Flutter · 0★ — Open-source inventory management system with parts, stock, and purchase orders.
14
+ - [Label Studio](#label-studio) — AI/ML · Python · 0★ — Open-source data labeling platform — annotate images, text, audio, video, and time series for ML training.
15
+ - [Logseq](#logseq) — Web · ClojureScript · 0★ — Privacy-first, open-source knowledge base that works on top of plain text Markdown and Org-mode files.
16
+ - [PrivateGPT](#private-gpt) — AI/ML · Python · 0★ — Interact privately with your documents using LLMs — 100% private, no data leaves your execution environment.
17
+ - [Wakapi](#wakapi) — Mobile · Kotlin · 0★ — Open-source time tracker for developers — coding stats, language breakdowns, and project-level metrics.
25
18
 
26
- **Why listed:**
27
- - One-click app + DB deploys
28
- - Active dev
29
- - Clear upgrade path from manual Docker
19
+ ## Projects
30
20
 
31
- ---
32
-
33
- ## Gitea
21
+ ### Coolify
22
+ Open-source, self-hostable Heroku / Netlify / Vercel alternative — deploy apps and databases from a single dashboard.
23
+ - slug: coolify
24
+ - category: DevOps
25
+ - stack: SvelteKit
26
+ - stars: 0
27
+ - url: https://example.com/projects/coolify
34
28
 
29
+ ### Gitea
35
30
  Lightweight, self-hosted Git service — painless, single-binary, low-resource alternative to GitHub.
31
+ - slug: gitea
32
+ - category: DevOps
33
+ - stack: Go
34
+ - stars: 0
35
+ - url: https://example.com/projects/gitea
36
36
 
37
- - **URL**: https://example.com/gitea
38
- - **Repository**: https://github.com/go-gitea/gitea
39
- - **Stack**: Go
40
- - **Platforms**: linux, self-host, docker
41
- - **Category**: DevOps
42
- - **Tags**: git, forge, self-host, go
43
- - **Stars**: 0
44
- - **Last commit**: —
45
-
46
- **Best for:**
47
- - Self-hosted Git hosting
48
- - Lightweight CI/CD integration
49
- - Internal team forges
50
-
51
- **Why listed:**
52
- - Single binary, easy install
53
- - Mature, stable releases
54
- - Active community
55
-
56
- ---
57
-
58
- ## Hoppscotch
59
-
37
+ ### Hoppscotch
60
38
  Open-source API development ecosystem — design, test, and debug APIs faster from a single interface.
39
+ - slug: hoppscotch
40
+ - category: Web
41
+ - stack: Vue
42
+ - stars: 0
43
+ - url: https://example.com/projects/hoppscotch
61
44
 
62
- - **URL**: https://example.com/hoppscotch
63
- - **Repository**: https://github.com/hoppscotch/hoppscotch
64
- - **Stack**: Vue
65
- - **Platforms**: web, desktop, self-host
66
- - **Category**: Web
67
- - **Tags**: api, testing, developer-tools, vue
68
- - **Stars**: 0
69
- - **Last commit**: —
70
-
71
- **Best for:**
72
- - API exploration
73
- - REST/GraphQL/WebSocket testing
74
- - Self-hosted team workflows
75
-
76
- **Why listed:**
77
- - Lightweight, fast UI
78
- - PWA + desktop builds
79
- - Open-source Postman/Insomnia alternative
80
-
81
- ---
82
-
83
- ## InvenTree
84
-
45
+ ### InvenTree
85
46
  Open-source inventory management system with parts, stock, and purchase orders.
47
+ - slug: inventree
48
+ - category: Mobile
49
+ - stack: Flutter
50
+ - stars: 0
51
+ - url: https://example.com/projects/inventree
86
52
 
87
- - **URL**: https://example.com/inventree
88
- - **Repository**: https://github.com/inventree/InvenTree
89
- - **Stack**: Flutter
90
- - **Platforms**: ios, android, web
91
- - **Category**: Mobile
92
- - **Tags**: inventory, stock, mobile, dart, flutter
93
- - **Stars**: 0
94
- - **Last commit**: —
95
-
96
- **Best for:**
97
- - Inventory tracking
98
- - Manufacturing
99
- - Hardware projects
100
-
101
- **Why listed:**
102
- - Production-grade mobile + web stack
103
- - Strong community
104
- - Cleanly factored Dart codebase
105
-
106
- ---
107
-
108
- ## Label Studio
109
-
53
+ ### Label Studio
110
54
  Open-source data labeling platform — annotate images, text, audio, video, and time series for ML training.
55
+ - slug: label-studio
56
+ - category: AI/ML
57
+ - stack: Python
58
+ - stars: 0
59
+ - url: https://example.com/projects/label-studio
111
60
 
112
- - **URL**: https://example.com/label-studio
113
- - **Repository**: https://github.com/HumanSignal/label-studio
114
- - **Stack**: Python
115
- - **Platforms**: web, self-host
116
- - **Category**: AI/ML
117
- - **Tags**: labeling, ml-ops, annotation, python
118
- - **Stars**: 0
119
- - **Last commit**: —
120
-
121
- **Best for:**
122
- - ML dataset labeling
123
- - Multi-modal annotation
124
- - Active learning pipelines
125
-
126
- **Why listed:**
127
- - Mature, production-grade
128
- - Strong ML backend
129
- - Active commercial + community backing
130
-
131
- ---
132
-
133
- ## Logseq
134
-
61
+ ### Logseq
135
62
  Privacy-first, open-source knowledge base that works on top of plain text Markdown and Org-mode files.
63
+ - slug: logseq
64
+ - category: Web
65
+ - stack: ClojureScript
66
+ - stars: 0
67
+ - url: https://example.com/projects/logseq
136
68
 
137
- - **URL**: https://example.com/logseq
138
- - **Repository**: https://github.com/logseq/logseq
139
- - **Stack**: ClojureScript
140
- - **Platforms**: web, desktop
141
- - **Category**: Web
142
- - **Tags**: notes, knowledge-base, productivity, clojure
143
- - **Stars**: 0
144
- - **Last commit**: —
145
-
146
- **Best for:**
147
- - PKM (personal knowledge management)
148
- - Local-first note taking
149
- - Graph-based outliner
150
-
151
- **Why listed:**
152
- - Local-first with sync
153
- - Active community
154
- - Strong plugin ecosystem
155
-
156
- ---
157
-
158
- ## PrivateGPT
159
-
69
+ ### PrivateGPT
160
70
  Interact privately with your documents using LLMs — 100% private, no data leaves your execution environment.
71
+ - slug: private-gpt
72
+ - category: AI/ML
73
+ - stack: Python
74
+ - stars: 0
75
+ - url: https://example.com/projects/private-gpt
161
76
 
162
- - **URL**: https://example.com/private-gpt
163
- - **Repository**: https://github.com/zylon-ai/private-gpt
164
- - **Stack**: Python
165
- - **Platforms**: linux, macos, self-host
166
- - **Category**: AI/ML
167
- - **Tags**: llm, rag, privacy, python
168
- - **Stars**: 0
169
- - **Last commit**: —
170
-
171
- **Best for:**
172
- - Private document Q&A
173
- - Local LLM experimentation
174
- - Enterprise privacy use cases
175
-
176
- **Why listed:**
177
- - Strict no-network mode
178
- - Pluggable LLM providers
179
- - Clean ingestion pipeline
180
-
181
- ---
182
-
183
- ## Wakapi
184
-
77
+ ### Wakapi
185
78
  Open-source time tracker for developers — coding stats, language breakdowns, and project-level metrics.
186
-
187
- - **URL**: https://example.com/wakapi
188
- - **Repository**: https://github.com/muety/wakapi
189
- - **Stack**: Kotlin
190
- - **Platforms**: android
191
- - **Category**: Mobile
192
- - **Tags**: time-tracking, analytics, mobile, kotlin
193
- - **Stars**: 0
194
- - **Last commit**: —
195
-
196
- **Best for:**
197
- - Personal coding stats
198
- - WakaTime alternative
199
- - Privacy-first telemetry
200
-
201
- **Why listed:**
202
- - Self-host friendly
203
- - Companion mobile app
204
- - Clean MVVM architecture
205
-
206
- ---
79
+ - slug: wakapi
80
+ - category: Mobile
81
+ - stack: Kotlin
82
+ - stars: 0
83
+ - url: https://example.com/projects/wakapi
@@ -1,112 +1,11 @@
1
1
  # Grove Directory
2
2
 
3
- Grove Directory is a curated, health-aware developer directory powered by
4
- the Grove framework. Every entry is real, runnable, and actively
5
- maintained — not an SDK, not a template, not a toy demo.
3
+ A curated, health-aware developer directory powered by Grove.
6
4
 
7
- The directory is built from plain YAML files in the consumer's
8
- repository. The build pipeline renders a static Astro site. No
9
- database, no JavaScript framework, no CDN with sticky sessions.
5
+ Directory: https://example.com/projects
6
+ Records indexed: 8
7
+ Categories: 4
10
8
 
11
- ## Main URLs
9
+ ## Usage
12
10
 
13
- - Home: https://example.com/
14
- - Browse: https://example.com/projects
15
- - About: https://example.com/about
16
- - Contributors: https://example.com/contributors
17
- - Submit a record: https://example.com/submit
18
-
19
- ## Filter views (one URL = one curated lens)
20
-
21
- - Trending: https://example.com/projects?label=hot
22
- - Recently added: https://example.com/projects?label=new
23
- - Established (mature): https://example.com/projects?label=mature
24
- - Featured: https://example.com/projects?label=featured
25
- - Good to learn: https://example.com/projects?lens=good-to-learn
26
- - Production-like: https://example.com/projects?lens=production-like
27
- - Beginner-friendly: https://example.com/projects?lens=beginner-friendly
28
- - Contribution-ready: https://example.com/projects?lens=contribution-ready
29
-
30
- ## Browse axes
31
-
32
- - By stack: https://example.com/projects (use the `stack` query param)
33
- - By category: https://example.com/projects (use the `category` query param)
34
- - By platform: https://example.com/projects (use the `platform` query param)
35
- - By license: https://example.com/projects (use the `license` query param)
36
- - By health: https://example.com/projects (use the `status` query param)
37
-
38
- ## What the directory contains
39
-
40
- - Real, runnable open-source records (projects, resources, entities)
41
- - Stack, language, and architecture at a glance
42
- - Activity, health signals, and maturity tiers
43
- - License, stars, and contribution readiness
44
- - Curated notes: best for, why listed, caveats
45
- - Filters by stack, platform, license, and status
46
-
47
- ## Data layout (for AI agents that want to ingest the catalog)
48
-
49
- - `data/records/*.yml` — human-edited source of truth (one file per record)
50
- - `data/taxonomy/categories.yml` — 16 categories (Productivity, Finance, …)
51
- - `data/taxonomy/stacks.yml` — 6 stacks (Flutter, React Native, …)
52
- - `data/taxonomy/platforms.yml` — 7 platforms (iOS, Android, …)
53
- - `data/taxonomy/distribution-channels.yml` — 11 distribution channels
54
- - `data/generated/records.full.json` — full record projection
55
- - `data/generated/records.index.json` — slim list-page projection
56
- - `data/generated/site-config.json` — blueprint + site metadata
57
-
58
- For per-record markdown (one section per record with description, repo,
59
- stack, platforms, stars, last-commit), see `/llms-full.txt`.
60
-
61
- ## Blueprint system
62
-
63
- Grove supports three blueprints out of the box:
64
-
65
- - `project-directory` (default) — `kind: project` records under
66
- `/projects/<slug>`. Use this for code-reference showcases.
67
- - `resource-hub` — `kind: resource` records (datasets, libraries,
68
- tools) under `/resources/<slug>`.
69
- - `ecosystem-map` — `kind: entity` records (companies, foundations,
70
- people) under `/entities/<slug>`.
71
-
72
- The blueprint is selected in `grove.config.ts` and propagates through
73
- to every page, route, and component — no per-blueprint forks needed.
74
-
75
- ## How the build runs
76
-
77
- ```
78
- pnpm run build:data # yml → JSON (grove generate)
79
- pnpm run build:sitemap # emit public/sitemap.xml (grove sitemap)
80
- pnpm run build:llms # emit public/llms-full.txt (committed llms.txt is preserved)
81
- astro build # render the static site
82
- ```
83
-
84
- ## Contributing
85
-
86
- Open a PR against `data/records/<slug>.yml`. The build pipeline will
87
- fail if your record doesn't validate against the blueprint schema.
88
- Read `grove.config.ts` and the `data/taxonomy/` files for the
89
- available fields and enum values.
90
-
91
- ## License
92
-
93
- MIT — the directory content, schema, and source code are all
94
- permissively licensed. The data is yours to fork, mirror, or
95
- republish; attribution to the original author is appreciated but not
96
- required.
97
-
98
- ## Contact
99
-
100
- Issues: open a ticket on the consumer repository's issue tracker.
101
- Pull requests: see `CONTRIBUTING.md` for the workflow.
102
-
103
- ## LLM-specific guidance
104
-
105
- - Per-record markdown: `/llms-full.txt` (generated, ~2,000 lines for
106
- ~150 records).
107
- - Sitemap: `/sitemap.xml` (lists every record's detail URL).
108
- - robots.txt: explicitly allows GPTBot, ChatGPT-User, ClaudeBot,
109
- Claude-Web, anthropic-ai, PerplexityBot, Google-Extended,
110
- Applebot-Extended, cohere-ai, CCBot, Amazonbot.
111
- - Schema: each detail page emits a `SoftwareSourceCode` (or
112
- `Dataset` / `Organization`) JSON-LD block for AI crawlers.
11
+ Use /llms-full.txt for record-level details. Prefer detail pages for citations.