shmakk 1.1.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/.env.example +23 -0
- package/LICENSE +21 -0
- package/README.md +138 -0
- package/bin/shmakk.js +2 -0
- package/docs/index.html +581 -0
- package/docs/voice.md +181 -0
- package/package.json +58 -0
- package/scripts/patch-onnxruntime.js +82 -0
- package/src/agent.js +0 -0
- package/src/audit.js +18 -0
- package/src/cli.js +177 -0
- package/src/completions.js +167 -0
- package/src/control.js +250 -0
- package/src/correction.js +159 -0
- package/src/endpoints.js +52 -0
- package/src/global-doctor.js +33 -0
- package/src/global-setup.js +62 -0
- package/src/glossary.js +235 -0
- package/src/history-parser.js +166 -0
- package/src/hooks/bash.js +43 -0
- package/src/hooks/fish.js +25 -0
- package/src/hooks/index.js +14 -0
- package/src/hooks/zsh.js +42 -0
- package/src/index.js +166 -0
- package/src/llm.js +45 -0
- package/src/markers.js +113 -0
- package/src/orchestrator.js +61 -0
- package/src/profiles.js +19 -0
- package/src/prompt-cache.js +83 -0
- package/src/pty.js +107 -0
- package/src/review.js +75 -0
- package/src/safety.js +77 -0
- package/src/services/stt.js +131 -0
- package/src/services/tts.js +307 -0
- package/src/services/voice.js +362 -0
- package/src/session.js +604 -0
- package/src/setup-voice.js +108 -0
- package/src/shell.js +32 -0
- package/src/skills.js +309 -0
- package/src/subagent.js +42 -0
- package/src/system-prompt.js +261 -0
- package/src/tools.js +386 -0
- package/src/web.js +228 -0
- package/src/workspace-index.js +213 -0
package/docs/index.html
ADDED
|
@@ -0,0 +1,581 @@
|
|
|
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>shmakk demo</title>
|
|
7
|
+
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Righteous&display=swap" rel="stylesheet">
|
|
8
|
+
<style>
|
|
9
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
10
|
+
|
|
11
|
+
body {
|
|
12
|
+
background: #1a1b1e;
|
|
13
|
+
font-family: 'JetBrains Mono', 'Fira Mono', monospace;
|
|
14
|
+
color: #d4d4d4;
|
|
15
|
+
min-height: 100vh;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
align-items: center;
|
|
19
|
+
padding: 40px 16px 60px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.hero {
|
|
23
|
+
text-align: center;
|
|
24
|
+
margin-bottom: 36px;
|
|
25
|
+
max-width: 700px;
|
|
26
|
+
}
|
|
27
|
+
.hero h1 {
|
|
28
|
+
font-family: 'Righteous', sans-serif;
|
|
29
|
+
font-size: clamp(42px, 7vw, 72px);
|
|
30
|
+
font-weight: 400;
|
|
31
|
+
letter-spacing: 0.02em;
|
|
32
|
+
line-height: 1;
|
|
33
|
+
margin-bottom: 10px;
|
|
34
|
+
background: linear-gradient(135deg, #4af073 0%, #4da6ff 100%);
|
|
35
|
+
-webkit-background-clip: text;
|
|
36
|
+
-webkit-text-fill-color: transparent;
|
|
37
|
+
background-clip: text;
|
|
38
|
+
}
|
|
39
|
+
.hero h1 em { font-style: normal; }
|
|
40
|
+
.hero .sub {
|
|
41
|
+
font-size: 13px;
|
|
42
|
+
color: #555;
|
|
43
|
+
margin-bottom: 6px;
|
|
44
|
+
line-height: 1.7;
|
|
45
|
+
}
|
|
46
|
+
.hero .honest {
|
|
47
|
+
font-size: 11px;
|
|
48
|
+
color: #3a3a3a;
|
|
49
|
+
margin-bottom: 20px;
|
|
50
|
+
font-style: italic;
|
|
51
|
+
}
|
|
52
|
+
.install {
|
|
53
|
+
display: inline-block;
|
|
54
|
+
background: #111;
|
|
55
|
+
border: 1px solid #2a2a2a;
|
|
56
|
+
border-radius: 4px;
|
|
57
|
+
padding: 8px 18px;
|
|
58
|
+
font-size: 13px;
|
|
59
|
+
color: #4af073;
|
|
60
|
+
margin-bottom: 28px;
|
|
61
|
+
}
|
|
62
|
+
.install span { color: #555; }
|
|
63
|
+
|
|
64
|
+
/* tabs */
|
|
65
|
+
.tabs {
|
|
66
|
+
display: flex;
|
|
67
|
+
border-bottom: 1px solid #2a2d35;
|
|
68
|
+
width: 100%;
|
|
69
|
+
max-width: 820px;
|
|
70
|
+
overflow-x: auto;
|
|
71
|
+
scrollbar-width: none;
|
|
72
|
+
}
|
|
73
|
+
.tabs::-webkit-scrollbar { display: none; }
|
|
74
|
+
.tab {
|
|
75
|
+
background: none; border: none;
|
|
76
|
+
font-family: 'JetBrains Mono', monospace;
|
|
77
|
+
font-size: 11px; color: #555;
|
|
78
|
+
padding: 9px 18px; cursor: pointer;
|
|
79
|
+
border-bottom: 2px solid transparent;
|
|
80
|
+
margin-bottom: -1px;
|
|
81
|
+
white-space: nowrap; letter-spacing: 0.04em;
|
|
82
|
+
transition: color .2s;
|
|
83
|
+
}
|
|
84
|
+
.tab:hover { color: #aaa; }
|
|
85
|
+
.tab.active { color: #4af073; border-bottom-color: #4af073; }
|
|
86
|
+
.tab.voice-tab { position: relative; }
|
|
87
|
+
.tab.voice-tab::after {
|
|
88
|
+
content: '';
|
|
89
|
+
position: absolute;
|
|
90
|
+
top: 8px; right: 6px;
|
|
91
|
+
width: 5px; height: 5px;
|
|
92
|
+
border-radius: 50%;
|
|
93
|
+
background: #4af073;
|
|
94
|
+
animation: pulse-dot 2s ease-in-out infinite;
|
|
95
|
+
}
|
|
96
|
+
@keyframes pulse-dot {
|
|
97
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
98
|
+
50% { opacity: 0.4; transform: scale(0.6); }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* window */
|
|
102
|
+
.window {
|
|
103
|
+
width: 100%; max-width: 820px;
|
|
104
|
+
background: #0f1117;
|
|
105
|
+
border: 1px solid #2a2d35;
|
|
106
|
+
border-top: none;
|
|
107
|
+
border-radius: 0 0 6px 6px;
|
|
108
|
+
overflow: hidden;
|
|
109
|
+
}
|
|
110
|
+
.titlebar {
|
|
111
|
+
background: #181b22;
|
|
112
|
+
padding: 7px 14px;
|
|
113
|
+
display: flex; align-items: center; gap: 7px;
|
|
114
|
+
border-bottom: 1px solid #2a2d35;
|
|
115
|
+
}
|
|
116
|
+
.dot { width: 11px; height: 11px; border-radius: 50%; }
|
|
117
|
+
.dot-r { background: #ff5f57; }
|
|
118
|
+
.dot-y { background: #febc2e; }
|
|
119
|
+
.dot-g { background: #28c840; }
|
|
120
|
+
.win-title { margin-left: 8px; font-size: 11px; color: #444; }
|
|
121
|
+
|
|
122
|
+
.term {
|
|
123
|
+
padding: 14px 18px 32px;
|
|
124
|
+
font-size: 13px; line-height: 1.65;
|
|
125
|
+
min-height: 340px; position: relative;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.panel { display: none; }
|
|
129
|
+
.panel.active { display: block; }
|
|
130
|
+
|
|
131
|
+
/* terminal colors */
|
|
132
|
+
.hostname { color: #4af073; }
|
|
133
|
+
.path { color: #5c9cf5; }
|
|
134
|
+
.exitcode { color: #ff6b6b; }
|
|
135
|
+
.muted { color: #555; }
|
|
136
|
+
.white { color: #fff; }
|
|
137
|
+
.user-input { color: #4af073; }
|
|
138
|
+
.cmd-first { color: #e0e0e0; }
|
|
139
|
+
.task-label { color: #888; }
|
|
140
|
+
.thinking { color: #888; }
|
|
141
|
+
.ai-out { color: #d4d4d4; }
|
|
142
|
+
.tool-arrow { color: #4af073; }
|
|
143
|
+
.tool-name { color: #d4d4d4; }
|
|
144
|
+
.tool-result { color: #888; }
|
|
145
|
+
.shmakk-section { color: #4af073; }
|
|
146
|
+
.tool-key { color: #d4d4d4; }
|
|
147
|
+
.warn-val { color: #ffb830; }
|
|
148
|
+
.confirm { color: #d4d4d4; }
|
|
149
|
+
.corr-old { color: #ff6b6b; text-decoration: line-through; }
|
|
150
|
+
.corr-arrow { color: #888; }
|
|
151
|
+
.corr-new { color: #4af073; }
|
|
152
|
+
.code { color: #4af073; }
|
|
153
|
+
.dim2 { color: #3d3d3d; }
|
|
154
|
+
.voice-mic { color: #4af073; }
|
|
155
|
+
.voice-txt { color: #4da6ff; }
|
|
156
|
+
.voice-resp { color: #d4d4d4; }
|
|
157
|
+
.voice-name { color: #ffb830; }
|
|
158
|
+
|
|
159
|
+
.ln { opacity: 0; transition: opacity 0.12s; }
|
|
160
|
+
.ln.show { opacity: 1; }
|
|
161
|
+
|
|
162
|
+
.cur {
|
|
163
|
+
display: inline-block; width: 8px; height: 14px;
|
|
164
|
+
background: #d4d4d4; vertical-align: text-bottom;
|
|
165
|
+
animation: blink 1.1s step-end infinite; margin-left: 1px;
|
|
166
|
+
}
|
|
167
|
+
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }
|
|
168
|
+
|
|
169
|
+
.replay {
|
|
170
|
+
position: absolute; bottom: 12px; right: 14px;
|
|
171
|
+
background: none; border: 1px solid #2a2d35;
|
|
172
|
+
color: #444; font-family: 'JetBrains Mono', monospace;
|
|
173
|
+
font-size: 11px; padding: 5px 12px; border-radius: 3px;
|
|
174
|
+
cursor: pointer; transition: color .2s, border-color .2s;
|
|
175
|
+
}
|
|
176
|
+
.replay:hover { color: #4af073; border-color: #4af073; }
|
|
177
|
+
|
|
178
|
+
/* voice panel specific */
|
|
179
|
+
.voice-schedule {
|
|
180
|
+
margin-top: 20px;
|
|
181
|
+
border-top: 1px solid #1e2330;
|
|
182
|
+
padding-top: 16px;
|
|
183
|
+
}
|
|
184
|
+
.voice-schedule-title {
|
|
185
|
+
font-size: 10px;
|
|
186
|
+
color: #333;
|
|
187
|
+
letter-spacing: 0.1em;
|
|
188
|
+
text-transform: uppercase;
|
|
189
|
+
margin-bottom: 10px;
|
|
190
|
+
}
|
|
191
|
+
.voice-slots {
|
|
192
|
+
display: flex;
|
|
193
|
+
gap: 6px;
|
|
194
|
+
flex-wrap: wrap;
|
|
195
|
+
}
|
|
196
|
+
.voice-slot {
|
|
197
|
+
font-size: 10px;
|
|
198
|
+
padding: 3px 8px;
|
|
199
|
+
border-radius: 3px;
|
|
200
|
+
border: 1px solid #1e2330;
|
|
201
|
+
color: #444;
|
|
202
|
+
white-space: nowrap;
|
|
203
|
+
}
|
|
204
|
+
.voice-slot.current {
|
|
205
|
+
border-color: #4af073;
|
|
206
|
+
color: #4af073;
|
|
207
|
+
background: rgba(74, 240, 115, 0.05);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* mic animation */
|
|
211
|
+
.mic-anim {
|
|
212
|
+
display: inline-block;
|
|
213
|
+
position: relative;
|
|
214
|
+
margin-right: 4px;
|
|
215
|
+
}
|
|
216
|
+
.mic-ring {
|
|
217
|
+
display: inline-block;
|
|
218
|
+
width: 8px; height: 8px;
|
|
219
|
+
border-radius: 50%;
|
|
220
|
+
background: #4af073;
|
|
221
|
+
animation: mic-pulse 1.5s ease-in-out infinite;
|
|
222
|
+
}
|
|
223
|
+
@keyframes mic-pulse {
|
|
224
|
+
0%, 100% { transform: scale(1); opacity: 1; box-shadow: 0 0 0 0 rgba(74,240,115,0.4); }
|
|
225
|
+
50% { transform: scale(1.1); opacity: 0.8; box-shadow: 0 0 0 4px rgba(74,240,115,0); }
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* feature grid */
|
|
229
|
+
.section-label {
|
|
230
|
+
width: 100%; max-width: 820px;
|
|
231
|
+
font-size: 10px; letter-spacing: 0.12em;
|
|
232
|
+
text-transform: uppercase; color: #333;
|
|
233
|
+
margin: 36px 0 12px;
|
|
234
|
+
}
|
|
235
|
+
.features {
|
|
236
|
+
max-width: 820px; width: 100%;
|
|
237
|
+
display: grid;
|
|
238
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
239
|
+
gap: 1px;
|
|
240
|
+
background: #1e2330;
|
|
241
|
+
border: 1px solid #1e2330;
|
|
242
|
+
border-radius: 6px;
|
|
243
|
+
overflow: hidden;
|
|
244
|
+
}
|
|
245
|
+
.feat {
|
|
246
|
+
background: #0f1117;
|
|
247
|
+
padding: 18px 16px;
|
|
248
|
+
}
|
|
249
|
+
.feat h3 { font-size: 12px; color: #fff; margin-bottom: 6px; }
|
|
250
|
+
.feat p { font-size: 11px; color: #555; line-height: 1.7; }
|
|
251
|
+
.feat code {
|
|
252
|
+
color: #4af073; font-family: 'JetBrains Mono', monospace;
|
|
253
|
+
font-size: 11px;
|
|
254
|
+
}
|
|
255
|
+
.feat.voice-feat {
|
|
256
|
+
background: #0d1210;
|
|
257
|
+
border-left: 2px solid #4af073;
|
|
258
|
+
}
|
|
259
|
+
.feat.voice-feat h3 { color: #4af073; }
|
|
260
|
+
|
|
261
|
+
/* cta */
|
|
262
|
+
.cta { margin-top: 36px; text-align: center; }
|
|
263
|
+
.cta a {
|
|
264
|
+
display: inline-block;
|
|
265
|
+
background: #4af073; color: #000;
|
|
266
|
+
font-family: 'JetBrains Mono', monospace;
|
|
267
|
+
font-size: 13px; font-weight: 700;
|
|
268
|
+
padding: 11px 26px; border-radius: 4px;
|
|
269
|
+
text-decoration: none; margin: 0 6px;
|
|
270
|
+
transition: opacity .2s;
|
|
271
|
+
}
|
|
272
|
+
.cta a:hover { opacity: 0.88; }
|
|
273
|
+
.cta a.ghost {
|
|
274
|
+
background: none; border: 1px solid #2a2d35; color: #888;
|
|
275
|
+
}
|
|
276
|
+
.cta a.ghost:hover { color: #4af073; border-color: #4af073; }
|
|
277
|
+
.cta-note { font-size: 11px; color: #333; margin-top: 14px; }
|
|
278
|
+
</style>
|
|
279
|
+
</head>
|
|
280
|
+
<body>
|
|
281
|
+
|
|
282
|
+
<div class="hero">
|
|
283
|
+
<h1>shm<em>akk</em></h1>
|
|
284
|
+
<p class="sub">AI-supervised terminal. No GUI. No bloat. Just your shell, smarter.<br>Optionally: talks back.</p>
|
|
285
|
+
<p class="honest">takes advantage of errors so you don't have to think about them</p>
|
|
286
|
+
<div class="install">npm install -g <span>git+https://github.com/marbad1994/shmakk.git</span></div>
|
|
287
|
+
</div>
|
|
288
|
+
|
|
289
|
+
<div class="tabs">
|
|
290
|
+
<button class="tab active" onclick="go('chat')">chat</button>
|
|
291
|
+
<button class="tab" onclick="go('project')">project builder</button>
|
|
292
|
+
<button class="tab" onclick="go('typo')">typo correction</button>
|
|
293
|
+
<button class="tab" onclick="go('skills')">skills</button>
|
|
294
|
+
<button class="tab" onclick="go('profiles')">profiles</button>
|
|
295
|
+
<button class="tab voice-tab" onclick="go('voice')">voice</button>
|
|
296
|
+
</div>
|
|
297
|
+
|
|
298
|
+
<div class="window">
|
|
299
|
+
<div class="titlebar">
|
|
300
|
+
<div class="dot dot-r"></div><div class="dot dot-y"></div><div class="dot dot-g"></div>
|
|
301
|
+
<span class="win-title" id="win-title">shmakk : MainThread</span>
|
|
302
|
+
</div>
|
|
303
|
+
<div class="term">
|
|
304
|
+
|
|
305
|
+
<!-- CHAT -->
|
|
306
|
+
<div class="panel active" id="panel-chat">
|
|
307
|
+
<div class="ln" data-d="0"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="white">shmakk</span></div>
|
|
308
|
+
<div class="ln" data-d="300"><span class="muted">session started. type commands or questions naturally.</span></div>
|
|
309
|
+
<div class="ln" data-d="500"> </div>
|
|
310
|
+
<div class="ln" data-d="600"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">Hey</span> can we chat?</span></div>
|
|
311
|
+
<div class="ln" data-d="900"><span class="task-label">[shmakk task] (Ctrl-C to interrupt)</span></div>
|
|
312
|
+
<div class="ln" data-d="1200"><span class="thinking">โฅ thinking...</span></div>
|
|
313
|
+
<div class="ln" data-d="2000"><span class="ai-out">Sure, we can chat! What's on your mind? Need help with</span></div>
|
|
314
|
+
<div class="ln" data-d="2100"><span class="ai-out">something in your project, or just want to bounce around some ideas?</span></div>
|
|
315
|
+
<div class="ln" data-d="2500"> </div>
|
|
316
|
+
<div class="ln" data-d="2600"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">whats</span> the fastest way to reverse a string in python</span></div>
|
|
317
|
+
<div class="ln" data-d="2900"><span class="task-label">[shmakk task] (Ctrl-C to interrupt)</span></div>
|
|
318
|
+
<div class="ln" data-d="3200"><span class="thinking">โฅ thinking...</span></div>
|
|
319
|
+
<div class="ln" data-d="3900"><span class="ai-out">Slice with step -1:</span></div>
|
|
320
|
+
<div class="ln" data-d="4000"> </div>
|
|
321
|
+
<div class="ln" data-d="4100"><span class="code"> s[::-1]</span></div>
|
|
322
|
+
<div class="ln" data-d="4200"> </div>
|
|
323
|
+
<div class="ln" data-d="4300"><span class="ai-out">Fastest and most Pythonic. Works on any sequence.</span></div>
|
|
324
|
+
<div class="ln" data-d="4600"> </div>
|
|
325
|
+
<div class="ln" data-d="4700"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="cur"></span></div>
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
<!-- PROJECT -->
|
|
329
|
+
<div class="panel" id="panel-project">
|
|
330
|
+
<div class="ln" data-d="0"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted"> (main)></span> <span class="user-input"><span class="cmd-first">set</span> up a react and flask project with a login page using oauth, follow best practice and set it up with docker compose and add redis and mongodb</span></div>
|
|
331
|
+
<div class="ln" data-d="400"><span class="task-label">[shmakk task] (Ctrl-C to interrupt)</span></div>
|
|
332
|
+
<div class="ln" data-d="700"><span class="thinking">โฅ thinking...</span></div>
|
|
333
|
+
<div class="ln" data-d="1400"> </div>
|
|
334
|
+
<div class="ln" data-d="1500"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span> <span class="exitcode">[127]</span><span class="muted">></span></div>
|
|
335
|
+
<div class="ln" data-d="1700"><span class="tool-arrow">โ</span> <span class="tool-name">list_dir(.)</span></div>
|
|
336
|
+
<div class="ln" data-d="1900"><span class="tool-result"> 1 entries</span></div>
|
|
337
|
+
<div class="ln" data-d="2100"><span class="tool-arrow">โ</span> <span class="tool-name">make_dir(backend)</span> <span class="tool-result">โ created</span></div>
|
|
338
|
+
<div class="ln" data-d="2300"><span class="tool-arrow">โ</span> <span class="tool-name">make_dir(frontend/src/components)</span> <span class="tool-result">โ created</span></div>
|
|
339
|
+
<div class="ln" data-d="2500"><span class="tool-arrow">โ</span> <span class="tool-name">make_dir(nginx)</span> <span class="tool-result">โ created</span></div>
|
|
340
|
+
<div class="ln" data-d="2700"><span class="tool-arrow">โ</span> <span class="tool-name">write_file(backend/requirements.txt)</span> <span class="tool-result">โ written</span></div>
|
|
341
|
+
<div class="ln" data-d="2900"><span class="tool-arrow">โ</span> <span class="tool-name">write_file(backend/app.py)</span> <span class="tool-result">โ written</span></div>
|
|
342
|
+
<div class="ln" data-d="3100"><span class="muted"> ยท read 3 files</span></div>
|
|
343
|
+
<div class="ln" data-d="3300"><span class="tool-arrow">โ</span> <span class="tool-name">write_file(docker-compose.yml)</span> <span class="tool-result">โ written</span></div>
|
|
344
|
+
<div class="ln" data-d="3600"> </div>
|
|
345
|
+
<div class="ln" data-d="3700"><span class="ai-out">Done. React + Flask + OAuth + Redis + MongoDB + Nginx scaffolded.</span></div>
|
|
346
|
+
<div class="ln" data-d="3800"><span class="ai-out">Run with: <span class="code">docker compose up --build</span></span></div>
|
|
347
|
+
<div class="ln" data-d="4100"> </div>
|
|
348
|
+
<div class="ln" data-d="4200"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="cur"></span></div>
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<!-- TYPO -->
|
|
352
|
+
<div class="panel" id="panel-typo">
|
|
353
|
+
<div class="ln" data-d="0"><span class="muted"># shmakk uses your machine's command history + probability</span></div>
|
|
354
|
+
<div class="ln" data-d="100"><span class="muted"># to correct typos. no LLM call. instant.</span></div>
|
|
355
|
+
<div class="ln" data-d="200"> </div>
|
|
356
|
+
<div class="ln" data-d="300"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">gti</span> commit -m "fix login bug"</span></div>
|
|
357
|
+
<div class="ln" data-d="600"><span class="task-label">[shmakk task] (Ctrl-C to interrupt)</span></div>
|
|
358
|
+
<div class="ln" data-d="850"><span class="muted">correcting: </span><span class="corr-old">gti</span><span class="corr-arrow"> โ </span><span class="corr-new">git</span><span class="muted"> (your history, p=0.99)</span></div>
|
|
359
|
+
<div class="ln" data-d="1100"><span class="muted">running: </span><span class="white">git commit -m "fix login bug"</span></div>
|
|
360
|
+
<div class="ln" data-d="1600"> </div>
|
|
361
|
+
<div class="ln" data-d="1700"><span class="ai-out">[main 7d3a91f] fix login bug</span></div>
|
|
362
|
+
<div class="ln" data-d="1800"><span class="ai-out"> 2 files changed, 18 insertions(+), 4 deletions(-)</span></div>
|
|
363
|
+
<div class="ln" data-d="2200"> </div>
|
|
364
|
+
<div class="ln" data-d="2300"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">docekr-compose</span> up</span></div>
|
|
365
|
+
<div class="ln" data-d="2600"><span class="task-label">[shmakk task] (Ctrl-C to interrupt)</span></div>
|
|
366
|
+
<div class="ln" data-d="2850"><span class="muted">correcting: </span><span class="corr-old">docekr-compose</span><span class="corr-arrow"> โ </span><span class="corr-new">docker-compose</span><span class="muted"> (your history, p=0.97)</span></div>
|
|
367
|
+
<div class="ln" data-d="3100"><span class="muted">running: </span><span class="white">docker-compose up</span></div>
|
|
368
|
+
<div class="ln" data-d="3600"> </div>
|
|
369
|
+
<div class="ln" data-d="3700"><span class="ai-out">Starting demo-deepseek_redis_1 ... done</span></div>
|
|
370
|
+
<div class="ln" data-d="3800"><span class="ai-out">Starting demo-deepseek_mongo_1 ... done</span></div>
|
|
371
|
+
<div class="ln" data-d="3900"><span class="ai-out">Starting demo-deepseek_backend_1 ... done</span></div>
|
|
372
|
+
<div class="ln" data-d="4200"> </div>
|
|
373
|
+
<div class="ln" data-d="4300"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="cur"></span></div>
|
|
374
|
+
</div>
|
|
375
|
+
|
|
376
|
+
<!-- SKILLS -->
|
|
377
|
+
<div class="panel" id="panel-skills">
|
|
378
|
+
<div class="ln" data-d="0"><span class="muted"># install a skill from any URL โ shmakk handles the rest</span></div>
|
|
379
|
+
<div class="ln" data-d="100"> </div>
|
|
380
|
+
<div class="ln" data-d="200"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">shmakk</span> --install-skill https://example.com/skills/rust-expert.md</span></div>
|
|
381
|
+
<div class="ln" data-d="600"><span class="task-label">[shmakk task] (Ctrl-C to interrupt)</span></div>
|
|
382
|
+
<div class="ln" data-d="900"><span class="thinking">โฅ fetching skill...</span></div>
|
|
383
|
+
<div class="ln" data-d="1500"><span class="tool-result"> fetched: rust-expert.md (2.1 KB)</span></div>
|
|
384
|
+
<div class="ln" data-d="1700"><span class="tool-result"> installed to: ~/.shmakk/skills/rust-expert</span></div>
|
|
385
|
+
<div class="ln" data-d="1900"><span class="ai-out">Skill 'rust-expert' ready. It will be loaded automatically</span></div>
|
|
386
|
+
<div class="ln" data-d="2000"><span class="ai-out">when relevant context is detected.</span></div>
|
|
387
|
+
<div class="ln" data-d="2400"> </div>
|
|
388
|
+
<div class="ln" data-d="2500"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">shmakk</span> --list-skills</span></div>
|
|
389
|
+
<div class="ln" data-d="2900"><span class="tool-result"> rust-expert loaded from https://example.com/skills/rust-expert.md</span></div>
|
|
390
|
+
<div class="ln" data-d="3050"><span class="tool-result"> docker-compose loaded from https://example.com/skills/docker.md</span></div>
|
|
391
|
+
<div class="ln" data-d="3200"><span class="tool-result"> git-flow loaded from https://example.com/skills/git-flow.md</span></div>
|
|
392
|
+
<div class="ln" data-d="3500"> </div>
|
|
393
|
+
<div class="ln" data-d="3600"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">shmakk</span> --load-skill rust-expert</span></div>
|
|
394
|
+
<div class="ln" data-d="4000"><span class="ai-out">rust-expert skill active for this session.</span></div>
|
|
395
|
+
<div class="ln" data-d="4300"> </div>
|
|
396
|
+
<div class="ln" data-d="4400"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~</span><span class="muted">></span> <span class="cur"></span></div>
|
|
397
|
+
</div>
|
|
398
|
+
|
|
399
|
+
<!-- PROFILES -->
|
|
400
|
+
<div class="panel" id="panel-profiles">
|
|
401
|
+
<div class="ln" data-d="0"><span class="muted"># runtime profiles, live switching, context budgeting</span></div>
|
|
402
|
+
<div class="ln" data-d="100"> </div>
|
|
403
|
+
<div class="ln" data-d="200"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">shmakk</span> --profile builder</span></div>
|
|
404
|
+
<div class="ln" data-d="600"><span class="ai-out">profile: builder (large context, file-write optimised)</span></div>
|
|
405
|
+
<div class="ln" data-d="900"> </div>
|
|
406
|
+
<div class="ln" data-d="1000"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">shmakk</span> --profile-set tiny</span></div>
|
|
407
|
+
<div class="ln" data-d="1400"><span class="ai-out">switching to profile: tiny (minimal context, fastest responses)</span></div>
|
|
408
|
+
<div class="ln" data-d="1700"><span class="muted">restarting inner shellโฆ</span></div>
|
|
409
|
+
<div class="ln" data-d="2100"><span class="ai-out">ready.</span></div>
|
|
410
|
+
<div class="ln" data-d="2400"> </div>
|
|
411
|
+
<div class="ln" data-d="2500"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="user-input"><span class="cmd-first">shmakk</span> --compact</span></div>
|
|
412
|
+
<div class="ln" data-d="2900"><span class="muted">context budget: 18 400 / 32 000 tokens used</span></div>
|
|
413
|
+
<div class="ln" data-d="3100"><span class="ai-out">conversation history cleared. context reset.</span></div>
|
|
414
|
+
<div class="ln" data-d="3400"> </div>
|
|
415
|
+
<div class="ln" data-d="3500"><span class="muted"># available profiles</span></div>
|
|
416
|
+
<div class="ln" data-d="3600"><span class="tool-result"> tiny minimal context, fastest responses</span></div>
|
|
417
|
+
<div class="ln" data-d="3700"><span class="tool-result"> balanced default โ good for daily work</span></div>
|
|
418
|
+
<div class="ln" data-d="3800"><span class="tool-result"> deep larger investigations, multi-step tasks</span></div>
|
|
419
|
+
<div class="ln" data-d="3900"><span class="tool-result"> builder editing and building large projects</span></div>
|
|
420
|
+
<div class="ln" data-d="4100"> </div>
|
|
421
|
+
<div class="ln" data-d="4200"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~/D/r/s/demo-deepseek</span><span class="muted">></span> <span class="cur"></span></div>
|
|
422
|
+
</div>
|
|
423
|
+
|
|
424
|
+
<!-- VOICE -->
|
|
425
|
+
<div class="panel" id="panel-voice">
|
|
426
|
+
<div class="ln" data-d="0"><span class="muted"># always-on speech-to-speech. no hotkey. just speak.</span></div>
|
|
427
|
+
<div class="ln" data-d="150"><span class="muted"># 100% local โ whisper + kokoro ONNX, no API, no cloud.</span></div>
|
|
428
|
+
<div class="ln" data-d="300"> </div>
|
|
429
|
+
<div class="ln" data-d="400"><span class="hostname">marcus@tobarko.ai</span> <span class="path">~</span><span class="muted">></span> <span class="white">shmakk --sts</span></div>
|
|
430
|
+
<div class="ln" data-d="700"><span class="muted">[shmakk] STT ready (Whisper-base ONNX)</span></div>
|
|
431
|
+
<div class="ln" data-d="900"><span class="muted">[shmakk] TTS ready (Kokoro-82M, voice=<span class="voice-name">af_river</span>)</span></div>
|
|
432
|
+
<div class="ln" data-d="1100"> </div>
|
|
433
|
+
<div class="ln" data-d="1300"><span class="voice-mic"><span class="mic-anim"><span class="mic-ring"></span></span> listening...</span></div>
|
|
434
|
+
<div class="ln" data-d="2400"><span class="voice-txt">๐ค hey can you check if there are any syntax errors in agent.js</span></div>
|
|
435
|
+
<div class="ln" data-d="2700"><span class="task-label">[shmakk task] (Ctrl-C to interrupt)</span></div>
|
|
436
|
+
<div class="ln" data-d="2900"><span class="muted">ยท read agent.js</span></div>
|
|
437
|
+
<div class="ln" data-d="3300"><span class="ai-out">No syntax errors. One thing worth flagging: the tool</span></div>
|
|
438
|
+
<div class="ln" data-d="3400"><span class="ai-out">result cache uses JSON.stringify as a key โ that could</span></div>
|
|
439
|
+
<div class="ln" data-d="3500"><span class="ai-out">collide for deeply nested args. Low risk for current tools.</span></div>
|
|
440
|
+
<div class="ln" data-d="3700"><span class="muted">[shmakk] ๐ speaking as <span class="voice-name">af_river</span>...</span></div>
|
|
441
|
+
<div class="ln" data-d="4000"> </div>
|
|
442
|
+
<div class="ln" data-d="4100"><span class="voice-mic"><span class="mic-anim"><span class="mic-ring"></span></span> listening...</span></div>
|
|
443
|
+
<div class="ln" data-d="4800"><span class="voice-txt">๐ค stop</span></div>
|
|
444
|
+
<div class="ln" data-d="5000"><span class="muted">๐คซ stopped</span></div>
|
|
445
|
+
<div class="ln" data-d="5200"> </div>
|
|
446
|
+
<div class="ln" data-d="5300"><span class="voice-mic"><span class="mic-anim"><span class="mic-ring"></span></span> listening...</span></div>
|
|
447
|
+
|
|
448
|
+
<div class="voice-schedule ln show" data-d="0" style="opacity:1">
|
|
449
|
+
<div class="voice-schedule-title">today's voice schedule โ deterministic, feels random</div>
|
|
450
|
+
<div class="voice-slots" id="voice-slots"></div>
|
|
451
|
+
<div style="font-size:10px;color:#2a2a2a;margin-top:10px;">
|
|
452
|
+
seed = date ร prime โ bucket sizes 2โ5h โ voice index. same day = same schedule. no state, no config.
|
|
453
|
+
</div>
|
|
454
|
+
</div>
|
|
455
|
+
</div>
|
|
456
|
+
|
|
457
|
+
<button class="replay" onclick="replay()">โบ replay</button>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<!-- FEATURES -->
|
|
462
|
+
<div class="section-label">what it does</div>
|
|
463
|
+
<div class="features">
|
|
464
|
+
<div class="feat voice-feat">
|
|
465
|
+
<h3>๐ค Voice โ speaks back</h3>
|
|
466
|
+
<p>Always-on mic via VAD. Speak naturally, pause to send. Kokoro TTS reads responses aloud sentence-by-sentence so the first word plays in under a second. Say <code>stop</code> to interrupt mid-sentence. 28 voices, all local, no API.</p>
|
|
467
|
+
</div>
|
|
468
|
+
<div class="feat voice-feat">
|
|
469
|
+
<h3>๐ฒ A different voice every few hours</h3>
|
|
470
|
+
<p>shmakk rotates through all 28 Kokoro voices on a deterministic daily schedule โ changes every 2 to 5 hours, timed differently each day. No randomness at runtime, no state. Just a hash of the date. Feels alive, costs nothing.</p>
|
|
471
|
+
</div>
|
|
472
|
+
<div class="feat">
|
|
473
|
+
<h3>Typo correction</h3>
|
|
474
|
+
<p>Deterministic, no API call. Uses your machine's command history and probability to fix typos the way <em>you</em> type, not some generic model.</p>
|
|
475
|
+
</div>
|
|
476
|
+
<div class="feat">
|
|
477
|
+
<h3>Chat in shell</h3>
|
|
478
|
+
<p>Just write. Ask questions, get answers, run suggested commands โ all without leaving the terminal. Session history is preserved until you <code>--compact</code>.</p>
|
|
479
|
+
</div>
|
|
480
|
+
<div class="feat">
|
|
481
|
+
<h3>Project scaffolding</h3>
|
|
482
|
+
<p>Describe what you want in plain English. shmakk plans, creates dirs, writes files, asks before anything risky. Subagents spawned automatically for parallel work.</p>
|
|
483
|
+
</div>
|
|
484
|
+
<div class="feat">
|
|
485
|
+
<h3>Skills</h3>
|
|
486
|
+
<p>Extend behaviour with any URL: <code>shmakk --install-skill <url></code>. Loaded per-session or automatically when relevant context is detected.</p>
|
|
487
|
+
</div>
|
|
488
|
+
<div class="feat">
|
|
489
|
+
<h3>Runtime profiles</h3>
|
|
490
|
+
<p><code>tiny</code> ยท <code>balanced</code> ยท <code>deep</code> ยท <code>builder</code>. Switch live with <code>--profile-set</code>. Context budgeting and loop-stall protection built in.</p>
|
|
491
|
+
</div>
|
|
492
|
+
<div class="feat">
|
|
493
|
+
<h3>Safety</h3>
|
|
494
|
+
<p>Risky commands always confirm before running. Secrets (<code>.env</code>, tokens, keys) are never sent to the AI. Defensive handling for fallback tool-call formats.</p>
|
|
495
|
+
</div>
|
|
496
|
+
</div>
|
|
497
|
+
|
|
498
|
+
<div class="cta">
|
|
499
|
+
<a href="https://github.com/marbad1994/shmakk">โญ Star on GitHub</a>
|
|
500
|
+
<a class="ghost" href="https://github.com/marbad1994/shmakk#readme">Read the docs</a>
|
|
501
|
+
<p class="cta-note">works with any OpenAI-compatible API โ bring your own key</p>
|
|
502
|
+
</div>
|
|
503
|
+
|
|
504
|
+
<script>
|
|
505
|
+
let current = 'chat';
|
|
506
|
+
let timers = [];
|
|
507
|
+
const order = ['chat','project','typo','skills','profiles','voice'];
|
|
508
|
+
|
|
509
|
+
function go(name) {
|
|
510
|
+
timers.forEach(clearTimeout); timers = [];
|
|
511
|
+
document.querySelectorAll('.tab').forEach((b,i) => b.classList.toggle('active', order[i] === name));
|
|
512
|
+
document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
|
|
513
|
+
const panel = document.getElementById('panel-' + name);
|
|
514
|
+
panel.classList.add('active');
|
|
515
|
+
panel.querySelectorAll('.ln:not(.voice-schedule)').forEach(l => l.classList.remove('show'));
|
|
516
|
+
current = name;
|
|
517
|
+
document.getElementById('win-title').textContent = name === 'voice'
|
|
518
|
+
? 'shmakk --sts : MainThread'
|
|
519
|
+
: 'shmakk : MainThread';
|
|
520
|
+
animate(panel);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
function animate(panel) {
|
|
524
|
+
panel.querySelectorAll('.ln:not(.voice-schedule)').forEach(el => {
|
|
525
|
+
const d = parseInt(el.dataset.d || 0);
|
|
526
|
+
timers.push(setTimeout(() => el.classList.add('show'), d));
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function replay() { go(current); }
|
|
531
|
+
animate(document.getElementById('panel-chat'));
|
|
532
|
+
|
|
533
|
+
// โโ Voice schedule โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
534
|
+
const VOICES = [
|
|
535
|
+
'af_bella','af_sarah','af_sky','af_nicole','af_heart','af_aoede','af_river',
|
|
536
|
+
'am_adam','am_michael','am_echo','am_liam',
|
|
537
|
+
'bf_emma','bf_isabella',
|
|
538
|
+
'bm_george','bm_lewis','bm_daniel',
|
|
539
|
+
'jf_alpha','jf_gongitsune','jf_nezumi','jf_tebukuro','jm_kumo',
|
|
540
|
+
'zf_xiaobei','zf_xiaoni','zf_xiaoxiao','zf_xiaoyi',
|
|
541
|
+
'zm_yunjian','zm_yunxia'
|
|
542
|
+
];
|
|
543
|
+
|
|
544
|
+
function lcg(seed) { return ((seed * 1664525 + 1013904223) >>> 0); }
|
|
545
|
+
|
|
546
|
+
function buildSchedule() {
|
|
547
|
+
const now = new Date();
|
|
548
|
+
const day = now.getFullYear() * 10000 + (now.getMonth() + 1) * 100 + now.getDate();
|
|
549
|
+
const daySeed = (day * 2654435761) >>> 0;
|
|
550
|
+
const minuteNow = now.getHours() * 60 + now.getMinutes();
|
|
551
|
+
|
|
552
|
+
let t = 0, b = 0, seed = daySeed;
|
|
553
|
+
const slots = [];
|
|
554
|
+
while (t < 1440) {
|
|
555
|
+
seed = lcg(seed);
|
|
556
|
+
const mins = 120 + (seed % 180);
|
|
557
|
+
const voiceSeed = (daySeed ^ (b * 2246822519)) >>> 0;
|
|
558
|
+
const voice = VOICES[voiceSeed % VOICES.length];
|
|
559
|
+
const end = Math.min(t + mins, 1440);
|
|
560
|
+
slots.push({ t, end, voice, current: minuteNow >= t && minuteNow < end });
|
|
561
|
+
t = end; b++;
|
|
562
|
+
}
|
|
563
|
+
return slots;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
function fmt(mins) {
|
|
567
|
+
return String(Math.floor(mins/60)).padStart(2,'0') + ':' + String(mins%60).padStart(2,'0');
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const slots = buildSchedule();
|
|
571
|
+
const container = document.getElementById('voice-slots');
|
|
572
|
+
slots.forEach(s => {
|
|
573
|
+
const el = document.createElement('div');
|
|
574
|
+
el.className = 'voice-slot' + (s.current ? ' current' : '');
|
|
575
|
+
el.textContent = fmt(s.t) + ' ' + s.voice;
|
|
576
|
+
el.title = fmt(s.t) + 'โ' + fmt(s.end) + ' (' + Math.round((s.end-s.t)/60*10)/10 + 'h)';
|
|
577
|
+
container.appendChild(el);
|
|
578
|
+
});
|
|
579
|
+
</script>
|
|
580
|
+
</body>
|
|
581
|
+
</html>
|