shmakk 1.2.3 → 1.2.5
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 +11 -0
- package/README.md +75 -1
- package/docs/index.html +154 -16
- package/docs/mcp.md +78 -0
- package/docs/ssh.md +82 -0
- package/docs/vibedit-analysis.md +375 -0
- package/docs/vim.md +110 -0
- package/docs/voice.md +4 -0
- package/package.json +9 -5
- package/scripts/test-vibedit.js +45 -0
- package/scripts/vibedit-demo.sh +52 -0
- package/skills/shmakk-skill-creator.md +269 -0
- package/src/_check.js +7 -0
- package/src/_check_schema.js +5 -0
- package/src/_cleanup.js +18 -0
- package/src/_fix.js +9 -0
- package/src/_test_import.js +15 -0
- package/src/agent.js +11 -4
- package/src/browser-daemon.js +209 -0
- package/src/browser.js +10 -0
- package/src/cli/browserDaemon.js +60 -0
- package/src/cli/connectBrowser.js +137 -0
- package/src/cli.js +235 -8
- package/src/completions.js +8 -0
- package/src/control.js +273 -1
- package/src/core/browserConnector.js +523 -0
- package/src/correction.js +6 -0
- package/src/electron.js +305 -0
- package/src/endpoints.js +74 -9
- package/src/index.js +24 -1
- package/src/llm.js +501 -61
- package/src/mobile.js +307 -0
- package/src/notify.js +51 -3
- package/src/orchestrator.js +35 -1
- package/src/pty.js +11 -6
- package/src/review.js +45 -11
- package/src/self-commands.js +153 -0
- package/src/session-convert.js +508 -0
- package/src/session-search.js +31 -0
- package/src/session.js +392 -46
- package/src/skills/browserActions.ts +984 -0
- package/src/skills.js +451 -24
- package/src/system-prompt.js +31 -25
- package/src/tools.js +81 -0
- package/src/vibedit/control.js +534 -0
- package/src/vibedit/electron.js +108 -0
- package/src/vibedit/files.js +171 -0
- package/src/vibedit/index.js +298 -0
- package/src/vibedit/overlay.js +1482 -0
- package/src/vibedit/prompts.js +245 -0
- package/src/vibedit/state.js +32 -0
- package/src/vim.js +410 -0
package/src/system-prompt.js
CHANGED
|
@@ -52,14 +52,18 @@ Core Principles:
|
|
|
52
52
|
- Do not delete files, overwrite large sections, rename public APIs, change schemas, run destructive commands, or perform broad refactors without explicit user confirmation.
|
|
53
53
|
- Never expose secrets, credentials, tokens, private keys, environment values, or sensitive paths.
|
|
54
54
|
|
|
55
|
-
Tool Call Format:
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
|
|
55
|
+
Tool Call Format — use whichever your model supports natively:
|
|
56
|
+
- Native tool calls (preferred when your API endpoint supports tool_use / tool_calls).
|
|
57
|
+
- XML format:
|
|
58
|
+
<tool_calls>
|
|
59
|
+
<invoke name="tool_name">
|
|
60
|
+
<parameter name="arg_name" string="true|false">value</parameter>
|
|
61
|
+
</invoke>
|
|
62
|
+
</tool_calls>
|
|
63
|
+
- JSON fallback format (no other prose in the message):
|
|
59
64
|
{"shmakk_actions":[{"tool":"tool_name","args":{...}}]}
|
|
60
65
|
|
|
61
|
-
- Do not
|
|
62
|
-
- Do not mix JSON tool calls with explanatory text.
|
|
66
|
+
- Do not mix tool call text with explanatory prose.
|
|
63
67
|
- Do not wrap JSON tool calls in markdown fences.
|
|
64
68
|
- Do not emit invalid JSON.
|
|
65
69
|
- Do not include comments inside JSON.
|
|
@@ -224,24 +228,33 @@ Provide a concise final summary with:
|
|
|
224
228
|
|
|
225
229
|
Examples:
|
|
226
230
|
|
|
227
|
-
Correct
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
231
|
+
Correct XML tool call:
|
|
232
|
+
<tool_calls>
|
|
233
|
+
<invoke name="list_dir">
|
|
234
|
+
<parameter name="path" string="true">src</parameter>
|
|
235
|
+
</invoke>
|
|
236
|
+
</tool_calls>
|
|
237
|
+
|
|
238
|
+
Correct XML tool call with explanation (one short sentence before the XML is fine):
|
|
239
|
+
I'll check the project structure first.
|
|
240
|
+
<tool_calls>
|
|
241
|
+
<invoke name="list_dir">
|
|
242
|
+
<parameter name="path" string="true">src</parameter>
|
|
243
|
+
</invoke>
|
|
244
|
+
</tool_calls>
|
|
245
|
+
|
|
246
|
+
Correct JSON fallback:
|
|
238
247
|
{"shmakk_actions":[{"tool":"list_dir","args":{"path":"src"}}]}
|
|
239
248
|
|
|
240
|
-
Incorrect:
|
|
249
|
+
Incorrect (wrapping JSON in markdown fences):
|
|
241
250
|
\`\`\`json
|
|
242
251
|
{"shmakk_actions":[{"tool":"list_dir","args":{"path":"src"}}]}
|
|
243
252
|
\`\`\`
|
|
244
253
|
|
|
254
|
+
Incorrect (mixing prose with JSON):
|
|
255
|
+
I'll check the src directory:
|
|
256
|
+
{"shmakk_actions":[{"tool":"list_dir","args":{"path":"src"}}]}
|
|
257
|
+
|
|
245
258
|
Incorrect:
|
|
246
259
|
Can you run npm test for me?
|
|
247
260
|
|
|
@@ -253,13 +266,6 @@ Remember:
|
|
|
253
266
|
- Use tools directly.
|
|
254
267
|
- Prefer minimal edits.
|
|
255
268
|
- Verify when possible.
|
|
256
|
-
- Use only native tool calls or the exact JSON fallback.
|
|
257
|
-
|
|
258
|
-
Final rule:
|
|
259
|
-
Never output XML, markdown, or prose when calling a tool.
|
|
260
|
-
Use native tool calls if available.
|
|
261
|
-
Otherwise output only:
|
|
262
|
-
{"shmakk_actions":[{"tool":"tool_name","args":{...}}]}
|
|
263
269
|
${indexHint}
|
|
264
270
|
${activeSkillText ? `\n\n${activeSkillText}` : ''}
|
|
265
271
|
${specialistHint ? `\n\n${specialistHint.trim()}` : ''}
|
package/src/tools.js
CHANGED
|
@@ -7,6 +7,8 @@ const { execFile } = require('child_process');
|
|
|
7
7
|
const { classifyRunCommand, isSecretPath } = require('./safety');
|
|
8
8
|
const { webSearch, fetchUrl } = require('./web');
|
|
9
9
|
const { dispatchBrowser, classifyBrowserCommand } = require('./browser');
|
|
10
|
+
const { dispatchMobile, classifyMobileCommand } = require('./mobile');
|
|
11
|
+
const { dispatchElectron, classifyElectronCommand } = require('./electron');
|
|
10
12
|
const { recordEdit } = require('./edit-tracker');
|
|
11
13
|
const { appendMemory } = require('./memory');
|
|
12
14
|
const { isMutationTool, hashArgs } = require('./guard');
|
|
@@ -178,6 +180,50 @@ const TOOLS = [
|
|
|
178
180
|
},
|
|
179
181
|
},
|
|
180
182
|
}},
|
|
183
|
+
{ type: 'function', function: {
|
|
184
|
+
name: 'mobile',
|
|
185
|
+
description: 'Control an Android device/emulator via ADB. Commands: screenshot (capture screen as PNG), click (tap at x,y coordinates), type (input text), swipe (drag from x1,y1 to x2,y2), key (press BACK/HOME/etc), read_page (parse UI hierarchy via uiautomator), list_apps (list installed packages), launch (start app by package name), close (force-stop app), wait (pause in ms). Requires adb on PATH and a connected device.',
|
|
186
|
+
parameters: {
|
|
187
|
+
type: 'object',
|
|
188
|
+
required: ['command'],
|
|
189
|
+
properties: {
|
|
190
|
+
command: { type: 'string', enum: ['screenshot', 'click', 'type', 'swipe', 'key', 'read_page', 'list_apps', 'launch', 'close', 'wait'] },
|
|
191
|
+
x: { type: 'number', description: 'X coordinate for click' },
|
|
192
|
+
y: { type: 'number', description: 'Y coordinate for click' },
|
|
193
|
+
x1: { type: 'number', description: 'Start X for swipe' },
|
|
194
|
+
y1: { type: 'number', description: 'Start Y for swipe' },
|
|
195
|
+
x2: { type: 'number', description: 'End X for swipe' },
|
|
196
|
+
y2: { type: 'number', description: 'End Y for swipe' },
|
|
197
|
+
duration: { type: 'number', description: 'Swipe duration in ms' },
|
|
198
|
+
text: { type: 'string', description: 'Text to type' },
|
|
199
|
+
code: { type: 'string', description: 'Key code: BACK, HOME, ENTER, DELETE, MENU, APP_SWITCH, VOLUME_UP, VOLUME_DOWN' },
|
|
200
|
+
package: { type: 'string', description: 'Android package name (e.g. com.example.app)' },
|
|
201
|
+
filter: { type: 'string', description: 'Package name filter for list_apps' },
|
|
202
|
+
ms: { type: 'number', description: 'Milliseconds to wait' },
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
}},
|
|
206
|
+
{ type: 'function', function: {
|
|
207
|
+
name: 'electron',
|
|
208
|
+
description: 'Control an Electron desktop app via Chrome DevTools Protocol (CDP). Commands: screenshot (capture window as PNG), navigate (go to URL), click (CSS selector), type (fill input), read_page (extract page content, links, forms), evaluate (run JS), select (dropdown), wait (for selector or seconds), scroll (up/down), close (disconnect), connect (attach to a debug port). The Electron app must be running with --remote-debugging-port (default 9222). Requires playwright installed.',
|
|
209
|
+
parameters: {
|
|
210
|
+
type: 'object',
|
|
211
|
+
required: ['command'],
|
|
212
|
+
properties: {
|
|
213
|
+
command: { type: 'string', enum: ['screenshot', 'navigate', 'click', 'type', 'read_page', 'evaluate', 'select', 'wait', 'scroll', 'close', 'connect'] },
|
|
214
|
+
url: { type: 'string', description: 'URL for navigate' },
|
|
215
|
+
selector: { type: 'string', description: 'CSS selector for click/type/select/wait' },
|
|
216
|
+
text: { type: 'string', description: 'Text to type or option to select' },
|
|
217
|
+
code: { type: 'string', description: 'JavaScript for evaluate' },
|
|
218
|
+
seconds: { type: 'number', description: 'Seconds to wait' },
|
|
219
|
+
direction: { type: 'string', enum: ['up', 'down'], description: 'Scroll direction' },
|
|
220
|
+
amount: { type: 'number', description: 'Scroll amount in pixels' },
|
|
221
|
+
debugPort: { type: 'number', description: 'CDP debug port. Default 9222.' },
|
|
222
|
+
value: { type: 'string', description: 'Option value for select' },
|
|
223
|
+
fullPage: { type: 'boolean', description: 'Screenshot full page. Default true.' },
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
}},
|
|
181
227
|
{ type: 'function', function: {
|
|
182
228
|
name: 'image_gen',
|
|
183
229
|
description: 'Generate an image from a text prompt using OpenAI DALL-E. The image is saved to disk and the file path is returned. Requires SHMAKK_OPENAI_API_KEY env var.',
|
|
@@ -299,6 +345,8 @@ function classifyTool(name, args, mcpManager) {
|
|
|
299
345
|
if (name === 'run') return classifyRunCommand(args.cmd || '');
|
|
300
346
|
if (name === 'web_search' || name === 'fetch_url') return 'safe';
|
|
301
347
|
if (name === 'browser') return classifyBrowserCommand(args);
|
|
348
|
+
if (name === 'mobile') return classifyMobileCommand(args);
|
|
349
|
+
if (name === 'electron') return classifyElectronCommand(args);
|
|
302
350
|
if (name === 'remember') return 'safe';
|
|
303
351
|
if (name === 'image_gen') return 'unsafe'; // external API call, costs money
|
|
304
352
|
if (name === 'tts_generate') return 'safe'; // local-only, no network
|
|
@@ -330,6 +378,27 @@ function describeTool(name, args, mcpManager) {
|
|
|
330
378
|
if (cmd === 'evaluate') return `browser eval JS`;
|
|
331
379
|
return `browser ${cmd}`;
|
|
332
380
|
}
|
|
381
|
+
if (name === 'mobile') {
|
|
382
|
+
const cmd = args.command || '';
|
|
383
|
+
if (cmd === 'screenshot') return 'mobile screenshot';
|
|
384
|
+
if (cmd === 'click') return `mobile click (${args.x}, ${args.y})`;
|
|
385
|
+
if (cmd === 'type') return `mobile type "${(args.text || '').slice(0, 40)}"`;
|
|
386
|
+
if (cmd === 'swipe') return `mobile swipe (${args.x1},${args.y1}) to (${args.x2},${args.y2})`;
|
|
387
|
+
if (cmd === 'read_page') return 'mobile read page';
|
|
388
|
+
if (cmd === 'launch') return `mobile launch ${args.package || ''}`;
|
|
389
|
+
if (cmd === 'close') return `mobile close ${args.package || ''}`;
|
|
390
|
+
return `mobile ${cmd}`;
|
|
391
|
+
}
|
|
392
|
+
if (name === 'electron') {
|
|
393
|
+
const cmd = args.command || '';
|
|
394
|
+
if (cmd === 'screenshot') return 'electron screenshot';
|
|
395
|
+
if (cmd === 'navigate') return `electron navigate ${args.url || ''}`;
|
|
396
|
+
if (cmd === 'click') return `electron click ${args.selector || ''}`;
|
|
397
|
+
if (cmd === 'type') return `electron type into ${args.selector || ''}`;
|
|
398
|
+
if (cmd === 'read_page') return 'electron read page content';
|
|
399
|
+
if (cmd === 'connect') return `electron connect port ${args.debugPort || 9222}`;
|
|
400
|
+
return `electron ${cmd}`;
|
|
401
|
+
}
|
|
333
402
|
if (name === 'image_gen') return `image_gen: "${(args.prompt || '').slice(0, 80)}" (${args.size || '1024x1024'})`;
|
|
334
403
|
if (name === 'tts_generate') return `tts_generate: "${(args.text || '').slice(0, 80)}" (voice: ${args.voice || 'af_heart'})`;
|
|
335
404
|
if (name === 'video_probe') return `video_probe ${args.path || ''}`;
|
|
@@ -528,6 +597,12 @@ async function dispatchTool(name, args, roots, confirmTool, signal, mcpManager)
|
|
|
528
597
|
if (name === 'browser') {
|
|
529
598
|
return await dispatchBrowser(args);
|
|
530
599
|
}
|
|
600
|
+
if (name === 'mobile') {
|
|
601
|
+
return await dispatchMobile(args);
|
|
602
|
+
}
|
|
603
|
+
if (name === 'electron') {
|
|
604
|
+
return await dispatchElectron(args);
|
|
605
|
+
}
|
|
531
606
|
if (name === 'remember') {
|
|
532
607
|
const r = appendMemory({
|
|
533
608
|
category: args.category,
|
|
@@ -603,6 +678,12 @@ async function dispatchTool(name, args, roots, confirmTool, signal, mcpManager)
|
|
|
603
678
|
prompt,
|
|
604
679
|
size,
|
|
605
680
|
revised_prompt: postData.data[0].revised_prompt || prompt,
|
|
681
|
+
images: [{
|
|
682
|
+
mimeType: 'image/png',
|
|
683
|
+
data: b64,
|
|
684
|
+
dataLength: b64.length,
|
|
685
|
+
truncated: false,
|
|
686
|
+
}],
|
|
606
687
|
};
|
|
607
688
|
}
|
|
608
689
|
if (name === 'tts_generate') {
|