nothumanallowed 6.2.0 → 6.3.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": "6.2.0",
3
+ "version": "6.3.0",
4
4
  "description": "NotHumanAllowed — 38 AI agents for security, code, DevOps, data & daily ops. Per-agent memory, Telegram + Discord auto-responder, proactive intelligence daemon, voice chat, plugin system.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.mjs CHANGED
@@ -414,6 +414,23 @@ function cmdConfig(args) {
414
414
  console.log(` Deadlines: ${proactive.deadlines !== false ? G + 'on' : D + 'off'}${NC}`);
415
415
  }
416
416
 
417
+ const profile = config.profile;
418
+ if (profile) {
419
+ console.log(`\n ${C}User Profile${NC}`);
420
+ if (profile.name) console.log(` Name: ${W}${profile.name}${NC}`);
421
+ if (profile.email) console.log(` Email: ${D}${profile.email}${NC}`);
422
+ if (profile.homeAddress) console.log(` Home: ${W}${profile.homeAddress}${NC}`);
423
+ if (profile.workAddress) console.log(` Work: ${W}${profile.workAddress}${NC}`);
424
+ if (profile.city) console.log(` City: ${W}${profile.city}${NC}`);
425
+ if (profile.company) console.log(` Company: ${D}${profile.company}${NC}`);
426
+ if (profile.role) console.log(` Role: ${D}${profile.role}${NC}`);
427
+ if (!profile.name && !profile.homeAddress) {
428
+ console.log(` ${D}(not set — agents won't know your personal info)${NC}`);
429
+ console.log(` ${D}Set with: nha config set name "Your Name"${NC}`);
430
+ console.log(` ${D} nha config set home "Via Roma 1, Modena"${NC}`);
431
+ }
432
+ }
433
+
417
434
  console.log('');
418
435
  }
419
436
 
@@ -485,7 +485,7 @@ function parseActions(text) {
485
485
 
486
486
  // ── System Prompt Builder ────────────────────────────────────────────────────
487
487
 
488
- function buildSystemPrompt(initialContext) {
488
+ function buildSystemPrompt(initialContext, config) {
489
489
  const today = new Date().toISOString().split('T')[0];
490
490
  const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
491
491
 
@@ -498,6 +498,26 @@ function buildSystemPrompt(initialContext) {
498
498
  `Be concise, helpful, and proactive. When presenting data, format it clearly. ` +
499
499
  `Never output raw JSON to the user — always wrap results in natural language.`;
500
500
 
501
+ // Inject user profile if configured
502
+ const profile = config?.profile;
503
+ if (profile) {
504
+ const fields = [];
505
+ if (profile.name) fields.push(`Name: ${profile.name}`);
506
+ if (profile.email) fields.push(`Email: ${profile.email}`);
507
+ if (profile.phone) fields.push(`Phone: ${profile.phone}`);
508
+ if (profile.homeAddress) fields.push(`Home address: ${profile.homeAddress}`);
509
+ if (profile.workAddress) fields.push(`Work address: ${profile.workAddress}`);
510
+ if (profile.city) fields.push(`City: ${profile.city}`);
511
+ if (profile.country) fields.push(`Country: ${profile.country}`);
512
+ if (profile.company) fields.push(`Company: ${profile.company}`);
513
+ if (profile.role) fields.push(`Role: ${profile.role}`);
514
+ if (profile.notes) fields.push(`Notes: ${profile.notes}`);
515
+
516
+ if (fields.length > 0) {
517
+ prompt += `\n\n--- USER PROFILE (use this for personal references like "my home", "my city", etc.) ---\n${fields.join('\n')}`;
518
+ }
519
+ }
520
+
501
521
  if (initialContext) {
502
522
  prompt += `\n\n--- CURRENT CONTEXT (fetched at session start) ---\n${initialContext}`;
503
523
  }
@@ -695,7 +715,7 @@ export async function cmdChat(args) {
695
715
  if (history.length > 0) {
696
716
  ok(`Loaded ${Math.floor(history.length / 2)} previous conversation turns from memory.`);
697
717
  }
698
- const systemPrompt = buildSystemPrompt(initialContext);
718
+ const systemPrompt = buildSystemPrompt(initialContext, config);
699
719
 
700
720
  // ── Graceful exit ───────────────────────────────────────────────────────
701
721
  rl.on('close', () => {
@@ -463,6 +463,26 @@ export async function cmdUI(args) {
463
463
  `You help the user manage their emails, calendar, and tasks through natural conversation. ` +
464
464
  `Be concise, helpful, and proactive. When presenting data, format it clearly. ` +
465
465
  `Never output raw JSON to the user.`;
466
+
467
+ // Inject user profile
468
+ const profile = config?.profile;
469
+ if (profile) {
470
+ const fields = [];
471
+ if (profile.name) fields.push(`Name: ${profile.name}`);
472
+ if (profile.email) fields.push(`Email: ${profile.email}`);
473
+ if (profile.phone) fields.push(`Phone: ${profile.phone}`);
474
+ if (profile.homeAddress) fields.push(`Home address: ${profile.homeAddress}`);
475
+ if (profile.workAddress) fields.push(`Work address: ${profile.workAddress}`);
476
+ if (profile.city) fields.push(`City: ${profile.city}`);
477
+ if (profile.country) fields.push(`Country: ${profile.country}`);
478
+ if (profile.company) fields.push(`Company: ${profile.company}`);
479
+ if (profile.role) fields.push(`Role: ${profile.role}`);
480
+ if (profile.notes) fields.push(`Notes: ${profile.notes}`);
481
+ if (fields.length > 0) {
482
+ prompt += `\n\n--- USER PROFILE (use for "my home", "my city", "my office", etc.) ---\n${fields.join('\n')}`;
483
+ }
484
+ }
485
+
466
486
  return prompt;
467
487
  })();
468
488
 
@@ -354,7 +354,8 @@ html,body{height:100%;background:var(--bg);color:var(--text);font-family:var(--f
354
354
 
355
355
  const JS = `
356
356
  var API = '';
357
- var chatHistory = [];
357
+ var chatHistory = (function(){try{var s=localStorage.getItem('nha_voice_history');return s?JSON.parse(s):[];}catch(e){return [];}})();
358
+ function saveVoiceToStorage(){try{localStorage.setItem('nha_voice_history',JSON.stringify(chatHistory.slice(-20)));}catch(e){}}
358
359
  var isRecording = false;
359
360
  var recognition = null;
360
361
  var mediaRecorder = null;
@@ -523,7 +524,7 @@ function speak(text) {
523
524
  // ---- PROCESS MESSAGE ----
524
525
  function processMessage(text) {
525
526
  chatHistory.push({ role: 'user', content: text });
526
- renderMessages();
527
+ saveVoiceToStorage();renderMessages();
527
528
 
528
529
  chatHistory.push({ role: 'assistant', content: 'Thinking...' });
529
530
  renderMessages();
@@ -543,7 +544,7 @@ function processMessage(text) {
543
544
  response = 'No response from server.';
544
545
  chatHistory.push({ role: 'assistant', content: response });
545
546
  }
546
- renderMessages();
547
+ saveVoiceToStorage();renderMessages();
547
548
  setStatus('');
548
549
 
549
550
  // Speak the response
@@ -746,6 +747,19 @@ export async function cmdVoice(args) {
746
747
  `You help the user manage their emails, calendar, and tasks through voice commands. ` +
747
748
  `Keep responses SHORT and SPOKEN-FRIENDLY — 2-3 sentences max. ` +
748
749
  `Avoid markdown formatting, bullet points, numbered lists. Use natural spoken language.`;
750
+
751
+ const profile = config?.profile;
752
+ if (profile) {
753
+ const fields = [];
754
+ if (profile.name) fields.push(`Name: ${profile.name}`);
755
+ if (profile.homeAddress) fields.push(`Home: ${profile.homeAddress}`);
756
+ if (profile.workAddress) fields.push(`Work: ${profile.workAddress}`);
757
+ if (profile.city) fields.push(`City: ${profile.city}`);
758
+ if (fields.length > 0) {
759
+ prompt += `\n\n[USER PROFILE] ${fields.join('. ')}.`;
760
+ }
761
+ }
762
+
749
763
  return prompt;
750
764
  })();
751
765
 
package/src/config.mjs CHANGED
@@ -100,6 +100,20 @@ const DEFAULT_CONFIG = {
100
100
  speechSynthesis: true,
101
101
  language: '',
102
102
  },
103
+ profile: {
104
+ name: '',
105
+ email: '',
106
+ phone: '',
107
+ homeAddress: '',
108
+ workAddress: '',
109
+ city: '',
110
+ country: '',
111
+ timezone: '',
112
+ language: '',
113
+ company: '',
114
+ role: '',
115
+ notes: '',
116
+ },
103
117
  };
104
118
 
105
119
  /**
@@ -228,6 +242,23 @@ export function setConfigValue(key, value) {
228
242
  'proactive-meeting': 'ops.proactive.meetingPrep',
229
243
  'proactive-patterns': 'ops.proactive.patterns',
230
244
  'proactive-deadlines': 'ops.proactive.deadlines',
245
+ 'name': 'profile.name',
246
+ 'my-name': 'profile.name',
247
+ 'email': 'profile.email',
248
+ 'my-email': 'profile.email',
249
+ 'phone': 'profile.phone',
250
+ 'my-phone': 'profile.phone',
251
+ 'home': 'profile.homeAddress',
252
+ 'home-address': 'profile.homeAddress',
253
+ 'work': 'profile.workAddress',
254
+ 'work-address': 'profile.workAddress',
255
+ 'city': 'profile.city',
256
+ 'my-city': 'profile.city',
257
+ 'country': 'profile.country',
258
+ 'company': 'profile.company',
259
+ 'my-role': 'profile.role',
260
+ 'role': 'profile.role',
261
+ 'profile-notes': 'profile.notes',
231
262
  };
232
263
 
233
264
  const resolved = aliases[key] || key;
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 = '6.2.0';
8
+ export const VERSION = '6.3.0';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -180,8 +180,11 @@ input:focus,textarea:focus{border-color:var(--green3)}
180
180
  const JS = `
181
181
  var API = '';
182
182
  var currentView = 'dashboard';
183
- var chatHistory = [];
183
+ var chatHistory = (function(){try{var s=localStorage.getItem('nha_chat_history');return s?JSON.parse(s):[];}catch(e){return [];}})();
184
184
  var dash = {emails:[],events:[],tasks:[],plan:null,status:null};
185
+
186
+ function saveChatToStorage(){try{localStorage.setItem('nha_chat_history',JSON.stringify(chatHistory.slice(-40)));}catch(e){}}
187
+ function clearChatHistory(){chatHistory=[];saveChatToStorage();renderMessages();}
185
188
  var agentsList = [];
186
189
  var selectedAgent = null;
187
190
 
@@ -279,7 +282,7 @@ function renderDash(el){
279
282
  var chatReady=false;
280
283
  function renderChat(el){
281
284
  if(!chatReady||!document.getElementById('chatMessages')){
282
- el.innerHTML='<div class="chat"><div class="chat__messages" id="chatMessages"></div><div class="chat__bar"><button class="chat__mic" id="chatMic" onclick="toggleVoiceInput()" title="Voice input">&#127908;</button><textarea class="chat__input" id="chatInput" placeholder="Ask anything..." rows="1"></textarea><button class="chat__send" id="chatSend">Send</button></div></div>';
285
+ el.innerHTML='<div class="chat"><div class="chat__messages" id="chatMessages"></div><div class="chat__bar"><button class="chat__mic" id="chatMic" onclick="toggleVoiceInput()" title="Voice input">&#127908;</button><textarea class="chat__input" id="chatInput" placeholder="Ask anything..." rows="1"></textarea><button class="chat__send" id="chatSend">Send</button><button onclick="clearChatHistory()" style="background:none;color:var(--dim);font-size:10px;padding:4px 8px" title="Clear chat history">Clear</button></div></div>';
283
286
  chatReady=true;
284
287
  document.getElementById('chatSend').onclick=sendChat;
285
288
  document.getElementById('chatInput').onkeydown=function(e){if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();sendChat()}};
@@ -302,14 +305,14 @@ function sendChat(){
302
305
  var inp=document.getElementById('chatInput');if(!inp)return;
303
306
  var msg=inp.value.trim();if(!msg)return;
304
307
  chatHistory.push({role:'user',content:msg});
305
- inp.value='';renderMessages();
308
+ inp.value='';saveChatToStorage();renderMessages();
306
309
  chatHistory.push({role:'assistant',content:'Thinking...'});renderMessages();
307
310
  apiPost('/api/chat',{message:msg,history:chatHistory.slice(0,-1)}).then(function(r){
308
311
  chatHistory.pop();
309
312
  if(r&&r.response){chatHistory.push({role:'assistant',content:r.response})}
310
313
  else if(r&&r.error){chatHistory.push({role:'assistant',content:'Error: '+r.error})}
311
314
  else{chatHistory.push({role:'assistant',content:'Error: no response from server'})}
312
- renderMessages();
315
+ saveChatToStorage();renderMessages();
313
316
  // Refresh data if an action was executed
314
317
  if(r&&r.actions&&r.actions.length>0){
315
318
  // Clear calendar cache so new events show up