Skip to content

Commit 064e849

Browse files
dcramerclaude
andcommitted
feat: Add Bun runtime support
- Add bun to package.json engines field - Add test-bun CI job to run tests under Bun - Create PackageManagerTabs component for npm/pnpm/bun install options - Update docs homepage and install page with tabbed package manager UI - Add shared preference persistence (localStorage) across all pages - Consolidate CLI output styles into global.css - Update llms.txt with all package manager options Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7ef0b21 commit 064e849

File tree

8 files changed

+325
-64
lines changed

8 files changed

+325
-64
lines changed

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,23 @@ jobs:
2929

3030
- name: Run tests
3131
run: pnpm test
32+
33+
test-bun:
34+
runs-on: ubuntu-latest
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@v4
38+
39+
- name: Setup Bun
40+
uses: oven-sh/setup-bun@v2
41+
with:
42+
bun-version: latest
43+
44+
- name: Install dependencies
45+
run: bun install --frozen-lockfile
46+
47+
- name: Build
48+
run: bun run build
49+
50+
- name: Run tests
51+
run: bun test

docs/public/llms.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,26 @@ Two steps are required:
88

99
1. Install the CLI globally:
1010
```
11+
# npm
1112
npm install -g @zeeg/dex
13+
14+
# pnpm
15+
pnpm add -g @zeeg/dex
16+
17+
# bun
18+
bun add -g @zeeg/dex
1219
```
1320

1421
2. Add skills to your agent:
1522
```
23+
# npm
1624
npx skills dcramer/dex
25+
26+
# pnpm
27+
pnpm dlx skills dcramer/dex
28+
29+
# bun
30+
bunx skills dcramer/dex
1731
```
1832

1933
## Project Configuration
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
interface Props {
3+
npm: string;
4+
pnpm: string;
5+
bun: string;
6+
}
7+
8+
const { npm, pnpm, bun } = Astro.props;
9+
---
10+
11+
<div class="pm-tabs">
12+
<div class="terminal">
13+
<div class="terminal-header">
14+
<div class="terminal-dots">
15+
<span class="dot red"></span>
16+
<span class="dot yellow"></span>
17+
<span class="dot green"></span>
18+
</div>
19+
<div class="tab-buttons">
20+
<button class="tab-btn active" data-pm="npm">npm</button>
21+
<button class="tab-btn" data-pm="pnpm">pnpm</button>
22+
<button class="tab-btn" data-pm="bun">bun</button>
23+
</div>
24+
<button class="copy-button" aria-label="Copy to clipboard">
25+
<svg class="copy-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
26+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
27+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
28+
</svg>
29+
<svg class="check-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
30+
<polyline points="20 6 9 17 4 12"></polyline>
31+
</svg>
32+
</button>
33+
</div>
34+
<div class="terminal-body">
35+
<pre class="tab-content cli-output" data-pm="npm"><span class="cli-dim">$</span> {npm}</pre>
36+
<pre class="tab-content cli-output hidden" data-pm="pnpm"><span class="cli-dim">$</span> {pnpm}</pre>
37+
<pre class="tab-content cli-output hidden" data-pm="bun"><span class="cli-dim">$</span> {bun}</pre>
38+
</div>
39+
</div>
40+
</div>
41+
42+
<style>
43+
.pm-tabs {
44+
margin: 1.5rem 0;
45+
}
46+
47+
.terminal {
48+
background: #000;
49+
border: 1px solid rgba(255, 255, 255, 0.1);
50+
border-radius: 8px;
51+
overflow: hidden;
52+
box-shadow:
53+
0 0 0 1px rgba(255, 255, 255, 0.05),
54+
0 20px 50px -10px rgba(0, 0, 0, 0.7);
55+
position: relative;
56+
}
57+
58+
.terminal-header {
59+
display: flex;
60+
align-items: center;
61+
padding: 8px 12px;
62+
background: #0a0a0a;
63+
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
64+
gap: 8px;
65+
}
66+
67+
.terminal-dots {
68+
display: flex;
69+
gap: 6px;
70+
}
71+
72+
.dot {
73+
width: 10px;
74+
height: 10px;
75+
border-radius: 50%;
76+
}
77+
78+
.dot.red {
79+
background: #ff5f57;
80+
}
81+
82+
.dot.yellow {
83+
background: #febc2e;
84+
}
85+
86+
.dot.green {
87+
background: #28c840;
88+
}
89+
90+
.tab-buttons {
91+
display: flex;
92+
gap: 2px;
93+
margin-left: 8px;
94+
background: rgba(255, 255, 255, 0.05);
95+
border-radius: 4px;
96+
padding: 2px;
97+
}
98+
99+
.tab-btn {
100+
font-family: var(--font-mono);
101+
font-size: 0.7rem;
102+
color: #888;
103+
background: transparent;
104+
border: none;
105+
padding: 4px 10px;
106+
cursor: pointer;
107+
border-radius: 3px;
108+
transition: all 0.15s;
109+
}
110+
111+
.tab-btn:hover {
112+
color: #ccc;
113+
}
114+
115+
.tab-btn.active {
116+
background: rgba(255, 255, 255, 0.1);
117+
color: #fff;
118+
}
119+
120+
.copy-button {
121+
margin-left: auto;
122+
background: transparent;
123+
border: 1px solid rgba(255, 255, 255, 0.1);
124+
border-radius: 4px;
125+
padding: 4px 8px;
126+
cursor: pointer;
127+
color: #888;
128+
display: flex;
129+
align-items: center;
130+
gap: 4px;
131+
transition: all 0.2s;
132+
}
133+
134+
.copy-button:hover {
135+
background: rgba(255, 255, 255, 0.05);
136+
border-color: rgba(255, 255, 255, 0.2);
137+
color: #fff;
138+
}
139+
140+
.copy-button .check-icon {
141+
display: none;
142+
}
143+
144+
.copy-button.copied {
145+
border-color: #4ade80;
146+
color: #4ade80;
147+
}
148+
149+
.copy-button.copied .copy-icon {
150+
display: none;
151+
}
152+
153+
.copy-button.copied .check-icon {
154+
display: block;
155+
}
156+
157+
.terminal-body {
158+
padding: 1rem 1.25rem;
159+
}
160+
161+
/* Override global pre styles */
162+
.terminal-body pre {
163+
background: transparent !important;
164+
border: none !important;
165+
border-radius: 0 !important;
166+
padding: 0 !important;
167+
margin: 0 !important;
168+
box-shadow: none !important;
169+
}
170+
171+
.tab-content.hidden {
172+
display: none;
173+
}
174+
</style>

docs/src/layouts/Base.astro

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,63 @@ const base = import.meta.env.BASE_URL.replace(/\/$/, '');
103103
setTimeout(() => target.scrollIntoView(), 0);
104104
}
105105
}
106+
107+
// Package manager preference (shared across all pages)
108+
const PM_STORAGE_KEY = 'dex-docs-pm';
109+
110+
function setPackageManager(pm: string) {
111+
document.querySelectorAll('.pm-tabs').forEach((container) => {
112+
const buttons = container.querySelectorAll('.tab-btn');
113+
const contents = container.querySelectorAll('.tab-content');
114+
115+
buttons.forEach((btn) => {
116+
btn.classList.toggle('active', btn.getAttribute('data-pm') === pm);
117+
});
118+
119+
contents.forEach((content) => {
120+
content.classList.toggle('hidden', content.getAttribute('data-pm') !== pm);
121+
});
122+
});
123+
}
124+
125+
function initPackageManagerTabs() {
126+
const savedPm = localStorage.getItem(PM_STORAGE_KEY);
127+
if (savedPm) {
128+
setPackageManager(savedPm);
129+
}
130+
131+
document.querySelectorAll('.pm-tabs').forEach((container) => {
132+
container.querySelectorAll('.tab-btn').forEach((btn) => {
133+
btn.addEventListener('click', () => {
134+
const pm = btn.getAttribute('data-pm');
135+
if (!pm) return;
136+
localStorage.setItem(PM_STORAGE_KEY, pm);
137+
setPackageManager(pm);
138+
});
139+
});
140+
141+
const copyButton = container.querySelector('.copy-button');
142+
if (copyButton) {
143+
copyButton.addEventListener('click', async () => {
144+
const activeContent = container.querySelector('.tab-content:not(.hidden)');
145+
if (!activeContent) return;
146+
147+
const textToCopy = (activeContent.textContent || '').replace(/^\s*[$>]\s*/, '').trim();
148+
149+
try {
150+
await navigator.clipboard.writeText(textToCopy);
151+
copyButton.classList.add('copied');
152+
setTimeout(() => copyButton.classList.remove('copied'), 2000);
153+
} catch (err) {
154+
console.error('Failed to copy:', err);
155+
}
156+
});
157+
}
158+
});
159+
}
160+
161+
initPackageManagerTabs();
162+
document.addEventListener('astro:page-load', initPackageManagerTabs);
106163
</script>
107164
<main class="container">
108165
<slot />

docs/src/pages/index.astro

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
import Base from '../layouts/Base.astro';
33
import Terminal from '../components/Terminal.astro';
4+
import PackageManagerTabs from '../components/PackageManagerTabs.astro';
45
56
const base = import.meta.env.BASE_URL.replace(/\/$/, '');
67
---
@@ -25,13 +26,17 @@ const base = import.meta.env.BASE_URL.replace(/\/$/, '');
2526
<section class="section">
2627
<h2>Quick Start</h2>
2728
<p>Install dex globally:</p>
28-
<Terminal title="Terminal" showCopy={true}>
29-
<pre class="cli-output"><span class="cli-dim">$</span> npm install -g @zeeg/dex</pre>
30-
</Terminal>
29+
<PackageManagerTabs
30+
npm="npm install -g @zeeg/dex"
31+
pnpm="pnpm add -g @zeeg/dex"
32+
bun="bun add -g @zeeg/dex"
33+
/>
3134
<p>Or use the skills installer for Claude Code, OpenCode, Codex, or Cursor:</p>
32-
<Terminal title="Terminal" showCopy={true}>
33-
<pre class="cli-output"><span class="cli-dim">$</span> npx skills dcramer/dex</pre>
34-
</Terminal>
35+
<PackageManagerTabs
36+
npm="npx skills dcramer/dex"
37+
pnpm="pnpm dlx skills dcramer/dex"
38+
bun="bunx skills dcramer/dex"
39+
/>
3540
<p>Then use <code>/dex</code> to manage tasks. See the <a href={`${base}/install`}>install guide</a> for other installation methods.</p>
3641
</section>
3742

@@ -201,39 +206,4 @@ but index.ts uses loadConfig() with no argument."
201206
margin: 0;
202207
}
203208

204-
/* CLI output colors */
205-
.cli-output {
206-
font-family: var(--font-mono);
207-
font-size: 0.875rem;
208-
line-height: 1.6;
209-
color: #e5e5e5;
210-
margin: 0;
211-
white-space: pre-wrap;
212-
word-break: break-word;
213-
}
214-
215-
.cli-green {
216-
color: #4ade80;
217-
}
218-
219-
.cli-yellow {
220-
color: #facc15;
221-
}
222-
223-
.cli-cyan {
224-
color: #22d3ee;
225-
}
226-
227-
.cli-red {
228-
color: #f87171;
229-
}
230-
231-
.cli-bold {
232-
font-weight: 600;
233-
color: #fff;
234-
}
235-
236-
.cli-dim {
237-
color: #737373;
238-
}
239209
</style>

0 commit comments

Comments
 (0)