nothumanallowed 13.5.61 → 13.5.62

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": "13.5.61",
3
+ "version": "13.5.62",
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": {
@@ -4690,7 +4690,9 @@ REGOLE CRITICHE:
4690
4690
  content = content.replace(toolCall.old, toolCall.new);
4691
4691
  fs.writeFileSync(fp, content, 'utf8');
4692
4692
  toolResults.push({ op: 'edit', path: toolCall.path, ok: true });
4693
- sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'ok' });
4693
+ sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'ok',
4694
+ oldSnippet: (toolCall.old || '').slice(0, 300),
4695
+ newSnippet: (toolCall.new || '').slice(0, 300) });
4694
4696
  } else {
4695
4697
  sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'old_string non trovato — patch fallita' });
4696
4698
  }
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.61';
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
 
@@ -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)">&#9998;</span> '+wcEsc(tool.path)+' <span style="margin-left:auto;opacity:.5">&#9660;</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: X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy: geolocation=(), microphone=(), camera=(), Strict-Transport-Security: max-age=31536000; includeSubDomains; preload.',
7653
+ 'ALWAYS use security headers: X-Content-Type-Options, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy: geolocation=(), microphone=(), camera=(). NEVER set X-Frame-Options: DENY or frame-ancestors: none — the app runs in a sandbox iframe and must be embeddable. HSTS only in production (check NODE_ENV).',
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: helmet with full CSP (defaultSrc self, scriptSrc self, styleSrc self unsafe-inline, imgSrc self data:, connectSrc self, frameSrc none, objectSrc none), HSTS, X-Frame-Options DENY, Referrer-Policy. Add express-rate-limit for general routes (100/15min) and strict limiter for auth (5/15min). Export { applySecurityMiddleware, authLimiter }.' },
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.' },