nothumanallowed 9.2.3 → 9.3.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/README.md +96 -21
- package/bin/nha.mjs +4 -2
- package/package.json +2 -2
- package/src/cli.mjs +136 -1
- 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 +20 -3
package/README.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
# NotHumanAllowed
|
|
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
|
+
|
|
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
|
+
|
|
9
|
+
100% private — your data never leaves your machine. Zero data on our servers. Free and open source.
|
|
6
10
|
|
|
7
11
|
## Install
|
|
8
12
|
|
|
@@ -22,13 +26,13 @@ nha config set key sk-ant-api03-YOUR_KEY
|
|
|
22
26
|
# Connect Google (Gmail, Calendar, Drive, Contacts, Tasks)
|
|
23
27
|
nha google auth
|
|
24
28
|
|
|
25
|
-
# Start chatting —
|
|
29
|
+
# Start chatting — 58 tools available
|
|
26
30
|
nha chat
|
|
27
31
|
```
|
|
28
32
|
|
|
29
33
|
## What You Can Do
|
|
30
34
|
|
|
31
|
-
### Chat with
|
|
35
|
+
### Chat with 58 Tools + Web Search + Browser
|
|
32
36
|
|
|
33
37
|
```bash
|
|
34
38
|
nha chat
|
|
@@ -58,7 +62,34 @@ NHA: Available 60-min slots:
|
|
|
58
62
|
3. Wed Apr 9, 02:00 PM - 04:00 PM
|
|
59
63
|
```
|
|
60
64
|
|
|
61
|
-
###
|
|
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
|
|
62
93
|
|
|
63
94
|
| Category | Tools |
|
|
64
95
|
|----------|-------|
|
|
@@ -71,6 +102,7 @@ NHA: Available 60-min slots:
|
|
|
71
102
|
| **Slack** | List channels, read messages, send messages |
|
|
72
103
|
| **Notion** | Search pages/databases, read page content |
|
|
73
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 |
|
|
74
106
|
| **Other** | Maps directions, reminders, file reading |
|
|
75
107
|
|
|
76
108
|
Every tool is called directly from your machine to the provider's API. NHA servers are never involved.
|
|
@@ -105,7 +137,7 @@ nha ask jarvis "Build a REST API for user management"
|
|
|
105
137
|
nha voice
|
|
106
138
|
```
|
|
107
139
|
|
|
108
|
-
Same
|
|
140
|
+
Same 58 tools, spoken responses. Opens a local web UI with speech recognition.
|
|
109
141
|
|
|
110
142
|
### Background Daemon
|
|
111
143
|
|
|
@@ -185,19 +217,21 @@ Runs in the background. Alerts you before meetings, monitors email, auto-respond
|
|
|
185
217
|
|
|
186
218
|
Run `nha agents` to see all 38 with capabilities.
|
|
187
219
|
|
|
188
|
-
## Android App
|
|
220
|
+
## Android App (v1.2)
|
|
189
221
|
|
|
190
|
-
|
|
222
|
+
Download: [nothumanallowed.com/NHAapp-1.2.apk](https://nothumanallowed.com/NHAapp-1.2.apk)
|
|
191
223
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
-
|
|
199
|
-
- Voice chat
|
|
200
|
-
- Daily plan
|
|
224
|
+
Everything the CLI does, on your phone:
|
|
225
|
+
|
|
226
|
+
- **Streaming chat** — see words appear as the AI thinks
|
|
227
|
+
- **Web search** — search the internet and read any webpage, right from chat
|
|
228
|
+
- **Multiple conversations** — save, switch, export your chats
|
|
229
|
+
- **58 tools** — email, calendar, tasks, contacts, Drive, GitHub, Slack, Notion, browser
|
|
230
|
+
- **38 agents** — tap any agent, ask anything
|
|
231
|
+
- **Voice chat** — talk instead of typing, in 6 languages
|
|
232
|
+
- **Daily plan** — AI analyzes your emails + calendar every morning
|
|
233
|
+
- **Files & images** — attach PDFs, photos, documents for analysis
|
|
234
|
+
- **Tool indicators** — see "Searching the web...", "Reading email..." in real time
|
|
201
235
|
|
|
202
236
|
All API calls go directly from your phone to providers. Zero data through NHA servers.
|
|
203
237
|
|
|
@@ -217,7 +251,7 @@ All API calls go directly from your phone to providers. Zero data through NHA se
|
|
|
217
251
|
Your Machine Provider APIs
|
|
218
252
|
┌──────────────────┐ ┌─────────────────────┐
|
|
219
253
|
│ 38 agents │────→│ Google (Gmail, Cal, │
|
|
220
|
-
│
|
|
254
|
+
│ 58 tools │ │ Drive, Contacts) │
|
|
221
255
|
│ Your API keys │────→│ Your LLM provider │
|
|
222
256
|
│ Your data │────→│ GitHub, Slack, Notion│
|
|
223
257
|
│ (encrypted) │ └─────────────────────┘
|
|
@@ -250,6 +284,13 @@ Inside `nha chat`, use slash commands:
|
|
|
250
284
|
/clear Clear current conversation
|
|
251
285
|
/help Show all commands
|
|
252
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
|
|
253
294
|
```
|
|
254
295
|
|
|
255
296
|
Inline agent routing: `@saber audit this function for SQL injection`
|
|
@@ -257,7 +298,7 @@ Inline agent routing: `@saber audit this function for SQL injection`
|
|
|
257
298
|
## Commands
|
|
258
299
|
|
|
259
300
|
```bash
|
|
260
|
-
# Chat (
|
|
301
|
+
# Chat (58 tools + web search, streaming)
|
|
261
302
|
nha chat # Interactive chat with tools
|
|
262
303
|
nha voice # Voice chat with TTS
|
|
263
304
|
|
|
@@ -275,6 +316,13 @@ nha ops start # Background daemon
|
|
|
275
316
|
# Google
|
|
276
317
|
nha google auth # Connect Google account
|
|
277
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
|
+
|
|
278
326
|
# Config
|
|
279
327
|
nha config # Show settings
|
|
280
328
|
nha config set provider anthropic # Set LLM provider
|
|
@@ -284,12 +332,39 @@ nha doctor # Health check
|
|
|
284
332
|
nha mcp # Start MCP server
|
|
285
333
|
```
|
|
286
334
|
|
|
335
|
+
## Web Dashboard
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
nha ui
|
|
339
|
+
```
|
|
340
|
+
|
|
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.
|
|
342
|
+
|
|
343
|
+
## NHA vs OpenClaw
|
|
344
|
+
|
|
345
|
+
NHA was built after the [OpenClaw/Moltbook security breach](https://nothumanallowed.com/vs-openclaw) — 7 CVEs, 1.49M leaked records, 1.5M exposed API keys. See the [full comparison](https://nothumanallowed.com/vs-openclaw).
|
|
346
|
+
|
|
347
|
+
| | OpenClaw | NHA |
|
|
348
|
+
|---|---|---|
|
|
349
|
+
| Security | 7 CVEs, no WAF | SENTINEL WAF (Rust), 0 CVEs |
|
|
350
|
+
| Agents | 1 generic | 38 specialists |
|
|
351
|
+
| Tools | Install from hub | 58 built-in + web search + browser automation |
|
|
352
|
+
| Knowledge | None | 2.6M facts from 16 datasets |
|
|
353
|
+
| Daily Plan | None | 5-agent analysis |
|
|
354
|
+
| Browser | Chrome instance (heavy, attack surface) | Custom CDP engine, zero deps, SSRF-protected |
|
|
355
|
+
| Dependencies | Electron + Chrome | Zero |
|
|
356
|
+
| Privacy | Moltbook leaked 1.49M records | Zero data on our servers |
|
|
357
|
+
|
|
287
358
|
## Links
|
|
288
359
|
|
|
289
360
|
- [Website](https://nothumanallowed.com)
|
|
290
361
|
- [Documentation](https://nothumanallowed.com/docs/cli)
|
|
362
|
+
- [Android App](https://nothumanallowed.com/NHAapp-1.2.apk)
|
|
363
|
+
- [NHA vs OpenClaw](https://nothumanallowed.com/vs-openclaw)
|
|
364
|
+
- [Agents Guide](https://nothumanallowed.com/docs/agents)
|
|
365
|
+
- [Mobile Docs](https://nothumanallowed.com/docs/mobile)
|
|
366
|
+
- [GitHub](https://github.com/adoslabsproject-gif/nothumanallowed)
|
|
291
367
|
- [Privacy Policy](https://nothumanallowed.com/privacy)
|
|
292
|
-
- [Terms of Service](https://nothumanallowed.com/terms)
|
|
293
368
|
|
|
294
369
|
## License
|
|
295
370
|
|
package/bin/nha.mjs
CHANGED
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.0",
|
|
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
|
@@ -22,6 +22,22 @@ import { cmdVoice } from './commands/voice.mjs';
|
|
|
22
22
|
import { cmdPlugin, findPluginForCommand } from './commands/plugin.mjs';
|
|
23
23
|
import { banner, info, ok, warn, fail, C, G, Y, D, W, BOLD, NC, M, B, R } from './ui.mjs';
|
|
24
24
|
|
|
25
|
+
// Show web UI tip once after first real command
|
|
26
|
+
export function showUiTipOnce(cmd) {
|
|
27
|
+
const skipCmds = ['ui', 'help', 'version', 'setup', 'update', 'config', 'doctor', '--help', '-h'];
|
|
28
|
+
if (skipCmds.includes(cmd)) return;
|
|
29
|
+
try {
|
|
30
|
+
const marker = path.join(NHA_DIR, '.ui-tip-shown');
|
|
31
|
+
if (fs.existsSync(marker)) return;
|
|
32
|
+
console.log('');
|
|
33
|
+
console.log(` ${G}Tip:${NC} Run ${C}nha ui${NC} to open the full web dashboard in your browser.`);
|
|
34
|
+
console.log(` Use ${C}nha ui --lan${NC} to access it from your phone or tablet on the same Wi-Fi.`);
|
|
35
|
+
console.log(` ${D}Docs: https://nothumanallowed.com/docs/web-dashboard${NC}`);
|
|
36
|
+
fs.mkdirSync(NHA_DIR, { recursive: true });
|
|
37
|
+
fs.writeFileSync(marker, new Date().toISOString());
|
|
38
|
+
} catch {}
|
|
39
|
+
}
|
|
40
|
+
|
|
25
41
|
export async function main(argv) {
|
|
26
42
|
const cmd = argv[0] || 'help';
|
|
27
43
|
const args = argv.slice(1);
|
|
@@ -112,6 +128,10 @@ export async function main(argv) {
|
|
|
112
128
|
case 'voice':
|
|
113
129
|
return cmdVoice(args);
|
|
114
130
|
|
|
131
|
+
case 'browse':
|
|
132
|
+
case 'browser':
|
|
133
|
+
return cmdBrowse(args);
|
|
134
|
+
|
|
115
135
|
case 'plugin':
|
|
116
136
|
case 'plugins':
|
|
117
137
|
return cmdPlugin(args);
|
|
@@ -161,6 +181,7 @@ export async function main(argv) {
|
|
|
161
181
|
return spawnCore('legion', [cmd, ...args]);
|
|
162
182
|
}
|
|
163
183
|
}
|
|
184
|
+
|
|
164
185
|
}
|
|
165
186
|
|
|
166
187
|
// ── nha responder ─────────────────────────────────────────────────────────
|
|
@@ -230,6 +251,111 @@ async function cmdResponder(args) {
|
|
|
230
251
|
}
|
|
231
252
|
}
|
|
232
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
|
+
|
|
233
359
|
// ── nha run ────────────────────────────────────────────────────────────────
|
|
234
360
|
async function cmdRun(args) {
|
|
235
361
|
if (args.length === 0) {
|
|
@@ -551,8 +677,17 @@ function cmdHelp() {
|
|
|
551
677
|
console.log(` run "prompt" Multi-agent collaboration (server-routed)`);
|
|
552
678
|
console.log(` run "prompt" ${D}--agents saber,zero${NC} Collaborate with specific agents\n`);
|
|
553
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
|
+
|
|
554
688
|
console.log(` ${C}Daily Operations${NC} ${D}(Gmail + Calendar + Tasks)${NC}`);
|
|
555
|
-
console.log(` ui Open local web dashboard (http://
|
|
689
|
+
console.log(` ui Open local web dashboard (http://localhost:3847)`);
|
|
690
|
+
console.log(` ui --lan Access from phone/tablet on the same Wi-Fi`);
|
|
556
691
|
console.log(` ui --port=4000 Custom port ui --no-browser Don't auto-open`);
|
|
557
692
|
console.log(` chat Interactive chat — manage email/calendar/tasks naturally`);
|
|
558
693
|
console.log(` voice Voice-powered chat (opens browser with mic interface)`);
|
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.0';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|