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 +1 -1
- package/src/services/web-ui.mjs +129 -21
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,30 +342,134 @@ function renderEmails(el){
|
|
|
342
342
|
el.innerHTML=h;
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
// ---- CALENDAR ----
|
|
346
|
-
var
|
|
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
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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>';
|
|
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
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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(){
|