Skip to content

Commit 70d6aba

Browse files
Strawbangclaude
andcommitted
fix: correct info and redesign Ecosystem/Integrations
Stats: 4 → 5 open source tools (tersify, aimemo, semtree, semstore, trimcp) Integrations: replace made-up CLI flags with real commands - aimemo setup --claude/--cursor/--windsurf/--copilot - trimcp setup (auto-detects client) Ecosystem: redesign as two-column layout (flow diagram + detail panel) with cross-hover sync between diagram nodes and descriptions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent cbf9783 commit 70d6aba

3 files changed

Lines changed: 204 additions & 166 deletions

File tree

src/components/Ecosystem.astro

Lines changed: 184 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -7,65 +7,82 @@
77
<h2 class="reveal">One stack, zero friction</h2>
88
<p class="section-sub reveal">Each tool solves a distinct problem. Together they cover the full cost of AI-assisted development.</p>
99

10-
<div class="flow reveal">
11-
<div class="flow-col">
12-
<div class="flow-label">Your editor sends a request</div>
13-
<div class="flow-node editor-node">
14-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
10+
<div class="eco-layout reveal">
11+
12+
<!-- Left: flow diagram -->
13+
<div class="eco-flow">
14+
<div class="flow-node node-editor">
15+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1516
<rect x="2" y="3" width="20" height="14" rx="2"/><polyline points="8 21 12 17 16 21"/>
1617
</svg>
17-
Claude Code · Cursor · Windsurf
18+
Your editor
1819
</div>
19-
</div>
2020

21-
<div class="flow-arrow">↓</div>
21+
<div class="flow-connector">
22+
<div class="connector-line"></div>
23+
<div class="connector-branches">
24+
<div class="branch branch-left">
25+
<div class="branch-line"></div>
26+
<div class="flow-node node-tool" data-tool="trimcp">trimcp</div>
27+
</div>
28+
<div class="branch branch-right">
29+
<div class="branch-line"></div>
30+
<div class="flow-node node-tool" data-tool="tersify">tersify</div>
31+
</div>
32+
</div>
33+
</div>
2234

23-
<div class="flow-row">
24-
<div class="flow-tool">
25-
<div class="tool-chip chip-rust">trimcp</div>
26-
<p>MCP tool outputs compressed before they reach the model</p>
27-
<span class="tool-stat">−60–90% tokens on MCP responses</span>
35+
<div class="flow-connector">
36+
<div class="connector-branches">
37+
<div class="branch branch-left">
38+
<div class="branch-line"></div>
39+
<div class="flow-node node-tool" data-tool="semtree">semtree</div>
40+
</div>
41+
<div class="branch branch-right">
42+
<div class="branch-line"></div>
43+
<div class="flow-node node-tool" data-tool="aimemo">aimemo</div>
44+
</div>
45+
</div>
46+
<div class="connector-line"></div>
2847
</div>
29-
<div class="flow-tool">
30-
<div class="tool-chip chip-rust">tersify</div>
31-
<p>Code and text stripped of noise before being sent</p>
32-
<span class="tool-stat">−50% tokens on code context</span>
48+
49+
<div class="flow-node node-result">
50+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
51+
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
52+
</svg>
53+
Faster · cheaper · smarter
3354
</div>
3455
</div>
3556

36-
<div class="flow-arrow">↓</div>
37-
38-
<div class="flow-row">
39-
<div class="flow-tool">
40-
<div class="tool-chip chip-rust">semtree</div>
41-
<p>Codebase parsed and indexed semantically with tree-sitter</p>
42-
<span class="tool-stat">Precise context — only what's relevant</span>
57+
<!-- Right: tool descriptions -->
58+
<div class="eco-details">
59+
<div class="eco-item" data-tool="trimcp">
60+
<div class="eco-name">trimcp</div>
61+
<p>MCP tool outputs compressed before they reach the model.</p>
62+
<span class="eco-stat">−60–90% tokens on MCP responses</span>
4363
</div>
44-
<div class="flow-tool">
45-
<div class="tool-chip chip-rust">aimemo</div>
46-
<p>Decisions, conventions, and tasks remembered across sessions</p>
47-
<span class="tool-stat">No repeated explanations</span>
64+
<div class="eco-item" data-tool="tersify">
65+
<div class="eco-name">tersify</div>
66+
<p>Code and text stripped of noise before being sent.</p>
67+
<span class="eco-stat">−50% tokens on code context</span>
68+
</div>
69+
<div class="eco-item" data-tool="semtree">
70+
<div class="eco-name">semtree</div>
71+
<p>Codebase indexed semantically — only relevant code injected.</p>
72+
<span class="eco-stat">Precise context, no noise</span>
73+
</div>
74+
<div class="eco-item" data-tool="aimemo">
75+
<div class="eco-name">aimemo</div>
76+
<p>Decisions and conventions remembered across sessions.</p>
77+
<span class="eco-stat">No repeated explanations</span>
4878
</div>
49-
</div>
50-
51-
<div class="flow-arrow">↓</div>
5279

53-
<div class="flow-col">
54-
<div class="flow-label">The model gets what it needs — nothing more</div>
55-
<div class="flow-node result-node">
56-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
57-
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
58-
</svg>
59-
Faster · cheaper · smarter completions
80+
<div class="eco-note">
81+
<span class="note-tag">Also standalone</span>
82+
<span><a href="/projects/semstore">semstore</a> is the vector store powering semtree — available as a library for any Rust app.</span>
6083
</div>
6184
</div>
62-
</div>
6385

64-
<div class="also-note reveal">
65-
<span class="note-label">Also standalone</span>
66-
<span class="note-text">
67-
<a href="/projects/semstore">semstore</a> is the vector store powering semtree — available as a library to build your own semantic search into any Rust app.
68-
</span>
6986
</div>
7087
</div>
7188
</section>
@@ -76,148 +93,190 @@
7693
border-bottom: 1px solid var(--border);
7794
}
7895

79-
.flow {
96+
.eco-layout {
8097
margin-top: 3rem;
81-
display: flex;
82-
flex-direction: column;
98+
display: grid;
99+
grid-template-columns: 1fr 1fr;
100+
gap: 4rem;
83101
align-items: center;
84-
gap: 0;
85102
}
86103

87-
.flow-arrow {
88-
font-size: 1.25rem;
89-
color: var(--rust-dim);
90-
padding: 0.75rem 0;
91-
line-height: 1;
92-
}
93-
94-
.flow-col {
104+
/* Flow diagram */
105+
.eco-flow {
95106
display: flex;
96107
flex-direction: column;
97108
align-items: center;
98-
gap: 0.75rem;
99-
width: 100%;
100-
max-width: 600px;
101-
}
102-
103-
.flow-label {
104-
font-family: 'IBM Plex Mono', monospace;
105-
font-size: 0.72rem;
106-
color: var(--text-dim);
107-
text-transform: uppercase;
108-
letter-spacing: 0.1em;
109+
gap: 0;
110+
user-select: none;
109111
}
110112

111113
.flow-node {
112114
display: inline-flex;
113115
align-items: center;
114-
gap: 0.6rem;
115-
padding: 0.65rem 1.5rem;
116+
gap: 0.5rem;
117+
padding: 0.55rem 1.25rem;
116118
border-radius: 4px;
117119
font-family: 'IBM Plex Mono', monospace;
118-
font-size: 0.82rem;
119-
width: 100%;
120-
max-width: 480px;
121-
justify-content: center;
120+
font-size: 0.8rem;
121+
white-space: nowrap;
122+
position: relative;
123+
z-index: 1;
122124
}
123125

124-
.editor-node {
126+
.node-editor {
125127
background: var(--bg-2);
126128
border: 1px solid var(--border-hi);
127129
color: var(--text-muted);
128130
}
129131

130-
.result-node {
132+
.node-result {
131133
background: var(--rust-glow);
132134
border: 1px solid var(--rust-dim);
133135
color: var(--rust);
134136
}
135137

136-
.flow-row {
137-
display: grid;
138-
grid-template-columns: 1fr 1fr;
139-
gap: 1px;
138+
.node-tool {
139+
background: var(--bg-3);
140+
border: 1px solid var(--border);
141+
color: var(--text-dim);
142+
font-weight: 500;
143+
letter-spacing: -0.01em;
144+
transition: border-color 0.2s, color 0.2s, background 0.2s;
145+
cursor: default;
146+
}
147+
148+
.node-tool.active,
149+
.node-tool:hover {
150+
border-color: var(--rust-dim);
151+
color: var(--rust);
152+
background: var(--rust-glow);
153+
}
154+
155+
.flow-connector {
156+
display: flex;
157+
flex-direction: column;
158+
align-items: center;
140159
width: 100%;
141-
max-width: 700px;
160+
max-width: 260px;
161+
}
162+
163+
.connector-line {
164+
width: 1px;
165+
height: 20px;
166+
background: var(--border);
167+
}
168+
169+
.connector-branches {
170+
display: flex;
171+
width: 100%;
172+
justify-content: center;
173+
gap: 0;
174+
}
175+
176+
.branch {
177+
display: flex;
178+
flex-direction: column;
179+
align-items: center;
180+
flex: 1;
181+
}
182+
183+
.branch-line {
184+
width: 1px;
185+
height: 20px;
142186
background: var(--border);
187+
}
188+
189+
/* Details panel */
190+
.eco-details {
191+
display: flex;
192+
flex-direction: column;
193+
gap: 0;
143194
border: 1px solid var(--border);
144195
border-radius: 6px;
145196
overflow: hidden;
146197
}
147198

148-
.flow-tool {
149-
background: var(--bg-2);
150-
padding: 1.25rem 1.5rem;
151-
display: flex;
152-
flex-direction: column;
153-
gap: 0.5rem;
199+
.eco-item {
200+
padding: 1rem 1.25rem;
201+
border-bottom: 1px solid var(--border);
202+
transition: background 0.2s;
203+
cursor: default;
154204
}
155205

156-
.tool-chip {
206+
.eco-item:last-of-type { border-bottom: none; }
207+
.eco-item:hover,
208+
.eco-item.active { background: var(--bg-3); }
209+
210+
.eco-name {
157211
font-family: 'Space Mono', monospace;
158-
font-size: 0.78rem;
212+
font-size: 0.82rem;
159213
font-weight: 700;
214+
color: var(--rust);
160215
letter-spacing: -0.02em;
161-
display: inline-block;
162-
margin-bottom: 0.25rem;
216+
margin-bottom: 0.3rem;
163217
}
164218

165-
.chip-rust { color: var(--rust); }
166-
167-
.flow-tool p {
219+
.eco-item p {
168220
font-size: 0.82rem;
169221
color: var(--text-muted);
170-
line-height: 1.6;
171-
margin: 0;
222+
line-height: 1.55;
223+
margin: 0 0 0.4rem;
172224
}
173225

174-
.tool-stat {
226+
.eco-stat {
175227
font-family: 'IBM Plex Mono', monospace;
176-
font-size: 0.7rem;
228+
font-size: 0.68rem;
177229
color: var(--text-dim);
178-
border-top: 1px solid var(--border);
179-
padding-top: 0.5rem;
180-
margin-top: 0.25rem;
230+
letter-spacing: 0.02em;
181231
}
182232

183-
.also-note {
184-
margin-top: 2.5rem;
233+
.eco-note {
234+
padding: 0.85rem 1.25rem;
235+
background: var(--bg-2);
236+
border-top: 1px solid var(--border);
185237
display: flex;
238+
gap: 0.6rem;
186239
align-items: baseline;
187-
gap: 0.75rem;
188-
padding: 1rem 1.5rem;
189-
background: var(--bg-2);
190-
border: 1px solid var(--border);
191-
border-radius: 4px;
192-
max-width: 700px;
193-
width: 100%;
240+
flex-wrap: wrap;
241+
font-size: 0.8rem;
242+
color: var(--text-muted);
243+
line-height: 1.5;
194244
}
195245

196-
.note-label {
246+
.note-tag {
197247
font-family: 'IBM Plex Mono', monospace;
198-
font-size: 0.68rem;
248+
font-size: 0.65rem;
199249
text-transform: uppercase;
200250
letter-spacing: 0.1em;
201251
color: var(--rust);
202252
white-space: nowrap;
203253
flex-shrink: 0;
204254
}
205255

206-
.note-text {
207-
font-size: 0.85rem;
208-
color: var(--text-muted);
209-
line-height: 1.6;
210-
}
256+
.eco-note a { color: var(--rust); text-decoration: none; }
257+
.eco-note a:hover { text-decoration: underline; }
211258

212-
.note-text a {
213-
color: var(--rust);
214-
text-decoration: none;
259+
@media (max-width: 860px) {
260+
.eco-layout { grid-template-columns: 1fr; gap: 2rem; }
261+
.eco-flow { display: none; }
215262
}
263+
</style>
216264

217-
.note-text a:hover { text-decoration: underline; }
265+
<script>
266+
// Sync hover between flow nodes and detail items
267+
const tools = ['trimcp', 'tersify', 'semtree', 'aimemo'];
218268

219-
@media (max-width: 640px) {
220-
.flow-row { grid-template-columns: 1fr; }
221-
.also-note { flex-direction: column; gap: 0.4rem; }
222-
}
223-
</style>
269+
tools.forEach((tool) => {
270+
const node = document.querySelector<HTMLElement>(`.node-tool[data-tool="${tool}"]`);
271+
const item = document.querySelector<HTMLElement>(`.eco-item[data-tool="${tool}"]`);
272+
if (!node || !item) return;
273+
274+
const activate = () => { node.classList.add('active'); item.classList.add('active'); };
275+
const deactivate = () => { node.classList.remove('active'); item.classList.remove('active'); };
276+
277+
node.addEventListener('mouseenter', activate);
278+
node.addEventListener('mouseleave', deactivate);
279+
item.addEventListener('mouseenter', activate);
280+
item.addEventListener('mouseleave', deactivate);
281+
});
282+
</script>

0 commit comments

Comments
 (0)