Skip to content

Commit 9d6a006

Browse files
committed
feat: add project pages, crates.io links, update memo-agent repo
1 parent 6ce244a commit 9d6a006

6 files changed

Lines changed: 515 additions & 146 deletions

File tree

src/components/Footer.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
<div class="footer-right">
1212
<div class="footer-col">
1313
<div class="footer-col-title">Projects</div>
14-
<a href="https://github.com/rustkit-ai/memo" target="_blank" rel="noopener">memo</a>
14+
<a href="https://github.com/rustkit-ai/memo-agent" target="_blank" rel="noopener">memo</a>
1515
<a href="https://github.com/rustkit-ai/rustkit-mcp" target="_blank" rel="noopener">rustkit-mcp</a>
1616
<a href="https://github.com/rustkit-ai/rustkit-semantic" target="_blank" rel="noopener">rustkit-semantic</a>
1717
</div>
1818
<div class="footer-col">
1919
<div class="footer-col-title">Organization</div>
2020
<a href="https://github.com/rustkit-ai" target="_blank" rel="noopener">GitHub</a>
21-
<a href="https://github.com/rustkit-ai/memo/releases" target="_blank" rel="noopener">Releases</a>
21+
<a href="https://github.com/rustkit-ai/memo-agent/releases" target="_blank" rel="noopener">Releases</a>
2222
<a href="/team">Team</a>
2323
</div>
2424
</div>

src/components/Hero.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
<div class="install-block">
1919
<span class="install-prompt">$</span>
20-
<code id="install-cmd">cargo install memo</code>
20+
<code id="install-cmd">cargo install memo-agent</code>
2121
<button class="copy-btn" id="copy-btn" aria-label="Copy install command">
2222
<svg id="icon-copy" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2323
<rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/>
@@ -231,7 +231,7 @@
231231
const iconCheck = document.getElementById('icon-check');
232232

233233
btn?.addEventListener('click', () => {
234-
navigator.clipboard.writeText('cargo install memo');
234+
navigator.clipboard.writeText('cargo install memo-agent');
235235
btn.classList.add('copied');
236236
iconCopy!.style.display = 'none';
237237
iconCheck!.style.display = 'block';

src/components/Projects.astro

Lines changed: 70 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,20 @@
11
---
2-
// Fetch stars at build time from GitHub API
2+
import { projects } from '../data/projects';
3+
34
type Repo = { name: string; stargazers_count: number };
45
56
let repoStars: Record<string, number> = {};
67
try {
78
const res = await fetch('https://api.github.com/orgs/rustkit-ai/repos');
89
const repos: Repo[] = await res.json();
910
repos.forEach((r) => { repoStars[r.name] = r.stargazers_count; });
10-
} catch {
11-
// fallback — stars stay 0
12-
}
13-
14-
const projects = [
15-
{
16-
name: 'memo',
17-
description: 'Persistent memory for AI coding agents — Claude Code, Cursor, Windsurf, and Copilot. One command setup, zero manual steps.',
18-
url: 'https://github.com/rustkit-ai/memo',
19-
install: 'cargo install memo',
20-
stars: repoStars['memo'] ?? 0,
21-
icon: 'brain',
22-
},
23-
{
24-
name: 'rustkit-mcp',
25-
description: 'An MCP proxy that dramatically reduces LLM token costs. Sit between your AI tools and APIs — efficient, transparent, fast.',
26-
url: 'https://github.com/rustkit-ai/rustkit-mcp',
27-
install: 'cargo install rustkit-mcp',
28-
stars: repoStars['rustkit-mcp'] ?? 0,
29-
icon: 'activity',
30-
},
31-
{
32-
name: 'rustkit-semantic',
33-
description: 'Local semantic search for Rust apps — store text, search by meaning. No cloud, no API key. Powered by BGE-Small + HNSW + SQLite, runs fully on-device.',
34-
url: 'https://github.com/rustkit-ai/rustkit-semantic',
35-
install: 'cargo add rustkit-semantic',
36-
stars: repoStars['rustkit-semantic'] ?? 0,
37-
icon: 'search',
38-
},
39-
];
11+
} catch {}
12+
13+
const icons: Record<string, string> = {
14+
'memo-agent': 'brain',
15+
'rustkit-mcp': 'activity',
16+
'rustkit-semantic': 'search',
17+
};
4018
---
4119

4220
<section id="projects">
@@ -46,54 +24,58 @@ const projects = [
4624
<p class="section-sub reveal">Open source tools designed to make AI-assisted development faster and smarter.</p>
4725

4826
<div class="projects-grid">
49-
{projects.map((p) => (
50-
<a href={p.url} target="_blank" rel="noopener" class="project-card reveal">
51-
<div class="card-header">
52-
<div class="card-icon">
53-
{p.icon === 'brain' && (
54-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
55-
<path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z"/><circle cx="12" cy="12" r="3"/>
56-
</svg>
57-
)}
58-
{p.icon === 'activity' && (
59-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
60-
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
61-
</svg>
62-
)}
63-
{p.icon === 'search' && (
64-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
65-
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
66-
</svg>
67-
)}
27+
{projects.map((p) => {
28+
const stars = repoStars[p.slug] ?? 0;
29+
const icon = icons[p.slug] ?? 'search';
30+
return (
31+
<a href={`/projects/${p.slug}`} class="project-card reveal">
32+
<div class="card-header">
33+
<div class="card-icon">
34+
{icon === 'brain' && (
35+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
36+
<path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z"/><circle cx="12" cy="12" r="3"/>
37+
</svg>
38+
)}
39+
{icon === 'activity' && (
40+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
41+
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
42+
</svg>
43+
)}
44+
{icon === 'search' && (
45+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
46+
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
47+
</svg>
48+
)}
49+
</div>
50+
<div class="card-badges">
51+
<span class="badge badge-rust">{p.language}</span>
52+
{stars > 0 && (
53+
<span class="badge badge-stars">
54+
<svg width="10" height="10" viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
55+
{stars}
56+
</span>
57+
)}
58+
</div>
6859
</div>
69-
<div class="card-badges">
70-
<span class="badge badge-rust">Rust</span>
71-
{p.stars > 0 && (
72-
<span class="badge badge-stars">
73-
<svg width="10" height="10" viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
74-
{p.stars}
75-
</span>
76-
)}
77-
</div>
78-
</div>
7960

80-
<div class="card-name">{p.name}</div>
81-
<p class="card-desc">{p.description}</p>
61+
<div class="card-name">{p.name}</div>
62+
<p class="card-desc">{p.description}</p>
63+
64+
{p.install && (
65+
<div class="card-install">
66+
<span class="install-prompt">$</span>
67+
<code>{p.install}</code>
68+
</div>
69+
)}
8270

83-
{p.install && (
84-
<div class="card-install">
85-
<span class="install-prompt">$</span>
86-
<code>{p.install}</code>
71+
<div class="card-footer">
72+
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
73+
rustkit-ai/{p.name}
74+
<span class="card-arrow">→</span>
8775
</div>
88-
)}
89-
90-
<div class="card-footer">
91-
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
92-
rustkit-ai/{p.name}
93-
<span class="card-arrow">→</span>
94-
</div>
95-
</a>
96-
))}
76+
</a>
77+
);
78+
})}
9779
</div>
9880
</div>
9981
</section>
@@ -136,31 +118,18 @@ const projects = [
136118
.project-card:hover { background: var(--bg-3); }
137119
.project-card:hover::before { transform: scaleX(1); }
138120

139-
.card-header {
140-
display: flex;
141-
align-items: flex-start;
142-
justify-content: space-between;
143-
gap: 1rem;
144-
}
121+
.card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
145122

146123
.card-icon {
147-
width: 36px;
148-
height: 36px;
124+
width: 36px; height: 36px;
149125
border-radius: 6px;
150126
background: var(--rust-glow);
151127
border: 1px solid var(--rust-dim);
152-
display: flex;
153-
align-items: center;
154-
justify-content: center;
128+
display: flex; align-items: center; justify-content: center;
155129
flex-shrink: 0;
156130
}
157131

158-
.card-icon svg {
159-
width: 18px;
160-
height: 18px;
161-
color: var(--rust);
162-
}
163-
132+
.card-icon svg { width: 18px; height: 18px; color: var(--rust); }
164133
.card-badges { display: flex; gap: 0.4rem; flex-wrap: wrap; }
165134

166135
.badge {
@@ -173,62 +142,24 @@ const projects = [
173142
}
174143

175144
.badge-rust { background: #e8591a18; color: #e87a4a; border: 1px solid #e8591a30; }
176-
.badge-stars {
177-
background: var(--blue-dim);
178-
color: var(--blue);
179-
border: 1px solid #4a9eff30;
180-
display: flex;
181-
align-items: center;
182-
gap: 0.3rem;
183-
}
184-
185-
.card-name {
186-
font-family: 'Space Mono', monospace;
187-
font-size: 1rem;
188-
font-weight: 700;
189-
letter-spacing: -0.02em;
190-
color: var(--text);
191-
}
145+
.badge-stars { background: var(--blue-dim); color: var(--blue); border: 1px solid #4a9eff30; display: flex; align-items: center; gap: 0.3rem; }
192146

147+
.card-name { font-family: 'Space Mono', monospace; font-size: 1rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
193148
.card-desc { font-size: 0.88rem; color: var(--text-muted); line-height: 1.6; flex: 1; }
194149

195150
.card-install {
196-
display: flex;
197-
align-items: center;
198-
gap: 0.5rem;
199-
background: var(--bg);
200-
border: 1px solid var(--border);
201-
border-radius: 4px;
202-
padding: 0.4rem 0.75rem;
203-
}
204-
205-
.install-prompt {
206-
font-family: 'IBM Plex Mono', monospace;
207-
font-size: 0.75rem;
208-
color: var(--rust);
209-
}
210-
211-
.card-install code {
212-
font-family: 'IBM Plex Mono', monospace;
213-
font-size: 0.75rem;
214-
color: var(--text-muted);
151+
display: flex; align-items: center; gap: 0.5rem;
152+
background: var(--bg); border: 1px solid var(--border);
153+
border-radius: 4px; padding: 0.4rem 0.75rem;
215154
}
216155

217-
.card-footer {
218-
display: flex;
219-
align-items: center;
220-
gap: 0.4rem;
221-
font-family: 'IBM Plex Mono', monospace;
222-
font-size: 0.75rem;
223-
color: var(--text-dim);
224-
transition: color 0.2s;
225-
}
156+
.install-prompt { font-family: 'IBM Plex Mono', monospace; font-size: 0.75rem; color: var(--rust); }
157+
.card-install code { font-family: 'IBM Plex Mono', monospace; font-size: 0.75rem; color: var(--text-muted); }
226158

159+
.card-footer { display: flex; align-items: center; gap: 0.4rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.75rem; color: var(--text-dim); transition: color 0.2s; }
227160
.project-card:hover .card-footer { color: var(--rust); }
228161
.card-arrow { margin-left: auto; transition: transform 0.2s; }
229162
.project-card:hover .card-arrow { transform: translateX(3px); }
230163

231-
@media (max-width: 640px) {
232-
.projects-grid { grid-template-columns: 1fr; }
233-
}
164+
@media (max-width: 640px) { .projects-grid { grid-template-columns: 1fr; } }
234165
</style>

src/components/Releases.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type Release = {
99
1010
let releases: Release[] = [];
1111
try {
12-
const res = await fetch('https://api.github.com/repos/rustkit-ai/memo/releases');
12+
const res = await fetch('https://api.github.com/repos/rustkit-ai/memo-agent/releases');
1313
const data: Release[] = await res.json();
1414
releases = data
1515
.filter((r) => r.published_at)
@@ -34,7 +34,7 @@ function formatDate(iso: string) {
3434
<div class="section-label reveal">Changelog</div>
3535
<h2 class="reveal">Latest releases</h2>
3636
<p class="section-sub reveal">
37-
Recent updates to <a href="https://github.com/rustkit-ai/memo" target="_blank" rel="noopener">memo</a>.
37+
Recent updates to <a href="https://github.com/rustkit-ai/memo-agent" target="_blank" rel="noopener">memo</a>.
3838
</p>
3939

4040
<div class="releases-list reveal">
@@ -51,7 +51,7 @@ function formatDate(iso: string) {
5151
))}
5252
</div>
5353

54-
<a href="https://github.com/rustkit-ai/memo/releases" target="_blank" rel="noopener" class="all-releases">
54+
<a href="https://github.com/rustkit-ai/memo-agent/releases" target="_blank" rel="noopener" class="all-releases">
5555
View all releases →
5656
</a>
5757
</div>

src/data/projects.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
export type Project = {
2+
slug: string;
3+
name: string;
4+
description: string;
5+
longDescription: string;
6+
github: string;
7+
crates: string | null;
8+
install: string | null;
9+
language: string;
10+
hasReleases: boolean;
11+
};
12+
13+
export const projects: Project[] = [
14+
{
15+
slug: 'memo-agent',
16+
name: 'memo',
17+
description: 'Persistent memory for AI coding agents — Claude Code, Cursor, Windsurf, and Copilot. One command setup, zero manual steps.',
18+
longDescription: `memo gives AI coding agents a persistent, structured memory that survives across sessions.
19+
Instead of losing context between conversations, your agent remembers what matters — architecture decisions, conventions, ongoing tasks, and more.
20+
21+
Works out of the box with Claude Code, Cursor, Windsurf, and GitHub Copilot. One command to install, zero config required.`,
22+
github: 'https://github.com/rustkit-ai/memo-agent',
23+
crates: 'https://crates.io/crates/memo-agent',
24+
install: 'cargo install memo-agent',
25+
language: 'Rust',
26+
hasReleases: true,
27+
},
28+
{
29+
slug: 'rustkit-mcp',
30+
name: 'rustkit-mcp',
31+
description: 'An MCP proxy that dramatically reduces LLM token costs. Sit between your AI tools and APIs — efficient, transparent, fast.',
32+
longDescription: `rustkit-mcp is a proxy layer for the Model Context Protocol (MCP) that filters, compresses, and optimizes tool output before it reaches your LLM.
33+
34+
The result: significantly fewer tokens consumed per request, without changing your workflow. Drop it in between your AI tools and your MCP servers — it's transparent by design.`,
35+
github: 'https://github.com/rustkit-ai/rustkit-mcp',
36+
crates: null,
37+
install: null,
38+
language: 'Rust',
39+
hasReleases: false,
40+
},
41+
{
42+
slug: 'rustkit-semantic',
43+
name: 'rustkit-semantic',
44+
description: 'Local semantic search for Rust apps — store text, search by meaning. No cloud, no API key. Powered by BGE-Small + HNSW + SQLite, runs fully on-device.',
45+
longDescription: `rustkit-semantic gives your Rust application a semantic search index backed by BGE-Small-EN-v1.5 (23MB, runs on CPU), HNSW approximate nearest-neighbour search, and SQLite for persistent storage.
46+
47+
No cloud. No API key. Everything runs on-device. Typical use cases include RAG pipelines, semantic caching, knowledge bases, and deduplication.`,
48+
github: 'https://github.com/rustkit-ai/rustkit-semantic',
49+
crates: 'https://crates.io/crates/rustkit-semantic',
50+
install: 'cargo add rustkit-semantic',
51+
language: 'Rust',
52+
hasReleases: false,
53+
},
54+
];

0 commit comments

Comments
 (0)