nothumanallowed 3.4.0 → 3.6.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.4.0",
3
+ "version": "3.6.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": {
@@ -132,7 +132,7 @@ input:focus,textarea:focus{border-color:var(--green3)}
132
132
  /* ---- MODAL ---- */
133
133
  .modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.7);z-index:300;align-items:center;justify-content:center}
134
134
  .modal-overlay--open{display:flex}
135
- .modal{background:var(--bg2);border:1px solid var(--border2);border-radius:8px;width:90%;max-width:500px;max-height:80vh;display:flex;flex-direction:column}
135
+ .modal{background:var(--bg2);border:1px solid var(--border2);border-radius:8px;width:92%;max-width:540px;max-height:90vh;display:flex;flex-direction:column}
136
136
  .modal__header{display:flex;justify-content:space-between;align-items:center;padding:14px 16px;border-bottom:1px solid var(--border)}
137
137
  .modal__header h2{font-size:16px;color:var(--green)}
138
138
  .modal__close{background:none;color:var(--dim);font-size:24px;padding:0 4px}
@@ -342,30 +342,134 @@ function renderEmails(el){
342
342
  el.innerHTML=h;
343
343
  }
344
344
 
345
- // ---- CALENDAR ----
346
- var calDate = new Date().toISOString().split('T')[0];
345
+ // ---- CALENDAR (monthly grid + day detail modal) ----
346
+ var calYear, calMonth;
347
+ var calEventsCache = {};
348
+ (function(){var d=new Date();calYear=d.getFullYear();calMonth=d.getMonth()})();
349
+
350
+ function calKey(y,m,d){return y+'-'+String(m+1).padStart(2,'0')+'-'+String(d).padStart(2,'0')}
351
+ function isToday(y,m,d){var t=new Date();return t.getFullYear()===y&&t.getMonth()===m&&t.getDate()===d}
352
+
347
353
  function renderCalendar(el){
348
- var h='<div style="display:flex;gap:8px;align-items:center;margin-bottom:12px">'+
349
- '<button class="btn btn--secondary" onclick="calNav(-1)">&lt;</button>'+
350
- '<span style="flex:1;text-align:center;font-weight:700;color:var(--bright)">'+calDate+(calDate===new Date().toISOString().split('T')[0]?' (today)':'')+'</span>'+
351
- '<button class="btn btn--secondary" onclick="calNav(1)">&gt;</button>'+
352
- '<button class="btn btn--secondary" onclick="calDate=new Date().toISOString().split(\\x27T\\x27)[0];renderCalendar(document.getElementById(\\x27content\\x27))">Today</button>'+
353
- '</div><div id="calEvents"><div style="text-align:center;padding:20px"><div class="spinner"></div></div></div>';
354
+ var firstDay=new Date(calYear,calMonth,1).getDay();
355
+ var daysInMonth=new Date(calYear,calMonth+1,0).getDate();
356
+ var monthName=new Date(calYear,calMonth,1).toLocaleDateString('en',{month:'long',year:'numeric'});
357
+ // Adjust so Monday=0
358
+ var startDay=(firstDay+6)%7;
359
+
360
+ var h='<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">'+
361
+ '<button class="btn btn--secondary" onclick="calPrev()">&larr;</button>'+
362
+ '<div style="flex:1;text-align:center;font-size:16px;font-weight:700;color:var(--bright)">'+esc(monthName)+'</div>'+
363
+ '<button class="btn btn--secondary" onclick="calNext()">&rarr;</button>'+
364
+ '</div>';
365
+
366
+ // Day headers
367
+ h+='<div style="display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px">';
368
+ ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'].forEach(function(d){
369
+ h+='<div style="text-align:center;font-size:10px;color:var(--dim);padding:4px">'+d+'</div>';
370
+ });
371
+ h+='</div>';
372
+
373
+ // Calendar grid
374
+ h+='<div style="display:grid;grid-template-columns:repeat(7,1fr);gap:2px">';
375
+ // Empty cells before first day
376
+ for(var i=0;i<startDay;i++){h+='<div style="min-height:48px;background:var(--bg);border-radius:4px"></div>'}
377
+ // Day cells
378
+ for(var d=1;d<=daysInMonth;d++){
379
+ var key=calKey(calYear,calMonth,d);
380
+ var today=isToday(calYear,calMonth,d);
381
+ var evts=calEventsCache[key]||[];
382
+ var hasDot=evts.length>0;
383
+ h+='<div onclick="openDayDetail(\\x27'+key+'\\x27)" style="min-height:48px;background:'+(today?'var(--greendim)':'var(--bg2)')+';border:1px solid '+(today?'var(--green3)':'var(--border)')+';border-radius:4px;padding:4px;cursor:pointer;position:relative">';
384
+ h+='<div style="font-size:12px;font-weight:'+(today?'700':'400')+';color:'+(today?'var(--green)':'var(--text)')+'">'+d+'</div>';
385
+ if(hasDot){
386
+ h+='<div style="font-size:8px;color:var(--amber);margin-top:2px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">'+esc(evts[0].summary)+'</div>';
387
+ if(evts.length>1)h+='<div style="font-size:8px;color:var(--dim)">+'+String(evts.length-1)+' more</div>';
388
+ }
389
+ h+='</div>';
390
+ }
391
+ h+='</div>';
392
+
393
+ // Loading indicator
394
+ h+='<div id="calLoading" style="text-align:center;padding:8px;color:var(--dim);font-size:10px">Loading events...</div>';
395
+
354
396
  el.innerHTML=h;
355
- apiGet('/api/calendar?date='+calDate).then(function(r){
356
- var ev=(r&&r.events)||[];
357
- var ce=document.getElementById('calEvents');if(!ce)return;
358
- if(ev.length===0){ce.innerHTML='<div class="card" style="text-align:center;color:var(--dim);padding:20px">No events on '+calDate+'</div>';return}
359
- var out='';ev.forEach(function(x){
360
- out+='<div class="card event"><span class="event__time">'+(x.isAllDay?'All day':fmtTime(x.start)+' - '+fmtTime(x.end))+'</span><span class="event__title">'+esc(x.summary)+'</span>'+(x.location?'<span class="event__location">'+esc(x.location)+'</span>':'')+'</div>';
361
- });
362
- ce.innerHTML=out;
397
+ loadMonthEvents();
398
+ }
399
+
400
+ function loadMonthEvents(){
401
+ var daysInMonth=new Date(calYear,calMonth+1,0).getDate();
402
+ var promises=[];
403
+ for(var d=1;d<=daysInMonth;d++){
404
+ var key=calKey(calYear,calMonth,d);
405
+ if(!calEventsCache[key]){
406
+ (function(k,day){
407
+ promises.push(apiGet('/api/calendar?date='+k).then(function(r){
408
+ calEventsCache[k]=(r&&r.events)||[];
409
+ }));
410
+ })(key,d);
411
+ }
412
+ }
413
+ if(promises.length===0){
414
+ var li=document.getElementById('calLoading');if(li)li.style.display='none';
415
+ return;
416
+ }
417
+ Promise.all(promises).then(function(){
418
+ var li=document.getElementById('calLoading');if(li)li.style.display='none';
419
+ // Re-render just the grid cells with events
420
+ renderCalendar(document.getElementById('content'));
363
421
  });
364
422
  }
365
- function calNav(dir){
366
- var d=new Date(calDate);d.setDate(d.getDate()+dir);
367
- calDate=d.toISOString().split('T')[0];
368
- renderCalendar(document.getElementById('content'));
423
+
424
+ function calPrev(){calMonth--;if(calMonth<0){calMonth=11;calYear--}renderCalendar(document.getElementById('content'))}
425
+ function calNext(){calMonth++;if(calMonth>11){calMonth=0;calYear++}renderCalendar(document.getElementById('content'))}
426
+
427
+ function openDayDetail(dateStr){
428
+ var evts=calEventsCache[dateStr]||[];
429
+ var dayLabel=new Date(dateStr+'T12:00:00').toLocaleDateString('en',{weekday:'long',month:'long',day:'numeric',year:'numeric'});
430
+
431
+ var h='<h2 style="color:var(--green);margin-bottom:4px">'+esc(dayLabel)+'</h2>';
432
+ h+='<div style="color:var(--dim);font-size:11px;margin-bottom:12px">'+dateStr+'</div>';
433
+
434
+ if(evts.length===0){
435
+ h+='<div style="color:var(--dim);padding:20px;text-align:center">No events on this day</div>';
436
+ } else {
437
+ evts.forEach(function(x){
438
+ var timeStr=x.isAllDay?'All day':fmtTime(x.start)+' - '+fmtTime(x.end);
439
+ h+='<div style="border:1px solid var(--border);border-radius:6px;padding:12px;margin-bottom:10px;background:var(--bg3)">';
440
+ h+='<div style="color:var(--amber);font-weight:700;font-size:13px;margin-bottom:4px">'+esc(timeStr)+'</div>';
441
+ h+='<div style="color:var(--bright);font-size:15px;font-weight:700;margin-bottom:6px">'+esc(x.summary)+'</div>';
442
+ if(x.location)h+='<div style="color:var(--cyan);font-size:12px;margin-bottom:4px">Location: '+esc(x.location)+'</div>';
443
+ if(x.organizer)h+='<div style="color:var(--dim);font-size:11px;margin-bottom:4px">Organizer: '+esc(x.organizer)+'</div>';
444
+ if(x.attendees&&x.attendees.length>0){
445
+ h+='<div style="color:var(--dim);font-size:11px;margin-bottom:4px">Attendees:</div>';
446
+ x.attendees.forEach(function(a){
447
+ var status=a.responseStatus==='accepted'?'var(--green)':a.responseStatus==='declined'?'var(--red)':'var(--dim)';
448
+ h+='<div style="font-size:11px;color:'+status+';padding-left:8px">'+esc(a.name||a.email)+' ('+esc(a.responseStatus)+')</div>';
449
+ });
450
+ }
451
+ if(x.description){
452
+ h+='<div style="border-top:1px solid var(--border);margin-top:8px;padding-top:8px;color:var(--text);font-size:12px;white-space:pre-wrap;word-wrap:break-word">'+esc(x.description)+'</div>';
453
+ }
454
+ if(x.hangoutLink){
455
+ h+='<div style="margin-top:8px"><a href="'+esc(x.hangoutLink)+'" target="_blank" style="color:var(--cyan);font-size:12px;font-weight:700">Join Video Call</a></div>';
456
+ }
457
+ if(x.htmlLink){
458
+ h+='<div style="margin-top:4px"><a href="'+esc(x.htmlLink)+'" target="_blank" style="color:var(--dim);font-size:10px">Open in Google Calendar</a></div>';
459
+ }
460
+ h+='</div>';
461
+ });
462
+ }
463
+
464
+ // Use the agent modal for day detail
465
+ document.getElementById('modalName').textContent=dayLabel;
466
+ document.getElementById('modalPrompt').style.display='none';
467
+ document.getElementById('modalResponse').style.display='block';
468
+ document.getElementById('modalResponse').innerHTML=h;
469
+ document.getElementById('agentModal').classList.add('modal-overlay--open');
470
+ // Hide ask button
471
+ var sendBtn=document.getElementById('agentModal').querySelector('.btn--primary');
472
+ if(sendBtn)sendBtn.style.display='none';
369
473
  }
370
474
 
371
475
  // ---- AGENTS ----
@@ -382,8 +486,12 @@ function openAgent(name,display){
382
486
  selectedAgent=name;
383
487
  document.getElementById('modalName').textContent=display||name;
384
488
  document.getElementById('modalPrompt').value='';
489
+ document.getElementById('modalPrompt').style.display='';
385
490
  document.getElementById('modalResponse').style.display='none';
386
491
  document.getElementById('modalResponse').textContent='';
492
+ document.getElementById('modalResponse').innerHTML='';
493
+ var sendBtn=document.getElementById('agentModal').querySelector('.btn--primary');
494
+ if(sendBtn)sendBtn.style.display='';
387
495
  document.getElementById('agentModal').classList.add('modal-overlay--open');
388
496
  }
389
497
  function closeModal(){