nothumanallowed 3.0.2 → 3.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "NotHumanAllowed — 38 AI agents for security, code, DevOps, data & daily ops. Ask agents directly, plan your day with 5 specialist agents, manage tasks, connect Gmail + Calendar.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  import http from 'http';
11
+ import os from 'os';
11
12
  import { exec } from 'child_process';
12
13
  import fs from 'fs';
13
14
  import path from 'path';
@@ -29,7 +30,6 @@ import { info, ok, fail, warn, C, G, D, NC, BOLD } from '../ui.mjs';
29
30
  // ── Constants ──────────────────────────────────────────────────────────────
30
31
 
31
32
  const DEFAULT_PORT = 3847;
32
- const HOST = '127.0.0.1';
33
33
 
34
34
  // ── Chat system prompt (reused from chat.mjs) ──────────────────────────────
35
35
 
@@ -311,16 +311,20 @@ function logRequest(method, url, statusCode, durationMs) {
311
311
  // ── Server ───────────────────────────────────────────────────────────────
312
312
 
313
313
  export async function cmdUI(args) {
314
- // Parse port flag
314
+ // Parse flags
315
315
  let port = DEFAULT_PORT;
316
316
  let noBrowser = false;
317
+ let lanMode = false;
317
318
  for (const arg of args) {
318
319
  if (arg.startsWith('--port=')) {
319
320
  port = parseInt(arg.split('=')[1], 10) || DEFAULT_PORT;
320
321
  } else if (arg === '--no-browser') {
321
322
  noBrowser = true;
323
+ } else if (arg === '--lan') {
324
+ lanMode = true;
322
325
  }
323
326
  }
327
+ const HOST = lanMode ? '0.0.0.0' : '127.0.0.1';
324
328
 
325
329
  const config = loadConfig();
326
330
  const htmlPage = getHTML(port);
@@ -367,6 +371,25 @@ export async function cmdUI(args) {
367
371
  return;
368
372
  }
369
373
 
374
+ // ── PWA Manifest ────────────────────────────────────────────────
375
+ if (pathname === '/manifest.json') {
376
+ sendJSON(res, 200, {
377
+ name: 'NHA — Operations Console',
378
+ short_name: 'NHA',
379
+ description: '38 AI agents for daily ops. Email, calendar, tasks, security.',
380
+ start_url: '/',
381
+ display: 'standalone',
382
+ background_color: '#0a0a0a',
383
+ theme_color: '#0a0a0a',
384
+ icons: [
385
+ { src: 'https://nothumanallowed.com/icon-192x192.png', sizes: '192x192', type: 'image/png' },
386
+ { src: 'https://nothumanallowed.com/icon-512x512.png', sizes: '512x512', type: 'image/png' },
387
+ ],
388
+ });
389
+ logRequest(method, pathname, 200, Date.now() - start);
390
+ return;
391
+ }
392
+
370
393
  // ── Favicon (no-content) ──────────────────────────────────────────
371
394
  if (pathname === '/favicon.ico') {
372
395
  res.writeHead(204);
@@ -597,17 +620,40 @@ export async function cmdUI(args) {
597
620
  });
598
621
 
599
622
  server.listen(port, HOST, () => {
600
- const url = `http://${HOST}:${port}`;
623
+ const localUrl = `http://127.0.0.1:${port}`;
624
+
625
+ // Get LAN IP for mobile access
626
+ let lanUrl = '';
627
+ if (lanMode) {
628
+ const nets = os.networkInterfaces();
629
+ for (const name of Object.keys(nets)) {
630
+ for (const net of nets[name]) {
631
+ if (net.family === 'IPv4' && !net.internal) {
632
+ lanUrl = `http://${net.address}:${port}`;
633
+ break;
634
+ }
635
+ }
636
+ if (lanUrl) break;
637
+ }
638
+ }
601
639
 
602
640
  console.log('');
603
641
  console.log(` ${BOLD}${C}NHA Local Operations Console${NC}`);
604
642
  console.log(` ${D}Zero-dependency web interface for your daily ops${NC}`);
605
643
  console.log('');
606
- console.log(` ${G}Server running at:${NC} ${url}`);
644
+ console.log(` ${G}Local:${NC} ${localUrl}`);
645
+ if (lanUrl) {
646
+ console.log(` ${G}Network:${NC} ${lanUrl} ${D}(mobile/tablet)${NC}`);
647
+ }
607
648
  console.log(` ${D}Provider:${NC} ${config.llm.provider || 'not set'}`);
608
649
  console.log(` ${D}API Key:${NC} ${config.llm.apiKey ? config.llm.apiKey.slice(0, 12) + '...' : '\x1b[0;31mnot set\x1b[0m'}`);
609
650
  console.log(` ${D}Agents loaded:${NC} ${agentCards.length}`);
610
651
  console.log('');
652
+ if (lanUrl) {
653
+ console.log(` ${D}Open ${lanUrl} on your phone to use NHA from mobile.${NC}`);
654
+ } else {
655
+ console.log(` ${D}Tip: use --lan to access from phone/tablet on same WiFi.${NC}`);
656
+ }
611
657
  console.log(` ${D}Press Ctrl+C to stop${NC}`);
612
658
  console.log('');
613
659
 
package/src/constants.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import os from 'os';
2
2
  import path from 'path';
3
3
 
4
- export const VERSION = '3.0.0';
4
+ export const VERSION = '3.1.0';
5
5
  export const BASE_URL = 'https://nothumanallowed.com/cli';
6
6
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
7
7
 
@@ -9,7 +9,13 @@ export function getHTML(port) {
9
9
  <html lang="en">
10
10
  <head>
11
11
  <meta charset="utf-8">
12
- <meta name="viewport" content="width=device-width,initial-scale=1">
12
+ <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
13
+ <meta name="mobile-web-app-capable" content="yes">
14
+ <meta name="apple-mobile-web-app-capable" content="yes">
15
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
16
+ <meta name="apple-mobile-web-app-title" content="NHA">
17
+ <meta name="theme-color" content="#0a0a0a">
18
+ <link rel="manifest" href="/manifest.json">
13
19
  <title>NHA — Local Operations Console</title>
14
20
  <style>
15
21
  *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}