nothumanallowed 11.0.4 → 11.1.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.1.1",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 53 tools. Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, GitHub, Notion, Slack, voice chat, 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
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 = '11.
|
|
8
|
+
export const VERSION = '11.1.1';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -708,6 +708,61 @@ export async function browserOpen(url, options = {}) {
|
|
|
708
708
|
}
|
|
709
709
|
}
|
|
710
710
|
|
|
711
|
+
// Auto-dismiss cookie/consent banners (best-effort, non-blocking)
|
|
712
|
+
try {
|
|
713
|
+
await browser.ws.send('Runtime.evaluate', {
|
|
714
|
+
expression: `(function() {
|
|
715
|
+
// Common consent banner selectors — covers 90%+ of European sites
|
|
716
|
+
var selectors = [
|
|
717
|
+
// iubenda
|
|
718
|
+
'.iubenda-cs-accept-btn', '#iubenda-cs-banner .iubenda-cs-accept-btn',
|
|
719
|
+
// OneTrust / CookiePro
|
|
720
|
+
'#onetrust-accept-btn-handler', '.onetrust-close-btn-handler',
|
|
721
|
+
// Quantcast / TCF
|
|
722
|
+
'.qc-cmp2-summary-buttons button[mode="primary"]', '.qc-cmp-button',
|
|
723
|
+
// Cookiebot
|
|
724
|
+
'#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll', '#CybotCookiebotDialogBodyButtonAccept',
|
|
725
|
+
// GDPR generic
|
|
726
|
+
'[data-testid="cookie-policy-manage-dialog-btn-accept-all"]',
|
|
727
|
+
'button[data-cookiefirst-action="accept"]',
|
|
728
|
+
'.cc-accept', '.cc-allow', '.cc-dismiss',
|
|
729
|
+
'#cookie-accept', '#accept-cookies', '#acceptCookies',
|
|
730
|
+
'.cookie-accept', '.accept-cookies', '.js-accept-cookies',
|
|
731
|
+
'[aria-label="Accept cookies"]', '[aria-label="Accetta"]', '[aria-label="Accept all"]',
|
|
732
|
+
'[aria-label="Accetta tutti"]', '[aria-label="Accetta tutto"]',
|
|
733
|
+
// Italian sites specific
|
|
734
|
+
'#didomi-notice-agree-button', '.didomi-continue-without-agreeing',
|
|
735
|
+
'.evidon-barrier-acceptall', '#privacy-cp-wall-accept',
|
|
736
|
+
// Generic patterns
|
|
737
|
+
'button[class*="accept"]', 'button[class*="consent"]', 'button[class*="agree"]',
|
|
738
|
+
'button[id*="accept"]', 'button[id*="consent"]',
|
|
739
|
+
// Last resort: buttons with common text
|
|
740
|
+
];
|
|
741
|
+
for (var i = 0; i < selectors.length; i++) {
|
|
742
|
+
var el = document.querySelector(selectors[i]);
|
|
743
|
+
if (el && el.offsetParent !== null) { el.click(); return 'dismissed:' + selectors[i]; }
|
|
744
|
+
}
|
|
745
|
+
// Text-based fallback: find buttons with accept/accetta text
|
|
746
|
+
var buttons = document.querySelectorAll('button, a[role="button"], [class*="btn"]');
|
|
747
|
+
var acceptTexts = ['accetta', 'accept all', 'accept', 'accetto', 'agree', 'ok, ho capito', 'ho capito', 'consenti', 'allow all', 'allow', 'got it', 'i agree', 'continua', 'prosegui'];
|
|
748
|
+
for (var j = 0; j < buttons.length; j++) {
|
|
749
|
+
var txt = (buttons[j].textContent || '').trim().toLowerCase();
|
|
750
|
+
if (txt.length > 1 && txt.length < 40) {
|
|
751
|
+
for (var k = 0; k < acceptTexts.length; k++) {
|
|
752
|
+
if (txt === acceptTexts[k] || txt.startsWith(acceptTexts[k])) {
|
|
753
|
+
buttons[j].click(); return 'dismissed-text:' + txt;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return 'no-banner-found';
|
|
759
|
+
})()`,
|
|
760
|
+
returnByValue: true,
|
|
761
|
+
});
|
|
762
|
+
// Wait for banner animation to finish
|
|
763
|
+
await new Promise(r => setTimeout(r, 300));
|
|
764
|
+
} catch { /* banner dismiss failed — non-critical */ }
|
|
765
|
+
|
|
711
766
|
return {
|
|
712
767
|
error: false,
|
|
713
768
|
title: titleResult.result?.value || '',
|
|
@@ -393,6 +393,7 @@ RULES:
|
|
|
393
393
|
- The user's timezone is {{TIMEZONE}}.
|
|
394
394
|
- CRITICAL: when creating calendar events, always use LOCAL time in format "YYYY-MM-DDTHH:MM:SS" WITHOUT any Z suffix or timezone offset.
|
|
395
395
|
- LANGUAGE: Respond in {{LANGUAGE}}. All conversational text, explanations, and descriptions must be in {{LANGUAGE}}. Tool names and JSON blocks remain in English.
|
|
396
|
+
- BROWSER TIP: Cookie/consent banners are auto-dismissed when a page loads. Do NOT waste time clicking cookie buttons — the browser handles it automatically.
|
|
396
397
|
- BROWSER TIP: When extracting data from a page, prefer browser_js with code "document.body.innerText.slice(0, 3000)" to get all visible text. This is more reliable than guessing CSS selectors.
|
|
397
398
|
- API TIP: For npm package info, use fetch_url with the registry API: fetch_url("https://registry.npmjs.org/PACKAGE/latest") for version/description, and fetch_url("https://api.npmjs.org/downloads/point/last-week/PACKAGE") for weekly downloads. These are JSON APIs, much more reliable than scraping the npm website.
|
|
398
399
|
`.trim();
|
|
@@ -1180,7 +1181,11 @@ export async function executeTool(action, params, config) {
|
|
|
1180
1181
|
const result = await be.browserOpen(url, {
|
|
1181
1182
|
waitForLoad: params.waitForLoad !== false,
|
|
1182
1183
|
});
|
|
1183
|
-
if (result.error)
|
|
1184
|
+
if (result.error) {
|
|
1185
|
+
// Navigate to blank to prevent stale screenshots from previous page
|
|
1186
|
+
try { await be.browserOpen('about:blank', { waitForLoad: false }); } catch {}
|
|
1187
|
+
return `Browser error: ${result.message}`;
|
|
1188
|
+
}
|
|
1184
1189
|
|
|
1185
1190
|
return `Page loaded: "${result.title}"\nURL: ${result.url}`;
|
|
1186
1191
|
}
|
|
@@ -1189,6 +1194,12 @@ export async function executeTool(action, params, config) {
|
|
|
1189
1194
|
const be = await import('./browser-engine.mjs');
|
|
1190
1195
|
if (!be.isBrowserRunning()) return 'No browser open. Use browser_open first.';
|
|
1191
1196
|
|
|
1197
|
+
// Check current URL — don't screenshot blank or error pages
|
|
1198
|
+
const currentInfo = await be.browserInfo();
|
|
1199
|
+
if (currentInfo.url === 'about:blank' || !currentInfo.url || currentInfo.url === '') {
|
|
1200
|
+
return 'No page loaded in browser. Use browser_open to navigate to a page first.';
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1192
1203
|
// Scroll to top before screenshot so user sees the most important content
|
|
1193
1204
|
await be.browserScroll({ direction: 'top' });
|
|
1194
1205
|
await new Promise(r => setTimeout(r, 300));
|