xminal 0.1.1 → 0.2.0
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/CHANGELOG.md +28 -0
- package/EXECUTION-PLAN.md +1 -1
- package/README.md +5 -2
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent.js +21 -1
- package/dist/core/agent.js.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime.js +7 -2
- package/dist/runtime.js.map +1 -1
- package/dist/server/http.js +26 -1
- package/dist/server/http.js.map +1 -1
- package/dist/tui/layout.js +32 -0
- package/dist/tui/layout.js.map +1 -0
- package/dist/tui/tui.js +525 -0
- package/dist/tui/tui.js.map +1 -0
- package/dist/version.js +1 -1
- package/package.json +3 -2
- package/site/index.html +561 -0
package/site/index.html
ADDED
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>XMINAL — Every coding agent. One terminal.</title>
|
|
7
|
+
<meta name="description" content="Provider-agnostic terminal coding agent & orchestration platform — 125 MIT projects fused into one hackable CLI">
|
|
8
|
+
<style>
|
|
9
|
+
:root {
|
|
10
|
+
--bg: #0b0f19;
|
|
11
|
+
--surface: #0f172a;
|
|
12
|
+
--border: #1e293b;
|
|
13
|
+
--text: #e2e8f0;
|
|
14
|
+
--muted: #94a3b8;
|
|
15
|
+
--accent-cyan: #22d3ee;
|
|
16
|
+
--accent-blue: #38bdf8;
|
|
17
|
+
--accent-violet: #a78bfa;
|
|
18
|
+
}
|
|
19
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
20
|
+
html { scroll-behavior: smooth; }
|
|
21
|
+
body {
|
|
22
|
+
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
|
23
|
+
background: var(--bg);
|
|
24
|
+
color: var(--text);
|
|
25
|
+
line-height: 1.6;
|
|
26
|
+
}
|
|
27
|
+
a { color: var(--accent-cyan); text-decoration: none; }
|
|
28
|
+
a:hover { color: var(--accent-blue); }
|
|
29
|
+
img { max-width: 100%; height: auto; }
|
|
30
|
+
/* Custom scrollbar */
|
|
31
|
+
::-webkit-scrollbar { width: 8px; height: 8px; }
|
|
32
|
+
::-webkit-scrollbar-track { background: var(--surface); }
|
|
33
|
+
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
|
|
34
|
+
::-webkit-scrollbar-thumb:hover { background: var(--muted); }
|
|
35
|
+
/* Focus visible */
|
|
36
|
+
:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 2px; }
|
|
37
|
+
/* Reduced motion */
|
|
38
|
+
@media (prefers-reduced-motion: reduce) {
|
|
39
|
+
* { transition: none !important; animation: none !important; }
|
|
40
|
+
}
|
|
41
|
+
/* ===== STICKY NAV ===== */
|
|
42
|
+
nav {
|
|
43
|
+
position: sticky;
|
|
44
|
+
top: 0;
|
|
45
|
+
background: rgba(11, 15, 25, 0.8);
|
|
46
|
+
backdrop-filter: blur(12px);
|
|
47
|
+
z-index: 100;
|
|
48
|
+
border-bottom: 1px solid var(--border);
|
|
49
|
+
}
|
|
50
|
+
.nav-container {
|
|
51
|
+
max-width: max(1200px, 100% - 2rem);
|
|
52
|
+
margin: 0 auto;
|
|
53
|
+
padding: 1rem 1.5rem;
|
|
54
|
+
display: flex;
|
|
55
|
+
justify-content: space-between;
|
|
56
|
+
align-items: center;
|
|
57
|
+
}
|
|
58
|
+
.nav-logo { font-size: 1.25rem; font-weight: 700; letter-spacing: 0.05em; }
|
|
59
|
+
.nav-links { display: flex; gap: 2rem; }
|
|
60
|
+
.nav-links a { color: var(--muted); transition: color 0.2s; }
|
|
61
|
+
.nav-links a:hover { color: var(--text); }
|
|
62
|
+
.nav-chip { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; background: var(--accent-cyan); color: var(--bg); font-weight: 600; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
63
|
+
/* ===== HERO ===== */
|
|
64
|
+
.hero { min-height: 80vh; display: flex; align-items: center; justify-content: center; position: relative; padding: 2rem 1.5rem; }
|
|
65
|
+
.hero-content { max-width: max(800px, 100% - 2rem); width: 100%; display: flex; flex-direction: column; gap: 1.5rem; }
|
|
66
|
+
.headline { font-size: clamp(3rem, 8vw, 5rem); font-weight: 900; line-height: 1.1; }
|
|
67
|
+
.headline .gradient { background: linear-gradient(135deg, var(--accent-cyan), var(--accent-blue), var(--accent-violet)); background-size: 200% 200%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; animation: gradientShift 3s ease-in-out infinite; }
|
|
68
|
+
@keyframes gradientShift { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
|
|
69
|
+
.subhead { font-size: clamp(1rem, 2vw, 1.25rem); color: var(--muted); max-width: 600px; }
|
|
70
|
+
.cta-row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
|
|
71
|
+
.cta-btn { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1.5rem; background: var(--accent-blue); color: var(--bg); font-weight: 600; border: none; border-radius: 4px; cursor: pointer; font-size: 0.9rem; transition: background 0.2s; }
|
|
72
|
+
.cta-btn:hover { background: var(--accent-violet); }
|
|
73
|
+
.cta-btn .copy-icon { width: 1em; height: 1em; }
|
|
74
|
+
/* Terminal mock */
|
|
75
|
+
.terminal-mock {
|
|
76
|
+
position: relative;
|
|
77
|
+
width: 100%;
|
|
78
|
+
max-width: 600px;
|
|
79
|
+
margin-top: 2rem;
|
|
80
|
+
background: var(--surface);
|
|
81
|
+
border: 1px solid var(--border);
|
|
82
|
+
border-radius: 8px;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
}
|
|
85
|
+
.terminal-mock .title-bar {
|
|
86
|
+
display: flex;
|
|
87
|
+
background: var(--border);
|
|
88
|
+
padding: 4px 8px;
|
|
89
|
+
}
|
|
90
|
+
.terminal-mock .title-bar .dot {
|
|
91
|
+
width: 12px; height: 12px; border-radius: 50%; margin-right: 4px;
|
|
92
|
+
flex-shrink: 0;
|
|
93
|
+
}
|
|
94
|
+
.terminal-mock .dot-accent { background: var(--accent-cyan); }
|
|
95
|
+
.terminal-mock .dot-warning { background: #f87171; }
|
|
96
|
+
.terminal-mock .dot-info { background: #fbbf24; }
|
|
97
|
+
.terminal-mock .terminal-body {
|
|
98
|
+
padding: 1rem;
|
|
99
|
+
font-family: ui-monospace, Menlo, Monaco, monospace;
|
|
100
|
+
font-size: 0.85rem;
|
|
101
|
+
color: var(--muted);
|
|
102
|
+
white-space: pre;
|
|
103
|
+
line-height: 1.6;
|
|
104
|
+
}
|
|
105
|
+
</style>
|
|
106
|
+
</head>
|
|
107
|
+
<body>
|
|
108
|
+
<!-- ===== NAV ===== -->
|
|
109
|
+
<nav>
|
|
110
|
+
<div class="nav-container">
|
|
111
|
+
<span class="nav-logo">XMINAL</span>
|
|
112
|
+
<div class="nav-links">
|
|
113
|
+
<a href="#features">Features</a>
|
|
114
|
+
<a href="#providers">Providers</a>
|
|
115
|
+
<a href="#quickstart">Quickstart</a>
|
|
116
|
+
<a href="#safety">Safety</a>
|
|
117
|
+
</div>
|
|
118
|
+
<button class="nav-chip" id="installChip">npm i -g xminal</button>
|
|
119
|
+
</div>
|
|
120
|
+
</nav>
|
|
121
|
+
|
|
122
|
+
<!-- ===== HERO ===== -->
|
|
123
|
+
<section class="hero" aria-label="hero">
|
|
124
|
+
<div class="hero-content">
|
|
125
|
+
<h1 class="headline">Every coding agent.<span class="gradient"> One terminal.</span></h1>
|
|
126
|
+
<p class="subhead">XMINAL is a provider-agnostic terminal coding agent & orchestration platform — 125 MIT projects fused into one hackable CLI. Streams, edits, verifies, remembers.</p>
|
|
127
|
+
<div class="cta-row">
|
|
128
|
+
<button class="cta-btn" id="copyBtn" aria-label="Copy npm install command">
|
|
129
|
+
npm install -g xminal
|
|
130
|
+
<svg class="copy-icon" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13"></rect><path d="M5 12h14"></path></svg>
|
|
131
|
+
</button>
|
|
132
|
+
<a class="cta-btn" href="https://github.com/quitsaurabhverma2008-sketch/xminal" target="_blank" rel="noopener" aria-label="Read the docs">Read the docs →</a>
|
|
133
|
+
</div>
|
|
134
|
+
<div class="terminal-mock" aria-label="terminal session mock">
|
|
135
|
+
<div class="title-bar">
|
|
136
|
+
<div class="dot dot-accent"></div>
|
|
137
|
+
<div class="dot dot-warning"></div>
|
|
138
|
+
<div class="dot dot-info"></div>
|
|
139
|
+
</div>
|
|
140
|
+
<div class="terminal-body" id="terminalBody">
|
|
141
|
+
XMINAL SESSION BANNER
|
|
142
|
+
xminal run "fix the failing test"
|
|
143
|
+
✓ test passed in 2.4s
|
|
144
|
+
✓ 2 turns · $0.00 cost
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</section>
|
|
149
|
+
<!-- ===== STATS BAR ===== -->
|
|
150
|
+
<section class="stats-bar" aria-label="stats">
|
|
151
|
+
<div class="stats-container" style="max-width: max(1200px, 100% - 2rem); margin: 0 auto; padding: 2rem 1.5rem; display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1rem; text-align: center;">
|
|
152
|
+
<div><div class="stat-number" id="stat-1">47</div><div class="stat-label">built-in providers</div></div>
|
|
153
|
+
<div><div class="stat-number" id="stat-2">258</div><div class="stat-model-alias">model aliases</div></div>
|
|
154
|
+
<div><div class="stat-number" id="stat-3">125</div><div class="stat-projects-mapped">projects mapped</div></div>
|
|
155
|
+
<div><div class="stat-number" id="stat-4">28</div><div class="stat-tests-passing">tests passing</div></div>
|
|
156
|
+
<div><div class="stat-number" id="stat-5">MIT</div><div class="stat-license">license</div></div>
|
|
157
|
+
</div>
|
|
158
|
+
</section>
|
|
159
|
+
|
|
160
|
+
<!-- ===== FEATURES GRID (12 CARDS) ===== -->
|
|
161
|
+
<section id="features" class="features-grid" aria-label="features">
|
|
162
|
+
<div class="container" style="max-width: max(1200px, 100% - 2rem); margin: 0 auto; padding: 2rem 1.5rem;">
|
|
163
|
+
<div class="section-header" style="text-align: center; margin-bottom: 3rem;">
|
|
164
|
+
<h2 style="font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700; margin-bottom: 1rem;">Features</h2>
|
|
165
|
+
<p style="color: var(--muted); max-width: 600px; margin: 0 auto;">Provider-agnostic terminal coding agent capabilities</p>
|
|
166
|
+
</div>
|
|
167
|
+
<div class="cards-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem;">
|
|
168
|
+
<!-- Feature card 1: Provider-agnostic -->
|
|
169
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
170
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, var(--accent-cyan), var(--accent-blue)); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
171
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
172
|
+
</div>
|
|
173
|
+
<div class="card-content" style="flex: 1;">
|
|
174
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Provider-agnostic</h3>
|
|
175
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Failover and cost routing across 47 built-in providers, automatically selecting the best model for each task.</p>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<!-- Feature card 2: Plan/Build/Compose/Review/YOLO modes -->
|
|
180
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
181
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #f97316, #ef4444); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
182
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M3 3v7h7l5-3h3L12 7l-5 3h7v7H3zm6-2c.83 0 1.5.67 1.5 1.5S6.83 6 6 6s-1.5.67-1.5-1.5S4.17 3 5 3zM7 12h2v2H7zm0-4h2v6H7zm4 8h2v2h-2zm0-4h2v6h-2z"></path></svg>
|
|
183
|
+
</div>
|
|
184
|
+
<div class="card-content" style="flex: 1;">
|
|
185
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Plan/Build/Compose/Review/YOLO modes</h3>
|
|
186
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Flexible workflow modes from structured planning to unassisted execution.</p>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
<!-- Feature card 3: Sessions -->
|
|
191
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
192
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #a855f7, #8b5cf6); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
193
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5.5l-4.5-3.5zM13 22h-2v-2h2zm2-4h-2v-6h2zm-7 0H5v-2h2zm7 0h-2V8h2zm7 4h-2V12h2z"></path></svg>
|
|
194
|
+
</div>
|
|
195
|
+
<div class="card-content" style="flex: 1;">
|
|
196
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Sessions</h3>
|
|
197
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Resume sessions, branch histories, and undo changes with full session persistence.</p>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<!-- Feature card 4: Memory -->
|
|
202
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
203
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #ec4899, #f472b6); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
204
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
|
|
205
|
+
</div>
|
|
206
|
+
<div class="card-content" style="flex: 1;">
|
|
207
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Memory</h3>
|
|
208
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Markdown storage with search — ~/.agents/skills discovery and lockfile-based lock coordination.</p>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
<!-- Feature card 5: Skills -->
|
|
213
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
214
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #f472b6, #f87171); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
215
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="card-content" style="flex: 1;">
|
|
218
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Skills</h3>
|
|
219
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">~/.agents/skills discovery + lockfile — auto-discover and coordinate agent skills.</p>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<!-- Feature card 6: MCP client -->
|
|
224
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
225
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #22d3ee, #38bdf8); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
226
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"></path></svg>
|
|
227
|
+
</div>
|
|
228
|
+
<div class="card-content" style="flex: 1;">
|
|
229
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">MCP client + XMINAL-as-MCP-server</h3>
|
|
230
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Model Context Protocol support — run XMINAL as your local MCP server.</p>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<!-- Feature card 7: Subagents & Ralph loops -->
|
|
235
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
236
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #ec4899, #f472b6); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
237
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
238
|
+
</div>
|
|
239
|
+
<div class="card-content" style="flex: 1;">
|
|
240
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Subagents & Ralph loops</h3>
|
|
241
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Autonomous subagent spawning and Ralph-style feedback loops for complex tasks.</p>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
|
|
245
|
+
<!-- Feature card 8: Worktree fleets -->
|
|
246
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
247
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #14b8a6, #0d9488); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
248
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
249
|
+
</div>
|
|
250
|
+
<div class="card-content" style="flex: 1;">
|
|
251
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Worktree fleets</h3>
|
|
252
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Parallel branch management across multiple worktrees for concurrent development.</p>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
<!-- Feature card 9: Audit receipts -->
|
|
257
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
258
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #f59e0b, #fbbf24); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
259
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
260
|
+
</div>
|
|
261
|
+
<div class="card-content" style="flex: 1;">
|
|
262
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Audit receipts</h3>
|
|
263
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Hash-chained audit logs with checkpoints and undo receipts for accountability.</p>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
<!-- Feature card 10: Web UI -->
|
|
268
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
269
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #8b5cf6, #a855f7); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
270
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
271
|
+
</div>
|
|
272
|
+
<div class="card-content" style="flex: 1;">
|
|
273
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Web UI built in</h3>
|
|
274
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Embedded web interface for visual task monitoring and control.</p>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
<!-- Feature card 11: OpenAI-compatible HTTP server (SSE) -->
|
|
279
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
280
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #06b6d4, #0891b2); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
281
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
282
|
+
</div>
|
|
283
|
+
<div class="card-content" style="flex: 1;">
|
|
284
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">OpenAI-compatible HTTP (SSE)</h3>
|
|
285
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">SSE endpoint compatible with OpenAI API specs for seamless integration.</p>
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
|
|
289
|
+
<!-- Feature card 12: Telegram bridge -->
|
|
290
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; display: flex; align-items: center; gap: 1rem;">
|
|
291
|
+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #14b8a6, #0d9488); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
292
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path></svg>
|
|
293
|
+
</div>
|
|
294
|
+
<div class="card-content" style="flex: 1;">
|
|
295
|
+
<h3 style="font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem;">Telegram bridge</h3>
|
|
296
|
+
<p style="color: var(--muted); font-size: 0.85rem; line-height: 1.5;">Telegram integration for remote task monitoring and notifications.</p>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
</section>
|
|
302
|
+
<!-- ===== QUICKSTART ===== -->
|
|
303
|
+
<section id="quickstart" class="quickstart" aria-label="quickstart">
|
|
304
|
+
<div class="container" style="max-width: max(1200px, 100% - 2rem); margin: 0 auto; padding: 2rem 1.5rem;">
|
|
305
|
+
<div class="section-header" style="text-align: center; margin-bottom: 3rem;">
|
|
306
|
+
<h2 style="font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700; margin-bottom: 1rem;">Quickstart</h2>
|
|
307
|
+
<p style="color: var(--muted); max-width: 600px; margin: 0 auto;">Get up and running in minutes</p>
|
|
308
|
+
</div>
|
|
309
|
+
<div class="tabs" role="tablist" style="display: flex; justify-content: center; margin-bottom: 2rem; gap: 1rem;">
|
|
310
|
+
<button class="tab-btn active" data-tab="macos">macOS / Linux</button>
|
|
311
|
+
<button class="tab-btn" data-tab="termux">Termux</button>
|
|
312
|
+
</div>
|
|
313
|
+
<div id="macosTab" class="tab-content active" style="display: block;">
|
|
314
|
+
<pre style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; font-family: ui-monospace, Menlo, Monaco, monospace; color: var(--text); overflow-x: auto;">
|
|
315
|
+
npm install -g xminal
|
|
316
|
+
export OPENROUTER_API_KEY=your_key_here
|
|
317
|
+
xminal doctor
|
|
318
|
+
xminal
|
|
319
|
+
</pre>
|
|
320
|
+
</div>
|
|
321
|
+
<div id="termuxTab" class="tab-content" style="display: none;">
|
|
322
|
+
<pre style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; font-family: ui-monospace, Menlo, Monaco, monospace; color: var(--text); overflow-x: auto;">
|
|
323
|
+
pkg install nodejs
|
|
324
|
+
npm install -g xminal
|
|
325
|
+
export OPENROUTER_API_KEY=your_key_here
|
|
326
|
+
xminal doctor
|
|
327
|
+
xminal
|
|
328
|
+
</pre>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
</section>
|
|
332
|
+
|
|
333
|
+
<!-- ===== PROVIDERS (real 47) ===== -->
|
|
334
|
+
<section id="providers" class="providers-section" aria-label="providers">
|
|
335
|
+
<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 3rem 1.5rem;">
|
|
336
|
+
<div style="text-align: center; margin-bottom: 2.5rem;">
|
|
337
|
+
<h2 style="font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700; margin-bottom: 0.75rem;">Providers</h2>
|
|
338
|
+
<p style="color: var(--muted); max-width: 640px; margin: 0 auto;">47 built-in providers — OpenAI-compatible, native adapters, and local servers. Default is keyless OpenCode free models.</p>
|
|
339
|
+
</div>
|
|
340
|
+
<div id="providerGrid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.75rem;"></div>
|
|
341
|
+
</div>
|
|
342
|
+
</section>
|
|
343
|
+
|
|
344
|
+
<!-- ===== SAFETY ===== -->
|
|
345
|
+
<section id="safety" aria-label="safety">
|
|
346
|
+
<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 3rem 1.5rem;">
|
|
347
|
+
<div style="text-align: center; margin-bottom: 2.5rem;">
|
|
348
|
+
<h2 style="font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700; margin-bottom: 0.75rem;">Safety is a feature</h2>
|
|
349
|
+
<p style="color: var(--muted); max-width: 640px; margin: 0 auto;">Autonomy without footguns — from first run to production CI.</p>
|
|
350
|
+
</div>
|
|
351
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.25rem;">
|
|
352
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem;">
|
|
353
|
+
<h3 style="font-size: 1rem; margin-bottom: 0.5rem;"><span style="color: var(--accent-cyan);">01</span> Permission modes</h3>
|
|
354
|
+
<p style="color: var(--muted); font-size: 0.9rem;"><code>ask</code> asks before every risky action · <code>auto</code> auto-approves low risk, asks for dangerous · <code>full</code> approves everything except protected paths.</p>
|
|
355
|
+
</div>
|
|
356
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem;">
|
|
357
|
+
<h3 style="font-size: 1rem; margin-bottom: 0.5rem;"><span style="color: var(--accent-blue);">02</span> Protected paths</h3>
|
|
358
|
+
<p style="color: var(--muted); font-size: 0.9rem;"><code>.env</code> · <code>~/.ssh</code> · <code>~/.aws</code> · <code>~/.gnupg</code> · <code>~/.config/gh</code> — denied even in full mode.</p>
|
|
359
|
+
</div>
|
|
360
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem;">
|
|
361
|
+
<h3 style="font-size: 1rem; margin-bottom: 0.5rem;"><span style="color: var(--accent-violet);">03</span> Checkpoints</h3>
|
|
362
|
+
<p style="color: var(--muted); font-size: 0.9rem;">Every edit snapshots the file first. <code>/undo</code> rewinds instantly — no git needed, no branches harmed.</p>
|
|
363
|
+
</div>
|
|
364
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem;">
|
|
365
|
+
<h3 style="font-size: 1rem; margin-bottom: 0.5rem;"><span style="color: var(--accent-cyan);">04</span> Audit receipts</h3>
|
|
366
|
+
<p style="color: var(--muted); font-size: 0.9rem;">Every allow/deny appended to a SHA-256 hash-chained log: <code>.xminal/receipts/audit.jsonl</code> · verify with <code>xminal audit verify</code>.</p>
|
|
367
|
+
</div>
|
|
368
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem;">
|
|
369
|
+
<h3 style="font-size: 1rem; margin-bottom: 0.5rem;"><span style="color: var(--accent-blue);">05</span> Secret redaction</h3>
|
|
370
|
+
<p style="color: var(--muted); font-size: 0.9rem;">Keys and tokens (<code>sk-*</code>, <code>ghp_*</code>, PEM blocks, JWTs…) are stripped from tool output before the model ever sees them.</p>
|
|
371
|
+
</div>
|
|
372
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem;">
|
|
373
|
+
<h3 style="font-size: 1rem; margin-bottom: 0.5rem;"><span style="color: var(--accent-violet);">06</span> Sandbox hooks</h3>
|
|
374
|
+
<p style="color: var(--muted); font-size: 0.9rem;">Optional <code>bwrap</code>/Docker sandbox for shell commands, plus a never-prompt safe list for read-only tools — all logged.</p>
|
|
375
|
+
</div>
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
</section>
|
|
379
|
+
|
|
380
|
+
<!-- ===== COMPARISON ===== -->
|
|
381
|
+
<section id="compare" aria-label="comparison">
|
|
382
|
+
<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 3rem 1.5rem;">
|
|
383
|
+
<div style="text-align: center; margin-bottom: 2.5rem;">
|
|
384
|
+
<h2 style="font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700; margin-bottom: 0.75rem;">XMINAL vs the rest</h2>
|
|
385
|
+
<p style="color: var(--muted); max-width: 640px; margin: 0 auto;">Honest checkmarks, not vibes.</p>
|
|
386
|
+
</div>
|
|
387
|
+
<div style="overflow-x: auto;">
|
|
388
|
+
<table style="width: 100%; border-collapse: collapse; font-size: 0.9rem; min-width: 720px;">
|
|
389
|
+
<thead>
|
|
390
|
+
<tr>
|
|
391
|
+
<th style="text-align: left; padding: 0.75rem; border-bottom: 2px solid var(--border); color: var(--muted); font-weight: 600;">Capability</th>
|
|
392
|
+
<th style="padding: 0.75rem; border-bottom: 2px solid var(--border); color: var(--accent-cyan);">XMINAL</th>
|
|
393
|
+
<th style="padding: 0.75rem; border-bottom: 2px solid var(--border); color: var(--muted);">Aider</th>
|
|
394
|
+
<th style="padding: 0.75rem; border-bottom: 2px solid var(--border); color: var(--muted);">Codex CLI</th>
|
|
395
|
+
<th style="padding: 0.75rem; border-bottom: 2px solid var(--border); color: var(--muted);">OpenCode</th>
|
|
396
|
+
<th style="padding: 0.75rem; border-bottom: 2px solid var(--border); color: var(--muted);">Gemini CLI</th>
|
|
397
|
+
</tr>
|
|
398
|
+
</thead>
|
|
399
|
+
<tbody id="compareBody"></tbody>
|
|
400
|
+
</table>
|
|
401
|
+
</div>
|
|
402
|
+
</div>
|
|
403
|
+
</section>
|
|
404
|
+
|
|
405
|
+
<!-- ===== ROADMAP ===== -->
|
|
406
|
+
<section id="roadmap" aria-label="roadmap">
|
|
407
|
+
<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 3rem 1.5rem;">
|
|
408
|
+
<div style="text-align: center; margin-bottom: 2.5rem;">
|
|
409
|
+
<h2 style="font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700; margin-bottom: 0.75rem;">Roadmap</h2>
|
|
410
|
+
<p style="color: var(--muted); max-width: 640px; margin: 0 auto;">From v0.1 to v1.0 — the 18-phase plan.</p>
|
|
411
|
+
</div>
|
|
412
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.25rem;">
|
|
413
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--accent-cyan); border-radius: 8px; padding: 1.5rem;">
|
|
414
|
+
<p style="font-size: 0.75rem; letter-spacing: 0.1em; color: var(--accent-cyan); margin-bottom: 0.5rem;">SHIPPED · v0.1.1</p>
|
|
415
|
+
<ul style="color: var(--muted); font-size: 0.9rem; padding-left: 1.1rem; line-height: 1.8;">
|
|
416
|
+
<li>Agent runtime: streaming, tools, modes</li>
|
|
417
|
+
<li>47 providers · 258 model aliases</li>
|
|
418
|
+
<li>Sessions, checkpoints, undo</li>
|
|
419
|
+
<li>Ralph verify loops · subagents · worktrees</li>
|
|
420
|
+
<li>MCP client <em>and</em> XMINAL-as-MCP-server</li>
|
|
421
|
+
<li>Web UI at <code>/</code> · HTTP/SSE API · Telegram</li>
|
|
422
|
+
</ul>
|
|
423
|
+
</div>
|
|
424
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--accent-blue); border-radius: 8px; padding: 1.5rem;">
|
|
425
|
+
<p style="font-size: 0.75rem; letter-spacing: 0.1em; color: var(--accent-blue); margin-bottom: 0.5rem;">NEXT · v0.2</p>
|
|
426
|
+
<ul style="color: var(--muted); font-size: 0.9rem; padding-left: 1.1rem; line-height: 1.8;">
|
|
427
|
+
<li>LSP diagnostics wiring</li>
|
|
428
|
+
<li>Ink-class streaming TUI</li>
|
|
429
|
+
<li>ACP (Agent Client Protocol)</li>
|
|
430
|
+
<li>Skills marketplace + <code>xminal skills install</code></li>
|
|
431
|
+
<li>Per-model router: quota/cost-aware</li>
|
|
432
|
+
</ul>
|
|
433
|
+
</div>
|
|
434
|
+
<div class="card" style="background: var(--surface); border: 1px solid var(--accent-violet); border-radius: 8px; padding: 1.5rem;">
|
|
435
|
+
<p style="font-size: 0.75rem; letter-spacing: 0.1em; color: var(--accent-violet); margin-bottom: 0.5rem;">VISION · v1.0</p>
|
|
436
|
+
<ul style="color: var(--muted); font-size: 0.9rem; padding-left: 1.1rem; line-height: 1.8;">
|
|
437
|
+
<li>Parallel worktree fleets with merge arbitrage</li>
|
|
438
|
+
<li>Background agents + cron/interval runs</li>
|
|
439
|
+
<li>Sandboxed cloud execution tiers</li>
|
|
440
|
+
<li>Cost-optimal planner/executor split</li>
|
|
441
|
+
</ul>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
</section>
|
|
446
|
+
|
|
447
|
+
<!-- ===== FAQ ===== -->
|
|
448
|
+
<section id="faq" aria-label="faq">
|
|
449
|
+
<div class="container" style="max-width: 900px; margin: 0 auto; padding: 3rem 1.5rem;">
|
|
450
|
+
<div style="text-align: center; margin-bottom: 2.5rem;">
|
|
451
|
+
<h2 style="font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700;">FAQ</h2>
|
|
452
|
+
</div>
|
|
453
|
+
<div id="faqList"></div>
|
|
454
|
+
</div>
|
|
455
|
+
</section>
|
|
456
|
+
|
|
457
|
+
<!-- ===== FINAL CTA ===== -->
|
|
458
|
+
<section id="cta" aria-label="call to action" style="text-align: center; padding: 4rem 1.5rem; border-top: 1px solid var(--border);">
|
|
459
|
+
<h2 style="font-size: clamp(2rem, 5vw, 3rem); font-weight: 800; margin-bottom: 1rem;">Ship faster.<br><span style="background: linear-gradient(135deg, var(--accent-cyan), var(--accent-blue), var(--accent-violet)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">Own your agent.</span></h2>
|
|
460
|
+
<p style="color: var(--muted); margin-bottom: 1.5rem;">MIT. Local-first. No telemetry. Yours.</p>
|
|
461
|
+
<div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
|
|
462
|
+
<button class="cta-btn" id="copyBtn2" style="font-size: 1rem; padding: 0.9rem 1.75rem;">npm install -g xminal
|
|
463
|
+
<svg class="copy-icon" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13"></rect><path d="M5 12h14"></path></svg>
|
|
464
|
+
</button>
|
|
465
|
+
<a class="cta-btn" href="https://github.com/quitsaurabhverma2008-sketch/xminal" target="_blank" rel="noopener" style="background: var(--surface); border: 1px solid var(--border); color: var(--text);">View on GitHub →</a>
|
|
466
|
+
</div>
|
|
467
|
+
</section>
|
|
468
|
+
|
|
469
|
+
<!-- ===== FOOTER ===== -->
|
|
470
|
+
<footer style="border-top: 1px solid var(--border); padding: 2rem 1.5rem; text-align: center; color: var(--muted); font-size: 0.85rem;">
|
|
471
|
+
<p style="font-weight: 700; letter-spacing: 0.15em; color: var(--text); margin-bottom: 0.5rem;">XMINAL</p>
|
|
472
|
+
<p>MIT License · <a href="https://github.com/quitsaurabhverma2008-sketch/xminal">GitHub</a> · <a href="https://www.npmjs.com/package/xminal">npm</a></p>
|
|
473
|
+
<p style="margin-top: 0.5rem; font-size: 0.75rem;">Built from 125 MIT terminal-agent projects — see <code>FEATURE_MATRIX.md</code></p>
|
|
474
|
+
</footer>
|
|
475
|
+
|
|
476
|
+
<script>
|
|
477
|
+
const providers = [
|
|
478
|
+
["opencode","keyless default"],["openai","cloud"],["anthropic","native"],["gemini","native"],
|
|
479
|
+
["openrouter","cloud"],["groq","cloud"],["deepseek","cloud"],["mistral","cloud"],["xai","cloud"],
|
|
480
|
+
["cerebras","cloud"],["cohere","cloud"],["togetherai","cloud"],["fireworks","cloud"],["perplexity","cloud"],
|
|
481
|
+
["moonshotai","cloud"],["moonshotai_cn","cloud"],["huggingface","cloud"],["github","GitHub Models"],
|
|
482
|
+
["nvidia","cloud"],["deepinfra","cloud"],["sambanova","cloud"],["novita","cloud"],["friendli","cloud"],
|
|
483
|
+
["nebius","cloud"],["poe","cloud"],["ollama_cloud","cloud"],["zai","cloud"],["zhipuai","cloud"],
|
|
484
|
+
["minimax","cloud"],["stepfun","cloud"],["stepfun_cn","cloud"],["siliconflow","cloud"],["volcengine","cloud"],
|
|
485
|
+
["302ai","cloud"],["venice","cloud"],["vercel","cloud"],["alibaba","cloud"],["ollama","local"],
|
|
486
|
+
["ollama_cn","local"],["lmstudio","local"],["vllm","local"],["llama_cpp","local"],["koboldcpp","local"],
|
|
487
|
+
["textgen","local"],["gpt4all","local"],["openwebui","local"],
|
|
488
|
+
];
|
|
489
|
+
const grid = document.getElementById('providerGrid');
|
|
490
|
+
for (const [name, kind] of providers) {
|
|
491
|
+
const el = document.createElement('div');
|
|
492
|
+
el.style.cssText = 'background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 0.6rem 0.7rem; text-align: center; font-size: 0.8rem;';
|
|
493
|
+
el.innerHTML = `<div style="color: var(--text); font-weight: 600;">${name}</div><div style="color: var(--muted); font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.08em; margin-top: 0.15rem;">${kind}</div>`;
|
|
494
|
+
grid.appendChild(el);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
const compareRows = [
|
|
498
|
+
["Providers (built-in)","47","~10","~20","many via plugins","few"],
|
|
499
|
+
["Open-source (MIT)","✓","✓","—","✓","✓"],
|
|
500
|
+
["MCP client + server","✓","—","—","✓","—"],
|
|
501
|
+
["Subagents / worktrees","✓","—","—","✓","—"],
|
|
502
|
+
["Local models (Ollama)","✓","✓","—","✓","—"],
|
|
503
|
+
["Web UI built-in","✓","—","—","✓","—"],
|
|
504
|
+
["Telegram bridge","✓","—","—","—","—"],
|
|
505
|
+
["Hash-chained audit log","✓","—","—","—","—"],
|
|
506
|
+
["Cost / token tracking","✓","✓","✓","✓","✓"],
|
|
507
|
+
];
|
|
508
|
+
const tbody = document.getElementById('compareBody');
|
|
509
|
+
for (const [cap, ...cells] of compareRows) {
|
|
510
|
+
const tr = document.createElement('tr');
|
|
511
|
+
tr.innerHTML = `<td style="padding: 0.75rem; border-bottom: 1px solid var(--border);">${cap}</td>` +
|
|
512
|
+
cells.map((c, i) => `<td style="padding: 0.75rem; text-align: center; border-bottom: 1px solid var(--border); color: ${i===0 ? 'var(--accent-cyan)' : 'var(--muted)'};">${c}</td>`).join('');
|
|
513
|
+
tbody.appendChild(tr);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const faqs = [
|
|
517
|
+
["Which models can I use?", "Any of 258 aliased models across OpenCode (keyless default), OpenAI, Anthropic, Gemini, OpenRouter, Groq, DeepSeek, Mistral, xAI, Cerebras, Cohere, Together, Fireworks, Moonshot and more. Local Ollama/LM Studio/vLLM included."],
|
|
518
|
+
["Is it free?", "Yes — MIT, zero telemetry, zero SaaS lock-in. The default OpenCode free models cost nothing. Bring your own keys for everything else."],
|
|
519
|
+
["Does it phone home?", "No. No analytics, no telemetry, no accounts. Your code stays on your machine; the only network calls are to the model providers you configure."],
|
|
520
|
+
["Can I use a local model?", "Yes — install Ollama, run `ollama pull qwen3:0.6b`, then `xminal -m ollama/qwen3:0.6b`. It's fully offline and unlimited."],
|
|
521
|
+
];
|
|
522
|
+
const faqList = document.getElementById('faqList');
|
|
523
|
+
for (const [q, a] of faqs) {
|
|
524
|
+
const details = document.createElement('details');
|
|
525
|
+
details.style.cssText = 'border: 1px solid var(--border); border-radius: 8px; padding: 1rem 1.25rem; margin-bottom: 0.75rem; background: var(--surface);';
|
|
526
|
+
details.innerHTML = `<summary style="cursor: pointer; font-weight: 600;">${q}</summary><p style="color: var(--muted); margin-top: 0.75rem; font-size: 0.9rem;">${a}</p>`;
|
|
527
|
+
faqList.appendChild(details);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function wireCopy(id, text) {
|
|
531
|
+
const btn = document.getElementById(id);
|
|
532
|
+
if (!btn) return;
|
|
533
|
+
btn.addEventListener('click', async () => {
|
|
534
|
+
try { await navigator.clipboard.writeText(text); } catch {}
|
|
535
|
+
const original = btn.firstChild.textContent;
|
|
536
|
+
btn.firstChild.textContent = 'Copied ✓';
|
|
537
|
+
setTimeout(() => { btn.firstChild.textContent = original; }, 1500);
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
wireCopy('copyBtn', 'npm install -g xminal');
|
|
541
|
+
wireCopy('copyBtn2', 'npm install -g xminal');
|
|
542
|
+
wireCopy('installChip', 'npm install -g xminal');
|
|
543
|
+
|
|
544
|
+
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
545
|
+
btn.addEventListener('click', () => {
|
|
546
|
+
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
|
547
|
+
document.querySelectorAll('.tab-content').forEach(c => { c.style.display = 'none'; });
|
|
548
|
+
btn.classList.add('active');
|
|
549
|
+
const target = document.getElementById(btn.dataset.tab === 'macos' ? 'macosTab' : 'termuxTab');
|
|
550
|
+
if (target) target.style.display = 'block';
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
const reveal = document.querySelectorAll('section');
|
|
555
|
+
const io = new IntersectionObserver(entries => {
|
|
556
|
+
for (const e of entries) if (e.isIntersecting) e.target.style.opacity = '1';
|
|
557
|
+
}, { threshold: 0.05 });
|
|
558
|
+
reveal.forEach(s => { s.style.transition = 'opacity 0.6s'; if (getComputedStyle(s).opacity === '1') return; s.style.opacity = '0.35'; io.observe(s); });
|
|
559
|
+
</script>
|
|
560
|
+
</body>
|
|
561
|
+
</html>
|