nothumanallowed 9.2.4 → 9.3.1
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/README.md +54 -11
- package/package.json +2 -2
- package/src/cli.mjs +117 -0
- package/src/commands/chat.mjs +43 -1
- package/src/commands/ui.mjs +24 -0
- package/src/constants.mjs +1 -1
- package/src/services/browser-engine.mjs +1156 -0
- package/src/services/tool-executor.mjs +197 -0
- package/src/services/web-ui.mjs +23 -4
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# NotHumanAllowed (v9.
|
|
1
|
+
# NotHumanAllowed (v9.3)
|
|
2
2
|
|
|
3
3
|
**Tell the AI what you need. It does it.**
|
|
4
4
|
|
|
5
5
|
Your AI assistant for email, calendar, web search, files, and everything else. Type what you want in plain language — NHA handles it. Read emails, schedule meetings, search the web, manage tasks, analyze documents, browse Google Drive, check GitHub, Slack, Notion — all from one place.
|
|
6
6
|
|
|
7
|
-
38 AI agents.
|
|
7
|
+
38 AI agents. 58 tools. Web search built in. Streaming chat. Multiple conversations with history and export. Browser automation. Voice chat. Available on **PC, Mac, Linux, and Android**.
|
|
8
8
|
|
|
9
9
|
100% private — your data never leaves your machine. Zero data on our servers. Free and open source.
|
|
10
10
|
|
|
@@ -26,13 +26,13 @@ nha config set key sk-ant-api03-YOUR_KEY
|
|
|
26
26
|
# Connect Google (Gmail, Calendar, Drive, Contacts, Tasks)
|
|
27
27
|
nha google auth
|
|
28
28
|
|
|
29
|
-
# Start chatting —
|
|
29
|
+
# Start chatting — 58 tools available
|
|
30
30
|
nha chat
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## What You Can Do
|
|
34
34
|
|
|
35
|
-
### Chat with
|
|
35
|
+
### Chat with 58 Tools + Web Search + Browser
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
nha chat
|
|
@@ -62,7 +62,34 @@ NHA: Available 60-min slots:
|
|
|
62
62
|
3. Wed Apr 9, 02:00 PM - 04:00 PM
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
###
|
|
65
|
+
### Browser Automation (Zero Dependencies)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
nha browse open https://example.com # Open page in headless Chrome
|
|
69
|
+
nha browse screenshot # Capture screenshot
|
|
70
|
+
nha browse extract "h1" # Extract content by CSS selector
|
|
71
|
+
nha browse js "document.title" # Execute JavaScript
|
|
72
|
+
nha browse close # Close browser
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Control Chrome headless via the Chrome DevTools Protocol — no Puppeteer, no Playwright, no npm dependencies. Pure WebSocket CDP client built from scratch.
|
|
76
|
+
|
|
77
|
+
All browser tools are also available in `nha chat` and `nha ui`:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
You: Open google.com and search for "NHA AI agents"
|
|
81
|
+
NHA: [Browser: google.com] Page loaded: "Google"
|
|
82
|
+
[Typed: NHA AI agents] into search field
|
|
83
|
+
[Key: Enter] submitted search
|
|
84
|
+
[Extracted: results] Found 10 results...
|
|
85
|
+
|
|
86
|
+
You: Take a screenshot
|
|
87
|
+
NHA: [Screenshot] Captured and saved to ~/nha-screenshot.png
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
10 browser tools: `browser_open`, `browser_screenshot`, `browser_click`, `browser_type`, `browser_extract`, `browser_js`, `browser_wait`, `browser_scroll`, `browser_key`, `browser_close`. SSRF-protected — blocks localhost and private IPs.
|
|
91
|
+
|
|
92
|
+
### 58 Tools
|
|
66
93
|
|
|
67
94
|
| Category | Tools |
|
|
68
95
|
|----------|-------|
|
|
@@ -75,6 +102,7 @@ NHA: Available 60-min slots:
|
|
|
75
102
|
| **Slack** | List channels, read messages, send messages |
|
|
76
103
|
| **Notion** | Search pages/databases, read page content |
|
|
77
104
|
| **Web** | Web search (DuckDuckGo), fetch URL content, deep search with page extraction |
|
|
105
|
+
| **Browser** | Open pages, screenshot, click, type, extract text/HTML, execute JS, wait for elements, scroll, keyboard input, close |
|
|
78
106
|
| **Other** | Maps directions, reminders, file reading |
|
|
79
107
|
|
|
80
108
|
Every tool is called directly from your machine to the provider's API. NHA servers are never involved.
|
|
@@ -109,7 +137,7 @@ nha ask jarvis "Build a REST API for user management"
|
|
|
109
137
|
nha voice
|
|
110
138
|
```
|
|
111
139
|
|
|
112
|
-
Same
|
|
140
|
+
Same 58 tools, spoken responses. Opens a local web UI with speech recognition.
|
|
113
141
|
|
|
114
142
|
### Background Daemon
|
|
115
143
|
|
|
@@ -198,7 +226,7 @@ Everything the CLI does, on your phone:
|
|
|
198
226
|
- **Streaming chat** — see words appear as the AI thinks
|
|
199
227
|
- **Web search** — search the internet and read any webpage, right from chat
|
|
200
228
|
- **Multiple conversations** — save, switch, export your chats
|
|
201
|
-
- **
|
|
229
|
+
- **58 tools** — email, calendar, tasks, contacts, Drive, GitHub, Slack, Notion, browser
|
|
202
230
|
- **38 agents** — tap any agent, ask anything
|
|
203
231
|
- **Voice chat** — talk instead of typing, in 6 languages
|
|
204
232
|
- **Daily plan** — AI analyzes your emails + calendar every morning
|
|
@@ -223,7 +251,7 @@ All API calls go directly from your phone to providers. Zero data through NHA se
|
|
|
223
251
|
Your Machine Provider APIs
|
|
224
252
|
┌──────────────────┐ ┌─────────────────────┐
|
|
225
253
|
│ 38 agents │────→│ Google (Gmail, Cal, │
|
|
226
|
-
│
|
|
254
|
+
│ 58 tools │ │ Drive, Contacts) │
|
|
227
255
|
│ Your API keys │────→│ Your LLM provider │
|
|
228
256
|
│ Your data │────→│ GitHub, Slack, Notion│
|
|
229
257
|
│ (encrypted) │ └─────────────────────┘
|
|
@@ -256,6 +284,13 @@ Inside `nha chat`, use slash commands:
|
|
|
256
284
|
/clear Clear current conversation
|
|
257
285
|
/help Show all commands
|
|
258
286
|
/quit Exit
|
|
287
|
+
|
|
288
|
+
# Browser (in chat)
|
|
289
|
+
"Open example.com" → browser_open
|
|
290
|
+
"Take a screenshot" → browser_screenshot
|
|
291
|
+
"Click the submit button" → browser_click
|
|
292
|
+
"Type hello in the search" → browser_type
|
|
293
|
+
"Extract all links" → browser_extract
|
|
259
294
|
```
|
|
260
295
|
|
|
261
296
|
Inline agent routing: `@saber audit this function for SQL injection`
|
|
@@ -263,7 +298,7 @@ Inline agent routing: `@saber audit this function for SQL injection`
|
|
|
263
298
|
## Commands
|
|
264
299
|
|
|
265
300
|
```bash
|
|
266
|
-
# Chat (
|
|
301
|
+
# Chat (58 tools + web search, streaming)
|
|
267
302
|
nha chat # Interactive chat with tools
|
|
268
303
|
nha voice # Voice chat with TTS
|
|
269
304
|
|
|
@@ -281,6 +316,13 @@ nha ops start # Background daemon
|
|
|
281
316
|
# Google
|
|
282
317
|
nha google auth # Connect Google account
|
|
283
318
|
|
|
319
|
+
# Browser
|
|
320
|
+
nha browse open <url> # Open in headless Chrome
|
|
321
|
+
nha browse screenshot # Save screenshot to ~/
|
|
322
|
+
nha browse extract "selector" # Extract text by CSS selector
|
|
323
|
+
nha browse js "code" # Execute JavaScript
|
|
324
|
+
nha browse close # Close browser
|
|
325
|
+
|
|
284
326
|
# Config
|
|
285
327
|
nha config # Show settings
|
|
286
328
|
nha config set provider anthropic # Set LLM provider
|
|
@@ -296,7 +338,7 @@ nha mcp # Start MCP server
|
|
|
296
338
|
nha ui
|
|
297
339
|
```
|
|
298
340
|
|
|
299
|
-
Opens a local web dashboard on `localhost:3847` with streaming chat, multi-conversation, email, calendar, tasks, contacts, drive, agents, notes, settings — all in your browser. Zero framework, pure HTML/CSS/JS.
|
|
341
|
+
Opens a local web dashboard on `localhost:3847` with streaming chat, multi-conversation, email, calendar, tasks, contacts, drive, agents, notes, settings — all in your browser. Zero framework, pure HTML/CSS/JS. Screenshots from browser automation appear inline in the chat.
|
|
300
342
|
|
|
301
343
|
## NHA vs OpenClaw
|
|
302
344
|
|
|
@@ -306,9 +348,10 @@ NHA was built after the [OpenClaw/Moltbook security breach](https://nothumanallo
|
|
|
306
348
|
|---|---|---|
|
|
307
349
|
| Security | 7 CVEs, no WAF | SENTINEL WAF (Rust), 0 CVEs |
|
|
308
350
|
| Agents | 1 generic | 38 specialists |
|
|
309
|
-
| Tools | Install from hub |
|
|
351
|
+
| Tools | Install from hub | 58 built-in + web search + browser automation |
|
|
310
352
|
| Knowledge | None | 2.6M facts from 16 datasets |
|
|
311
353
|
| Daily Plan | None | 5-agent analysis |
|
|
354
|
+
| Browser | Chrome instance (heavy, attack surface) | Custom CDP engine, zero deps, SSRF-protected |
|
|
312
355
|
| Dependencies | Electron + Chrome | Zero |
|
|
313
356
|
| Privacy | Moltbook leaked 1.49M records | Zero data on our servers |
|
|
314
357
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "9.
|
|
4
|
-
"description": "NotHumanAllowed — 38 AI agents +
|
|
3
|
+
"version": "9.3.1",
|
|
4
|
+
"description": "NotHumanAllowed — 38 AI agents + 58 tools + browser automation + web search. Streaming chat, headless Chrome CDP, multi-conversation, export. Gmail, Calendar, Drive, GitHub, Notion, Slack. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"nha": "./bin/nha.mjs",
|
package/src/cli.mjs
CHANGED
|
@@ -128,6 +128,10 @@ export async function main(argv) {
|
|
|
128
128
|
case 'voice':
|
|
129
129
|
return cmdVoice(args);
|
|
130
130
|
|
|
131
|
+
case 'browse':
|
|
132
|
+
case 'browser':
|
|
133
|
+
return cmdBrowse(args);
|
|
134
|
+
|
|
131
135
|
case 'plugin':
|
|
132
136
|
case 'plugins':
|
|
133
137
|
return cmdPlugin(args);
|
|
@@ -247,6 +251,111 @@ async function cmdResponder(args) {
|
|
|
247
251
|
}
|
|
248
252
|
}
|
|
249
253
|
|
|
254
|
+
// ── nha browse ────────────────────────────────────────────────────────────
|
|
255
|
+
async function cmdBrowse(args) {
|
|
256
|
+
const sub = args[0];
|
|
257
|
+
|
|
258
|
+
if (sub === 'open' && args[1]) {
|
|
259
|
+
const { browserOpen, browserInfo } = await import('./services/browser-engine.mjs');
|
|
260
|
+
info(`Opening ${args[1]}...`);
|
|
261
|
+
const result = await browserOpen(args[1]);
|
|
262
|
+
if (result.error) {
|
|
263
|
+
fail(result.message);
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
ok(`${result.title}`);
|
|
267
|
+
info(`URL: ${result.url}`);
|
|
268
|
+
|
|
269
|
+
// If there are more args, execute them as a sequence
|
|
270
|
+
if (args.length <= 2) {
|
|
271
|
+
info('Browser is running. Use "nha browse screenshot", "nha browse extract", etc.');
|
|
272
|
+
info('Or use "nha chat" — browser tools are available in chat.');
|
|
273
|
+
}
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (sub === 'screenshot') {
|
|
278
|
+
const { browserScreenshot, isBrowserRunning } = await import('./services/browser-engine.mjs');
|
|
279
|
+
if (!isBrowserRunning()) {
|
|
280
|
+
fail('No browser open. Run: nha browse open <url>');
|
|
281
|
+
process.exit(1);
|
|
282
|
+
}
|
|
283
|
+
const saveTo = args[1] || path.join(os.homedir(), `nha-screenshot-${Date.now()}.png`);
|
|
284
|
+
info('Capturing screenshot...');
|
|
285
|
+
const result = await browserScreenshot({ saveTo });
|
|
286
|
+
if (result.error) {
|
|
287
|
+
fail(result.message);
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
ok(`Screenshot saved: ${result.savedTo}`);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (sub === 'extract') {
|
|
295
|
+
const { browserExtract, isBrowserRunning } = await import('./services/browser-engine.mjs');
|
|
296
|
+
if (!isBrowserRunning()) {
|
|
297
|
+
fail('No browser open. Run: nha browse open <url>');
|
|
298
|
+
process.exit(1);
|
|
299
|
+
}
|
|
300
|
+
const selector = args[1] || 'body';
|
|
301
|
+
const result = await browserExtract({ selector, mode: 'text' });
|
|
302
|
+
if (result.error) {
|
|
303
|
+
fail(result.message);
|
|
304
|
+
process.exit(1);
|
|
305
|
+
}
|
|
306
|
+
console.log(result.content);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (sub === 'js' && args[1]) {
|
|
311
|
+
const { browserEval, isBrowserRunning } = await import('./services/browser-engine.mjs');
|
|
312
|
+
if (!isBrowserRunning()) {
|
|
313
|
+
fail('No browser open. Run: nha browse open <url>');
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
316
|
+
const code = args.slice(1).join(' ');
|
|
317
|
+
const result = await browserEval(code);
|
|
318
|
+
if (result.error) {
|
|
319
|
+
fail(result.message);
|
|
320
|
+
process.exit(1);
|
|
321
|
+
}
|
|
322
|
+
console.log(result.result);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (sub === 'close') {
|
|
327
|
+
const { browserClose } = await import('./services/browser-engine.mjs');
|
|
328
|
+
const result = await browserClose();
|
|
329
|
+
ok(result.message);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Help
|
|
334
|
+
console.log(`
|
|
335
|
+
${BOLD}${C}NHA Browser${NC} ${D}— Headless Chrome automation${NC}
|
|
336
|
+
|
|
337
|
+
${C}Usage:${NC}
|
|
338
|
+
nha browse open <url> Open a page in headless Chrome
|
|
339
|
+
nha browse screenshot Save screenshot to ~/
|
|
340
|
+
nha browse screenshot out.png Save to specific path
|
|
341
|
+
nha browse extract Extract all text from page
|
|
342
|
+
nha browse extract "h1" Extract text from CSS selector
|
|
343
|
+
nha browse js "code" Execute JavaScript in page
|
|
344
|
+
nha browse close Close the browser
|
|
345
|
+
|
|
346
|
+
${C}In Chat:${NC} All browser tools are available in ${W}nha chat${NC}:
|
|
347
|
+
"Open google.com and search for NHA"
|
|
348
|
+
"Take a screenshot of the page"
|
|
349
|
+
"Click the submit button"
|
|
350
|
+
"Fill the email field with test@example.com"
|
|
351
|
+
"Extract all links from the page"
|
|
352
|
+
|
|
353
|
+
${D}Requires Chrome or Chromium installed. Set CHROME_PATH to override.${NC}
|
|
354
|
+
${D}SSRF-protected — blocks localhost and private IPs.${NC}
|
|
355
|
+
${D}Zero npm dependencies — pure CDP WebSocket.${NC}
|
|
356
|
+
`);
|
|
357
|
+
}
|
|
358
|
+
|
|
250
359
|
// ── nha run ────────────────────────────────────────────────────────────────
|
|
251
360
|
async function cmdRun(args) {
|
|
252
361
|
if (args.length === 0) {
|
|
@@ -568,6 +677,14 @@ function cmdHelp() {
|
|
|
568
677
|
console.log(` run "prompt" Multi-agent collaboration (server-routed)`);
|
|
569
678
|
console.log(` run "prompt" ${D}--agents saber,zero${NC} Collaborate with specific agents\n`);
|
|
570
679
|
|
|
680
|
+
console.log(` ${C}Browser Automation${NC} ${D}(headless Chrome, zero dependencies)${NC}`);
|
|
681
|
+
console.log(` browse open <url> Open page in headless Chrome (CDP)`);
|
|
682
|
+
console.log(` browse screenshot Capture screenshot to file`);
|
|
683
|
+
console.log(` browse extract Extract page text (CSS selector)`);
|
|
684
|
+
console.log(` browse js "code" Execute JavaScript in page`);
|
|
685
|
+
console.log(` browse close Close browser`);
|
|
686
|
+
console.log(` ${D}Also available as tools in nha chat (browser_open, browser_click, etc.)${NC}\n`);
|
|
687
|
+
|
|
571
688
|
console.log(` ${C}Daily Operations${NC} ${D}(Gmail + Calendar + Tasks)${NC}`);
|
|
572
689
|
console.log(` ui Open local web dashboard (http://localhost:3847)`);
|
|
573
690
|
console.log(` ui --lan Access from phone/tablet on the same Wi-Fi`);
|
package/src/commands/chat.mjs
CHANGED
|
@@ -22,7 +22,7 @@ import { AGENTS_DIR, AGENTS } from '../constants.mjs';
|
|
|
22
22
|
import { callLLMStream, parseAgentFile } from '../services/llm.mjs';
|
|
23
23
|
|
|
24
24
|
import { extractMemory } from '../services/memory.mjs';
|
|
25
|
-
import { fail, info, ok, warn, C, G, Y, D, W, BOLD, NC, R } from '../ui.mjs';
|
|
25
|
+
import { fail, info, ok, warn, C, G, Y, D, W, BOLD, NC, R, M } from '../ui.mjs';
|
|
26
26
|
import {
|
|
27
27
|
DESTRUCTIVE_ACTIONS,
|
|
28
28
|
parseActions,
|
|
@@ -433,6 +433,26 @@ function formatToolLabel(action, params) {
|
|
|
433
433
|
return `Searching the web for "${params.query || '...'}"...`;
|
|
434
434
|
case 'fetch_url':
|
|
435
435
|
return `Fetching ${params.url || 'URL'}...`;
|
|
436
|
+
case 'browser_open':
|
|
437
|
+
return `Opening ${params.url || 'page'} in browser...`;
|
|
438
|
+
case 'browser_screenshot':
|
|
439
|
+
return `Taking screenshot...`;
|
|
440
|
+
case 'browser_click':
|
|
441
|
+
return `Clicking ${params.selector || `(${params.x}, ${params.y})`}...`;
|
|
442
|
+
case 'browser_type':
|
|
443
|
+
return `Typing into ${params.selector || 'field'}...`;
|
|
444
|
+
case 'browser_extract':
|
|
445
|
+
return `Extracting content from ${params.selector || 'page'}...`;
|
|
446
|
+
case 'browser_js':
|
|
447
|
+
return `Executing JavaScript...`;
|
|
448
|
+
case 'browser_wait':
|
|
449
|
+
return `Waiting for ${params.selector || 'element'}...`;
|
|
450
|
+
case 'browser_scroll':
|
|
451
|
+
return `Scrolling ${params.direction || 'down'}...`;
|
|
452
|
+
case 'browser_key':
|
|
453
|
+
return `Pressing ${params.key || 'key'}...`;
|
|
454
|
+
case 'browser_close':
|
|
455
|
+
return `Closing browser...`;
|
|
436
456
|
case 'gmail_list':
|
|
437
457
|
return `Searching emails...`;
|
|
438
458
|
case 'gmail_read':
|
|
@@ -476,6 +496,28 @@ function formatToolResult(action, params, result) {
|
|
|
476
496
|
const domain = (params.url || '').replace(/^https?:\/\//, '').split('/')[0];
|
|
477
497
|
return `${C}[Fetched: ${domain}]${NC}`;
|
|
478
498
|
}
|
|
499
|
+
case 'browser_open': {
|
|
500
|
+
const domain = (params.url || '').replace(/^https?:\/\//, '').split('/')[0];
|
|
501
|
+
return `${M}[Browser: ${domain}]${NC}`;
|
|
502
|
+
}
|
|
503
|
+
case 'browser_screenshot':
|
|
504
|
+
return `${M}[Screenshot]${NC}`;
|
|
505
|
+
case 'browser_click':
|
|
506
|
+
return `${M}[Click: ${params.selector || `(${params.x}, ${params.y})`}]${NC}`;
|
|
507
|
+
case 'browser_type':
|
|
508
|
+
return `${M}[Typed: ${(params.text || '').slice(0, 30)}${(params.text || '').length > 30 ? '...' : ''}]${NC}`;
|
|
509
|
+
case 'browser_extract':
|
|
510
|
+
return `${M}[Extracted: ${params.selector || 'page'}]${NC}`;
|
|
511
|
+
case 'browser_js':
|
|
512
|
+
return `${M}[JS executed]${NC}`;
|
|
513
|
+
case 'browser_wait':
|
|
514
|
+
return `${M}[Found: ${params.selector}]${NC}`;
|
|
515
|
+
case 'browser_scroll':
|
|
516
|
+
return `${M}[Scrolled ${params.direction || 'down'}]${NC}`;
|
|
517
|
+
case 'browser_key':
|
|
518
|
+
return `${M}[Key: ${params.key}]${NC}`;
|
|
519
|
+
case 'browser_close':
|
|
520
|
+
return `${M}[Browser closed]${NC}`;
|
|
479
521
|
case 'gmail_list':
|
|
480
522
|
case 'gmail_read':
|
|
481
523
|
case 'gmail_send':
|
package/src/commands/ui.mjs
CHANGED
|
@@ -1164,6 +1164,30 @@ export async function cmdUI(args) {
|
|
|
1164
1164
|
for (const { action, params } of actions) {
|
|
1165
1165
|
sendSSE('tool', { action, status: 'executing' });
|
|
1166
1166
|
try {
|
|
1167
|
+
// For browser_screenshot in web UI: capture and send base64 image
|
|
1168
|
+
if (action === 'browser_screenshot') {
|
|
1169
|
+
const be = await import('../services/browser-engine.mjs');
|
|
1170
|
+
if (!be.isBrowserRunning()) {
|
|
1171
|
+
toolResults.push({ action, result: 'No browser open. Use browser_open first.' });
|
|
1172
|
+
sendSSE('tool', { action, status: 'error', error: 'No browser open' });
|
|
1173
|
+
continue;
|
|
1174
|
+
}
|
|
1175
|
+
const ssResult = await be.browserScreenshot({
|
|
1176
|
+
fullPage: params.fullPage || false,
|
|
1177
|
+
format: params.format || 'png',
|
|
1178
|
+
quality: params.quality,
|
|
1179
|
+
});
|
|
1180
|
+
if (!ssResult.error) {
|
|
1181
|
+
sendSSE('screenshot', { base64: ssResult.base64, format: params.format || 'png' });
|
|
1182
|
+
toolResults.push({ action, result: `Screenshot captured (${Math.round(ssResult.size / 1024)}KB)` });
|
|
1183
|
+
sendSSE('tool', { action, status: 'done', result: 'Screenshot captured' });
|
|
1184
|
+
} else {
|
|
1185
|
+
toolResults.push({ action, result: `Error: ${ssResult.message}` });
|
|
1186
|
+
sendSSE('tool', { action, status: 'error', error: ssResult.message });
|
|
1187
|
+
}
|
|
1188
|
+
continue;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1167
1191
|
const result = await executeTool(action, params, config);
|
|
1168
1192
|
toolResults.push({ action, result: typeof result === 'object' ? JSON.stringify(result) : String(result) });
|
|
1169
1193
|
sendSSE('tool', { action, status: 'done', result: typeof result === 'string' ? result.slice(0, 500) : '' });
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '9.
|
|
8
|
+
export const VERSION = '9.3.1';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|