@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.
- package/LICENSE +21 -0
- package/dist/template-routes.test.d.ts +2 -0
- package/dist/template-routes.test.d.ts.map +1 -0
- package/dist/template-routes.test.js +63 -0
- package/dist/template-routes.test.js.map +1 -0
- package/dist/theme.test.js +19 -0
- package/dist/theme.test.js.map +1 -1
- package/package.json +4 -4
- package/src/components/CategoryGrid.astro +2 -11
- package/src/components/ContributorsGrid.astro +2 -11
- package/src/components/CurationGrid.astro +1 -1
- package/src/components/DecisionRow.astro +1 -1
- package/src/components/ExploreByCategory.astro +3 -3
- package/src/components/ExploreByStack.astro +3 -3
- package/src/components/FilterGroupMenu.astro +5 -5
- package/src/components/Hero.astro +8 -8
- package/src/components/Icon.astro +56 -53
- package/src/components/IndexRow.astro +5 -5
- package/src/components/ItemCard.astro +5 -16
- package/src/components/MinimalAbout.astro +2 -2
- package/src/components/OriginalCollection.astro +4 -4
- package/src/components/Pagination.astro +2 -2
- package/src/components/RecordSection.astro +1 -1
- package/src/components/RefinePanel.astro +1 -1
- package/src/components/SmartLensTabs.astro +3 -3
- package/src/components/StackGrid.astro +6 -15
- package/src/components/WhyThisExists.astro +3 -3
- package/src/layouts/Container.astro +4 -4
- package/src/layouts/Footer.astro +3 -3
- package/src/layouts/Header.astro +5 -5
- package/src/layouts/ThemeToggle.astro +1 -1
- package/src/styles.css +33 -339
- package/src/template-routes.test.ts +103 -0
- package/src/theme.test.ts +24 -0
- package/templates/default/.github/workflows/build.yml +1 -3
- package/templates/default/.github/workflows/cleanup-stale-records.yml +1 -3
- package/templates/default/.github/workflows/daily-refresh.yml +1 -3
- package/templates/default/.github/workflows/sync-contributors.yml +2 -4
- package/templates/default/.github/workflows/sync-github-metadata.yml +1 -3
- package/templates/default/.github/workflows/validate-data.yml +1 -3
- package/templates/default/grove.config.ts +1 -1
- package/templates/default/package.json +9 -4
- package/templates/default/public/icons/stacks/rag.svg +7 -0
- package/templates/default/public/llms-full.txt +63 -186
- package/templates/default/public/llms.txt +6 -107
- package/templates/default/public/sitemap.xml +10 -10
- package/templates/default/src/data/records.ts +80 -2
- package/templates/default/src/pages/404.astro +5 -5
- package/templates/default/src/pages/[slug]/[recordSlug].astro +36 -38
- package/templates/default/src/pages/[slug]/index.astro +223 -19
- package/templates/default/src/pages/about.astro +17 -10
- package/templates/default/src/pages/apps/[recordSlug].astro +2 -1
- package/templates/default/src/pages/contributors.astro +8 -17
- package/templates/default/src/pages/index.astro +11 -3
- package/templates/default/src/pages/sitemap.xml.ts +3 -3
- package/templates/default/src/pages/submit.astro +28 -36
- package/templates/default/tsconfig.json +9 -0
- package/templates/default/scripts/build-llms.mjs +0 -123
- package/templates/default/scripts/build-records-json.mjs +0 -27
- package/templates/default/scripts/build-sitemap.mjs +0 -20
- package/templates/default/scripts/cleanup-stale-records.mjs +0 -20
- package/templates/default/scripts/enrich-github-metadata.mjs +0 -99
- package/templates/default/scripts/fetch-icons.mjs +0 -137
- package/templates/default/scripts/migrate-legacy-to-schema-v1.mjs +0 -86
- package/templates/default/scripts/parse-legacy-readme.mjs +0 -59
- package/templates/default/scripts/refresh-records-activity.mjs +0 -24
- package/templates/default/scripts/repair-license-format.mjs +0 -72
- package/templates/default/scripts/report-cleanup-candidates.mjs +0 -21
- package/templates/default/scripts/seed-from-github.mjs +0 -62
- package/templates/default/scripts/sync-contributors.mjs +0 -145
- package/templates/default/scripts/sync-github-metadata.mjs +0 -28
- 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
|
});
|
|
@@ -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:
|
|
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:
|
|
39
|
+
run: pnpm exec grove sync contributors
|
|
42
40
|
|
|
43
41
|
- name: Commit contributors.json
|
|
44
42
|
run: |
|
|
@@ -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": "
|
|
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": "
|
|
29
|
-
"@grove-dev/cli": "
|
|
30
|
-
"@grove-dev/core": "
|
|
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
|
-
#
|
|
1
|
+
# Grove Directory — full directory
|
|
2
2
|
|
|
3
|
-
Generated
|
|
4
|
-
|
|
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
|
-
##
|
|
8
|
+
## Index
|
|
9
9
|
|
|
10
|
-
Open-source, self-hostable Heroku / Netlify / Vercel alternative — deploy apps and databases from a single dashboard.
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
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
|
-
|
|
27
|
-
- One-click app + DB deploys
|
|
28
|
-
- Active dev
|
|
29
|
-
- Clear upgrade path from manual Docker
|
|
19
|
+
## Projects
|
|
30
20
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
190
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
Directory: https://example.com/projects
|
|
6
|
+
Records indexed: 8
|
|
7
|
+
Categories: 4
|
|
10
8
|
|
|
11
|
-
##
|
|
9
|
+
## Usage
|
|
12
10
|
|
|
13
|
-
-
|
|
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.
|