nothumanallowed 3.5.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 +1 -1
- package/src/services/web-ui.mjs +124 -52
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "3.
|
|
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": {
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -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:
|
|
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,66 +342,134 @@ function renderEmails(el){
|
|
|
342
342
|
el.innerHTML=h;
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
// ---- CALENDAR ----
|
|
346
|
-
var
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
var
|
|
355
|
-
var
|
|
356
|
-
var
|
|
357
|
-
|
|
358
|
-
var
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
'<
|
|
362
|
-
'<
|
|
363
|
-
'
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
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
|
+
|
|
353
|
+
function renderCalendar(el){
|
|
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()">←</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()">→</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>';
|
|
367
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>';
|
|
368
395
|
|
|
369
|
-
h
|
|
370
|
-
|
|
396
|
+
el.innerHTML=h;
|
|
397
|
+
loadMonthEvents();
|
|
398
|
+
}
|
|
371
399
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
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);
|
|
379
411
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
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'));
|
|
421
|
+
});
|
|
422
|
+
}
|
|
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
|
+
});
|
|
390
450
|
}
|
|
391
|
-
if
|
|
392
|
-
|
|
393
|
-
out += '<div style="color:var(--dim);font-size:11px;margin-top:4px">👥 ' + esc(names) + '</div>';
|
|
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>';
|
|
394
453
|
}
|
|
395
|
-
if
|
|
396
|
-
|
|
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>';
|
|
397
456
|
}
|
|
398
|
-
if
|
|
399
|
-
|
|
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>';
|
|
400
459
|
}
|
|
401
|
-
|
|
460
|
+
h+='</div>';
|
|
402
461
|
});
|
|
403
|
-
|
|
404
|
-
|
|
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';
|
|
405
473
|
}
|
|
406
474
|
|
|
407
475
|
// ---- AGENTS ----
|
|
@@ -418,8 +486,12 @@ function openAgent(name,display){
|
|
|
418
486
|
selectedAgent=name;
|
|
419
487
|
document.getElementById('modalName').textContent=display||name;
|
|
420
488
|
document.getElementById('modalPrompt').value='';
|
|
489
|
+
document.getElementById('modalPrompt').style.display='';
|
|
421
490
|
document.getElementById('modalResponse').style.display='none';
|
|
422
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='';
|
|
423
495
|
document.getElementById('agentModal').classList.add('modal-overlay--open');
|
|
424
496
|
}
|
|
425
497
|
function closeModal(){
|