nothumanallowed 13.5.61 → 13.5.63
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 +1 -1
- package/src/commands/ui.mjs +29 -1
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +20 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.63",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -4110,6 +4110,32 @@ ${completedHeadings ? `## SECTIONS ALREADY WRITTEN (headings only):\n${completed
|
|
|
4110
4110
|
sendLog(` ✓ ${f.name}`);
|
|
4111
4111
|
}
|
|
4112
4112
|
|
|
4113
|
+
// Post-process HTML files: remove meta tags that break HTTP iframe sandbox
|
|
4114
|
+
// (Strict-Transport-Security, X-Frame-Options, frame-ancestors CSP meta)
|
|
4115
|
+
// This is system-level sanitization — the generated project code is NOT modified
|
|
4116
|
+
// by hand; the sandbox shim layer strips incompatible production-only headers.
|
|
4117
|
+
const htmlFiles = files.filter(function(f) { return f.name.endsWith('.html'); });
|
|
4118
|
+
if (htmlFiles.length > 0) {
|
|
4119
|
+
sendLog('🔧 Sanitizzazione meta tag sandbox...');
|
|
4120
|
+
for (const f of htmlFiles) {
|
|
4121
|
+
const fp = path.join(sandboxDir, f.name);
|
|
4122
|
+
let html = fs.readFileSync(fp, 'utf8');
|
|
4123
|
+
const before = html.length;
|
|
4124
|
+
// Remove Strict-Transport-Security meta (forces HTTPS, breaks HTTP sandbox)
|
|
4125
|
+
html = html.replace(/<meta[^>]+Strict-Transport-Security[^>]*>/gi, '');
|
|
4126
|
+
// Remove X-Frame-Options meta (blocks iframe embedding)
|
|
4127
|
+
html = html.replace(/<meta[^>]+X-Frame-Options[^>]*>/gi, '');
|
|
4128
|
+
// Remove Content-Security-Policy meta http-equiv (server sets it via helmet with sandbox-safe values)
|
|
4129
|
+
html = html.replace(/<meta[^>]+http-equiv=["']Content-Security-Policy["'][^>]*>/gi, '');
|
|
4130
|
+
// Remove frame-ancestors none/self directives from any remaining CSP meta
|
|
4131
|
+
html = html.replace(/<meta[^>]+content=["'][^"']*frame-ancestors[^"']*["'][^>]*>/gi, '');
|
|
4132
|
+
if (html.length !== before) {
|
|
4133
|
+
fs.writeFileSync(fp, html, 'utf8');
|
|
4134
|
+
sendLog(' ✓ ' + f.name + ' (meta tag produzione rimossi)');
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
|
|
4113
4139
|
// Inject sandbox db shim — replaces pg with in-memory SQLite-like store
|
|
4114
4140
|
const dbShim = `
|
|
4115
4141
|
// NHA WebCraft Sandbox DB Shim
|
|
@@ -4690,7 +4716,9 @@ REGOLE CRITICHE:
|
|
|
4690
4716
|
content = content.replace(toolCall.old, toolCall.new);
|
|
4691
4717
|
fs.writeFileSync(fp, content, 'utf8');
|
|
4692
4718
|
toolResults.push({ op: 'edit', path: toolCall.path, ok: true });
|
|
4693
|
-
sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'ok'
|
|
4719
|
+
sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'ok',
|
|
4720
|
+
oldSnippet: (toolCall.old || '').slice(0, 300),
|
|
4721
|
+
newSnippet: (toolCall.new || '').slice(0, 300) });
|
|
4694
4722
|
} else {
|
|
4695
4723
|
sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'old_string non trovato — patch fallita' });
|
|
4696
4724
|
}
|
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 = '13.5.
|
|
8
|
+
export const VERSION = '13.5.62';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -6989,6 +6989,7 @@ function wcChatPanelHtml() {
|
|
|
6989
6989
|
}).join('') + '</div>';
|
|
6990
6990
|
}
|
|
6991
6991
|
} else {
|
|
6992
|
+
var diffBlocks = '';
|
|
6992
6993
|
var toolBadges = (msg.tools || []).map(function(tool){
|
|
6993
6994
|
var isOk = tool.result === 'ok';
|
|
6994
6995
|
var isParseErr = tool.op === 'parse_error';
|
|
@@ -6996,6 +6997,17 @@ function wcChatPanelHtml() {
|
|
|
6996
6997
|
var color = isOk ? 'var(--green)' : 'var(--red)';
|
|
6997
6998
|
var label = isParseErr ? ('JSON err: ' + wcEsc(tool.result)) : wcEsc(tool.path);
|
|
6998
6999
|
var title = isOk ? tool.op + ': ' + tool.path : (tool.result || '');
|
|
7000
|
+
// Build inline diff block for successful edits
|
|
7001
|
+
if (isOk && tool.op === 'edit' && tool.oldSnippet) {
|
|
7002
|
+
var oldLines = tool.oldSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#3f0f0f;color:#fca5a5;font-family:var(--mono);font-size:9px;padding:0 8px;white-space:pre-wrap;word-break:break-all">- '+wcEsc(l)+'</div>'; }).join('');
|
|
7003
|
+
var newLines = tool.newSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#0f2f0f;color:#86efac;font-family:var(--mono);font-size:9px;padding:0 8px;white-space:pre-wrap;word-break:break-all">+ '+wcEsc(l)+'</div>'; }).join('');
|
|
7004
|
+
diffBlocks += '<details style="margin:2px 0;border:1px solid rgba(255,255,255,0.08);border-radius:5px;overflow:hidden">' +
|
|
7005
|
+
'<summary style="padding:3px 8px;font-size:9px;font-family:var(--mono);color:var(--dim);cursor:pointer;list-style:none;display:flex;align-items:center;gap:4px">' +
|
|
7006
|
+
'<span style="color:var(--green)">✎</span> '+wcEsc(tool.path)+' <span style="margin-left:auto;opacity:.5">▼</span>' +
|
|
7007
|
+
'</summary>' +
|
|
7008
|
+
oldLines + newLines +
|
|
7009
|
+
'</details>';
|
|
7010
|
+
}
|
|
6999
7011
|
return '<span title="'+wcEsc(title)+'" style="display:inline-flex;align-items:center;gap:3px;background:var(--bg3);border:1px solid '+(isOk?'var(--green3)':'var(--red)')+';border-radius:4px;padding:2px 6px;font-size:9px;font-family:var(--mono);color:'+color+'">' +
|
|
7000
7012
|
icon + ' ' + label + '</span>';
|
|
7001
7013
|
}).join(' ');
|
|
@@ -7006,6 +7018,7 @@ function wcChatPanelHtml() {
|
|
|
7006
7018
|
'<span style="font-size:10px;font-weight:700;color:var(--green)">WebCraft Agent</span>' +
|
|
7007
7019
|
'</div>' +
|
|
7008
7020
|
'<div style="padding:8px 10px;font-size:11px;color:var(--text);line-height:1.6;white-space:pre-wrap">'+agentText+'</div>' +
|
|
7021
|
+
(diffBlocks ? '<div style="padding:4px 8px 6px;border-top:1px solid rgba(255,255,255,0.06)">'+diffBlocks+'</div>' : '') +
|
|
7009
7022
|
(toolBadges ? '<div style="display:flex;flex-wrap:wrap;gap:4px;padding:6px 10px;border-top:1px solid rgba(255,255,255,0.06)">'+toolBadges+'</div>' : '') +
|
|
7010
7023
|
'</div>';
|
|
7011
7024
|
}
|
|
@@ -7190,7 +7203,7 @@ async function wcExecuteAgentCall(message, isPlanExec, planOrigMsg, attachments)
|
|
|
7190
7203
|
if (typingEl) typingEl.textContent = '...';
|
|
7191
7204
|
wcScrollChatToBottom();
|
|
7192
7205
|
} else if (ev.type === 'tool') {
|
|
7193
|
-
agentMsg.tools.push({ op: ev.op, path: ev.path, result: ev.result });
|
|
7206
|
+
agentMsg.tools.push({ op: ev.op, path: ev.path, result: ev.result, oldSnippet: ev.oldSnippet || '', newSnippet: ev.newSnippet || '' });
|
|
7194
7207
|
if ((ev.op === 'edit' || ev.op === 'write') && ev.result === 'ok') {
|
|
7195
7208
|
anyEdits = true;
|
|
7196
7209
|
wcChat[wcChat.length-1] = agentMsg;
|
|
@@ -7310,7 +7323,7 @@ async function wcTriggerAutoFix(missingModule) {
|
|
|
7310
7323
|
try {
|
|
7311
7324
|
var ev2 = JSON.parse(line2);
|
|
7312
7325
|
if (ev2.type === 'text') { agentMsg.text += ev2.token; }
|
|
7313
|
-
else if (ev2.type === 'tool') { agentMsg.tools.push({ op: ev2.op, path: ev2.path, result: ev2.result }); }
|
|
7326
|
+
else if (ev2.type === 'tool') { agentMsg.tools.push({ op: ev2.op, path: ev2.path, result: ev2.result, oldSnippet: ev2.oldSnippet || '', newSnippet: ev2.newSnippet || '' }); }
|
|
7314
7327
|
else if (ev2.type === 'done') { wcChatRunning = false; if (ev2.changed) { wcReloadProjectFiles(); } }
|
|
7315
7328
|
else if (ev2.type === 'restart_sandbox') { wcStartSandbox(); }
|
|
7316
7329
|
else if (ev2.type === 'error') { agentMsg.text += String.fromCharCode(10)+'Errore: '+ev2.msg; wcChatRunning = false; }
|
|
@@ -7637,7 +7650,7 @@ async function wcGenerate() {
|
|
|
7637
7650
|
|
|
7638
7651
|
// Security rules always injected
|
|
7639
7652
|
var SECURITY_RULES = [
|
|
7640
|
-
'ALWAYS use security headers
|
|
7653
|
+
'ALWAYS use security headers via Express/helmet server-side only. NEVER add X-Frame-Options, Strict-Transport-Security, frame-ancestors, or Content-Security-Policy as HTML meta http-equiv tags — the app runs inside an HTTP iframe sandbox and these meta tags will break resource loading. Only allowed HTML security meta: viewport, charset, X-UA-Compatible, Permissions-Policy.',
|
|
7641
7654
|
'NEVER put secrets, API keys, or DB credentials in frontend code. Only in .env server-side.',
|
|
7642
7655
|
'ALWAYS use prepared statements / parameterized queries. NEVER string-concatenate SQL.',
|
|
7643
7656
|
'ALWAYS hash passwords with bcrypt (cost factor 12+). NEVER store plain passwords.',
|
|
@@ -7657,7 +7670,7 @@ async function wcGenerate() {
|
|
|
7657
7670
|
{ name: 'package.json', lang: 'json', prompt: 'Generate package.json for an Express/PostgreSQL project named "'+projName+'". Dependencies: express, pg, bcryptjs, jsonwebtoken, nodemailer, helmet, express-rate-limit, cors, dotenv, express-validator, ioredis. DevDependencies: nodemon. Scripts: start, dev.' },
|
|
7658
7671
|
{ name: '.env.example', lang: 'bash', prompt: 'Generate .env.example with all required env vars: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASS, JWT_SECRET, JWT_REFRESH_SECRET, SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM, SENDGRID_API_KEY (commented as optional fallback), REDIS_URL (default redis://localhost:6379, works with Dragonfly too), PORT, NODE_ENV, CORS_ORIGIN, BASE_URL. Add helpful comments for each. Note that REDIS_URL is optional — app falls back to in-memory LRU if Redis unavailable.' },
|
|
7659
7672
|
{ name: 'server/db.js', lang: 'javascript', prompt: 'Generate server/db.js: pg.Pool singleton (max:10, idleTimeoutMillis:30000, connectionTimeoutMillis:2000). Circuit breaker: if DB fails 5+ times in 60s, open circuit (throw immediately) for 30s, then half-open (try one query). Export pool, query(text, params) with circuit breaker, transaction(callback) helper (BEGIN/COMMIT/ROLLBACK). Graceful shutdown on SIGTERM/SIGINT.' },
|
|
7660
|
-
{ name: 'server/middleware/security.js', lang: 'javascript', prompt: 'Generate server/middleware/security.js:
|
|
7673
|
+
{ name: 'server/middleware/security.js', lang: 'javascript', prompt: 'Generate server/middleware/security.js: detect sandbox via isSandbox = !process.env.NODE_ENV || process.env.NODE_ENV === "development". Use helmet CSP: defaultSrc self, scriptSrc self unsafe-inline, styleSrc self unsafe-inline, imgSrc self data:, connectSrc self, objectSrc none. frameAncestors: if isSandbox use ["self", "http://127.0.0.1:*", "http://localhost:*"] else ["none"]. NO X-Frame-Options DENY (conflicts with frameAncestors). NO HSTS in sandbox (HTTP only). Referrer-Policy strict-origin-when-cross-origin. Add express-rate-limit for general routes (100/15min) and strict limiter for auth (5/15min). Export { applySecurityMiddleware, authLimiter }.' },
|
|
7661
7674
|
{ name: 'server/middleware/validate.js', lang: 'javascript', prompt: 'Generate server/middleware/validate.js using express-validator. Export handleValidationErrors middleware. Export auth field validators: registerValidator (fields: '+authFieldsDef+'), loginValidator (email + password).' },
|
|
7662
7675
|
{ name: 'server/services/email.js', lang: 'javascript', prompt: 'Generate server/services/email.js: Nodemailer transporter using SMTP from env. Function sendVerificationEmail(to, token, baseUrl): sends HTML email with verification link. Function sendPasswordResetEmail(to, token, baseUrl). Add SendGrid fallback (commented out, predisposed with transporter swap). Never expose credentials.' },
|
|
7663
7676
|
{ name: 'server/routes/auth.js', lang: 'javascript', prompt: 'Generate server/routes/auth.js: POST /register (validate fields: '+authFieldsDef+', check duplicate email, bcrypt hash password cost 12, insert user, send verification email, return 201), POST /login (validate, check email verified, compare bcrypt, issue JWT access 15min + refresh 7d httpOnly cookie), POST /logout (clear refresh cookie), POST /refresh-token (validate refresh from httpOnly cookie, rotate token), GET /verify-email/:token (mark email verified). Use parameterized queries only. Apply authLimiter to register and login.' },
|
|
@@ -7668,9 +7681,9 @@ async function wcGenerate() {
|
|
|
7668
7681
|
{ name: 'public/css/components.css', lang: 'css', prompt: 'Generate public/css/components.css following STRICT BEM (block__element--modifier). Components: .btn (--primary, --secondary, --danger, --ghost), .form (form__field, form__label, form__input, form__error, form__hint), .card (card__header, card__body, card__footer), .nav (nav__brand, nav__links, nav__link--active), .alert (--success, --error, --warning, --info), .spinner, .badge, .modal (modal__overlay, modal__content, modal__header, modal__body, modal__footer). Fully accessible (focus states, aria).' },
|
|
7669
7682
|
{ name: 'public/css/pages.css', lang: 'css', prompt: 'Generate public/css/pages.css: page-level layout classes using BEM. .page-auth (centered card layout for login/register), .page-dashboard (sidebar + content grid), .page-landing (hero section, features grid, pricing cards). Responsive at 768px and 480px breakpoints.' },
|
|
7670
7683
|
{ name: 'public/js/main.js', lang: 'javascript', prompt: 'Generate public/js/main.js: vanilla JS, no dependencies. authAPI object with methods register(data), login(data), logout(), refreshToken(), getMe(). Cookie banner controller: reads localStorage consent, shows banner if not set, sets consent by category (necessary/analytics/marketing). Form handlers for register and login pages. Global error display utility. Export nothing (IIFE).' },
|
|
7671
|
-
{ name: 'public/index.html', lang: 'html', prompt: 'Generate public/index.html for "'+projName+'": '+desc+'. Full HTML5. Security meta tags
|
|
7672
|
-
{ name: 'public/login.html', lang: 'html', prompt: 'Generate public/login.html: login page for "'+projName+'". Form with email + password fields using .form BEM classes. Link to register.html. Error display area. Include same CSS files. ARIA labels, autocomplete attributes.' },
|
|
7673
|
-
{ name: 'public/register.html', lang: 'html', prompt: 'Generate public/register.html: registration page for "'+projName+'". Form fields: '+authFieldsDef+'. Use .form BEM classes. Client-side validation hints. Link to login.html. Error/success display. Include same CSS files. ARIA labels, autocomplete attributes.' },
|
|
7684
|
+
{ name: 'public/index.html', lang: 'html', prompt: 'Generate public/index.html for "'+projName+'": '+desc+'. Full HTML5. IMPORTANT: do NOT add X-Frame-Options, Strict-Transport-Security, or frame-ancestors meta tags — the app runs in an iframe sandbox on HTTP localhost and these will break it. Only add: X-UA-Compatible IE=edge, viewport, charset, Permissions-Policy (geolocation=(), microphone=(), camera=()). Include base.css, components.css, pages.css. GDPR cookie banner HTML (class .cookie-banner, .cookie-banner__text, .cookie-banner__actions, .cookie-banner__btn--accept, .cookie-banner__btn--reject). Navigation. Hero section. Include main.js at end of body. Semantic HTML, ARIA roles, lang attribute.' },
|
|
7685
|
+
{ name: 'public/login.html', lang: 'html', prompt: 'Generate public/login.html: login page for "'+projName+'". Form with email + password fields using .form BEM classes. Link to register.html. Error display area. Include same CSS files. ARIA labels, autocomplete attributes. Do NOT add X-Frame-Options or Strict-Transport-Security meta tags.' },
|
|
7686
|
+
{ name: 'public/register.html', lang: 'html', prompt: 'Generate public/register.html: registration page for "'+projName+'". Form fields: '+authFieldsDef+'. Use .form BEM classes. Client-side validation hints. Link to login.html. Error/success display. Include same CSS files. ARIA labels, autocomplete attributes. Do NOT add X-Frame-Options or Strict-Transport-Security meta tags.' },
|
|
7674
7687
|
{ name: 'server/middleware/sentinel.js', lang: 'javascript', prompt: 'Generate server/middleware/sentinel.js: a lightweight WAF middleware for Express. Check request for: SQL injection patterns (UNION SELECT, DROP TABLE, etc.), XSS patterns (<script, javascript:, onerror=), path traversal (../), oversized payloads (>100KB body). Rate limit by IP using an in-memory sliding window (fallback when Redis unavailable). Log blocked requests with IP, method, path, reason to stderr. Export sentinelMiddleware(req, res, next).' },
|
|
7675
7688
|
{ name: 'server/services/cache.js', lang: 'javascript', prompt: 'Generate server/services/cache.js: Redis/Dragonfly client using ioredis. Connect to REDIS_URL from env. Export: get(key), set(key, value, ttlSeconds), del(key), exists(key). Add circuit breaker pattern: if Redis fails 3+ times in 30s, switch to in-memory LRU fallback (Map with max 1000 entries, LRU eviction). Reconnect Redis in background every 60s. Log circuit state changes. This makes the app resilient when Redis is down.' },
|
|
7676
7689
|
{ name: 'README.md', lang: 'markdown', prompt: 'Generate README.md for "'+projName+'": project description, tech stack (Express, PostgreSQL with circuit breaker, Redis/Dragonfly with LRU fallback, JWT auth, Nodemailer SMTP + SendGrid fallback, Sentinel WAF, BEM CSS), folder structure, setup instructions (clone, npm install, copy .env.example to .env, run migrations with psql, optional: start Redis/Dragonfly, npm run dev), environment variables table (including REDIS_URL), API endpoints table, security notes, email configuration guide.' },
|