nothumanallowed 16.0.24 → 16.0.26

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,7 +1,7 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "16.0.24",
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.",
3
+ "version": "16.0.26",
4
+ "description": "Local AI assistant: 80 tools (Gmail, Calendar, Drive, GitHub, Slack, browser, code, files), 38 agents, visual workflows (Studio, AWF, WebCraft). Install with `npm i -g nothumanallowed`, run with `nha ui`. Free tier built-in (Liara), no API key required. Your data stays on your PC — OAuth tokens local, no cloud. Open-source MIT.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "nha": "bin/nha",
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 = '16.0.24';
8
+ export const VERSION = '16.0.26';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -343,9 +343,23 @@ class SandboxManager {
343
343
  }
344
344
  }
345
345
  } else if (missingModules.length > 0 && uniqueMissing.length === 0) {
346
- // All missing modules are shimmable should never reach here because
347
- // the shim handles them transparently. If it does, log the surprise.
348
- emit({ type: 'warn', msg: `Crash mentions modules that ARE shimmed (${missingModules.join(', ')}). The shim index.js may not have been preloaded — check .nha-launcher.js wiring.` });
346
+ // All missing modules are shimmable in THIS version of the CLI. If we
347
+ // reached this branch, the user has an OLDER CLI installed that doesn't
348
+ // know about these shims yet. Surface this loudly with the exact upgrade
349
+ // command — DON'T leave the user staring at a generic crash.
350
+ emit({ type: 'error', msg:
351
+ `\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
352
+ `⚠ IL TUO NHA È OBSOLETO — questo crash è già fixato nell'ultima versione.\n` +
353
+ `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
354
+ `Moduli mancanti che la nuova versione gestisce automaticamente:\n` +
355
+ ` → ${missingModules.join(', ')}\n\n` +
356
+ `Aggiorna NHA (3 comandi):\n` +
357
+ ` 1. npm install -g nothumanallowed@latest\n` +
358
+ ` 2. pkill -f "nha-launcher" ; pkill -f "node.*nha"\n` +
359
+ ` 3. nha ui\n\n` +
360
+ `Verifica versione dopo: nha --version (deve essere >= 16.0.25)\n` +
361
+ `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`
362
+ });
349
363
  }
350
364
 
351
365
  // ── Tier 2: runtime errors that need code fix (require/import mismatch,
@@ -3442,7 +3456,7 @@ export const _SHIMMED_MODULES = new Set([
3442
3456
  'pg', 'redis', 'ioredis', 'helmet', 'mongoose', 'sequelize',
3443
3457
  'dotenv', 'cors', 'morgan', 'body-parser', 'cookie-parser',
3444
3458
  'compression', 'express-rate-limit', 'jsonwebtoken', 'bcryptjs', 'bcrypt',
3445
- 'uuid', 'lodash', 'debug', 'chalk', 'multer', 'axios',
3459
+ 'uuid', 'lodash', 'debug', 'chalk', 'multer', 'axios', 'express',
3446
3460
  ]);
3447
3461
 
3448
3462
  /** Read declared dependencies from package.json (deps + devDeps + peer). */
@@ -3991,6 +4005,107 @@ multer.diskStorage = (opts) => ({ _kind: 'disk', opts });
3991
4005
  multer.memoryStorage = () => ({ _kind: 'memory' });
3992
4006
  module.exports = multer;
3993
4007
  module.exports.default = multer;
4008
+ `;
4009
+
4010
+ // express — minimal HTTP framework shim (route matching, middleware chain,
4011
+ // req.params/query/body, res.json/send/status). Enough to boot a typical
4012
+ // LLM-generated Express app even without express in node_modules.
4013
+ const expressShim = `
4014
+ const http = require('http');
4015
+ const url = require('url');
4016
+
4017
+ function parseBody(req) {
4018
+ return new Promise((resolve) => {
4019
+ let raw = '';
4020
+ req.on('data', (c) => { raw += c; });
4021
+ req.on('end', () => {
4022
+ const ct = req.headers['content-type'] || '';
4023
+ try {
4024
+ if (/json/i.test(ct)) resolve(raw ? JSON.parse(raw) : {});
4025
+ else if (/urlencoded/i.test(ct)) {
4026
+ const o = {};
4027
+ for (const p of raw.split('&')) { const [k, v] = p.split('=').map(decodeURIComponent); if (k) o[k] = v || ''; }
4028
+ resolve(o);
4029
+ } else resolve(raw);
4030
+ } catch { resolve(raw); }
4031
+ });
4032
+ });
4033
+ }
4034
+
4035
+ function compilePath(p) {
4036
+ if (p instanceof RegExp) return { re: p, keys: [] };
4037
+ const keys = [];
4038
+ const re = '^' + String(p).replace(/:([^/]+)/g, (_m, k) => { keys.push(k); return '([^/]+)'; }) + '/?$';
4039
+ return { re: new RegExp(re), keys };
4040
+ }
4041
+
4042
+ function createApp() {
4043
+ const stack = [];
4044
+ const settings = {};
4045
+ function use(arg, ...rest) {
4046
+ if (typeof arg === 'function') stack.push({ method: 'ALL', re: /.*/, keys: [], handlers: [arg, ...rest] });
4047
+ else { const c = compilePath(arg); stack.push({ method: 'ALL', re: c.re, keys: c.keys, handlers: rest.flat() }); }
4048
+ return app;
4049
+ }
4050
+ function addRoute(method) {
4051
+ return (path, ...handlers) => { const c = compilePath(path); stack.push({ method, re: c.re, keys: c.keys, handlers: handlers.flat() }); return app; };
4052
+ }
4053
+ const app = async function (req, res) {
4054
+ const parsed = url.parse(req.url, true);
4055
+ req.path = parsed.pathname;
4056
+ req.query = parsed.query;
4057
+ if (['POST', 'PUT', 'PATCH'].includes(req.method)) req.body = await parseBody(req);
4058
+ if (!res.json) {
4059
+ res.json = function (obj) { this.setHeader('Content-Type', 'application/json'); this.end(JSON.stringify(obj)); return this; };
4060
+ res.send = function (data) { if (typeof data === 'object') return this.json(data); this.end(String(data)); return this; };
4061
+ res.status = function (n) { this.statusCode = n; return this; };
4062
+ res.sendStatus = function (n) { this.statusCode = n; this.end(http.STATUS_CODES[n] || ''); return this; };
4063
+ res.redirect = function (loc) { this.statusCode = 302; this.setHeader('Location', loc); this.end(); return this; };
4064
+ }
4065
+ let i = 0;
4066
+ const next = (err) => {
4067
+ if (err) { res.statusCode = 500; return res.end('Error: ' + (err.message || err)); }
4068
+ while (i < stack.length) {
4069
+ const layer = stack[i++];
4070
+ if (layer.method !== 'ALL' && layer.method !== req.method) continue;
4071
+ const m = req.path.match(layer.re);
4072
+ if (!m) continue;
4073
+ req.params = {};
4074
+ layer.keys.forEach((k, idx) => { req.params[k] = m[idx + 1]; });
4075
+ let hIdx = 0;
4076
+ const runHandlers = (e) => {
4077
+ if (e) return next(e);
4078
+ if (hIdx >= layer.handlers.length) return next();
4079
+ const h = layer.handlers[hIdx++];
4080
+ try { return h.length === 4 ? h(e, req, res, runHandlers) : h(req, res, runHandlers); }
4081
+ catch (err) { return next(err); }
4082
+ };
4083
+ return runHandlers();
4084
+ }
4085
+ res.statusCode = 404;
4086
+ res.end('Cannot ' + req.method + ' ' + req.path);
4087
+ };
4088
+ next();
4089
+ };
4090
+ app.use = use;
4091
+ app.get = addRoute('GET'); app.post = addRoute('POST'); app.put = addRoute('PUT');
4092
+ app.delete = addRoute('DELETE'); app.patch = addRoute('PATCH'); app.options = addRoute('OPTIONS');
4093
+ app.all = (path, ...handlers) => { const c = compilePath(path); stack.push({ method: 'ALL', re: c.re, keys: c.keys, handlers: handlers.flat() }); return app; };
4094
+ app.set = (k, v) => { settings[k] = v; return app; };
4095
+ app.get_setting = (k) => settings[k];
4096
+ app.disable = (k) => { settings[k] = false; return app; };
4097
+ app.enable = (k) => { settings[k] = true; return app; };
4098
+ app.listen = function (port, cb) { const server = http.createServer(app); server.listen(port, cb); return server; };
4099
+ return app;
4100
+ }
4101
+
4102
+ const express = createApp;
4103
+ express.json = function (opts) { return async (req, res, next) => { if (/json/i.test(req.headers['content-type'] || '')) req.body = await parseBody(req); next(); }; };
4104
+ express.urlencoded = function (opts) { return async (req, res, next) => { if (/urlencoded/i.test(req.headers['content-type'] || '')) req.body = await parseBody(req); next(); }; };
4105
+ express.static = function (root) { return (req, res, next) => next(); };
4106
+ express.Router = function () { const r = createApp(); return r; };
4107
+ module.exports = express;
4108
+ module.exports.default = express;
3994
4109
  `;
3995
4110
 
3996
4111
  // axios — minimal fetch-based replacement
@@ -4067,6 +4182,7 @@ module.exports.default = proxy;
4067
4182
  'chalk.js': chalkShim,
4068
4183
  'multer.js': multerShim,
4069
4184
  'axios.js': axiosShim,
4185
+ 'express.js': expressShim,
4070
4186
  'noop.js': noopShim,
4071
4187
  };
4072
4188
  for (const [name, content] of Object.entries(shimFiles)) {