nothumanallowed 3.4.0 → 3.5.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.5.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": {
@@ -343,30 +343,66 @@ function renderEmails(el){
343
343
  }
344
344
 
345
345
  // ---- CALENDAR ----
346
- var calDate = new Date().toISOString().split('T')[0];
347
- 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
- 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>';
346
+ var calOffset = 0;
347
+ function renderCalendar(el) {
348
+ var today = new Date();
349
+ var target = new Date(today);
350
+ target.setDate(today.getDate() + calOffset);
351
+ var yyyy = target.getFullYear();
352
+ var mm = String(target.getMonth() + 1).padStart(2, '0');
353
+ var dd = String(target.getDate()).padStart(2, '0');
354
+ var dateStr = yyyy + '-' + mm + '-' + dd;
355
+ var dayName = target.toLocaleDateString('en', { weekday: 'long', month: 'long', day: 'numeric' });
356
+ var isToday = calOffset === 0;
357
+
358
+ var h = '<div style="display:flex;align-items:center;gap:8px;margin-bottom:16px;flex-wrap:wrap">' +
359
+ '<button class="btn btn--secondary" onclick="calOffset--;renderCalendar(document.getElementById(\\x27content\\x27))">&larr; Prev</button>' +
360
+ '<div style="flex:1;text-align:center"><div style="font-size:16px;font-weight:700;color:var(--bright)">' + esc(dayName) + '</div>' +
361
+ '<div style="font-size:11px;color:var(--dim)">' + dateStr + (isToday ? ' (today)' : '') + '</div></div>' +
362
+ '<button class="btn btn--secondary" onclick="calOffset++;renderCalendar(document.getElementById(\\x27content\\x27))">Next &rarr;</button>' +
363
+ '</div>';
364
+
365
+ if (!isToday) {
366
+ h += '<div style="text-align:center;margin-bottom:12px"><button class="btn btn--secondary" onclick="calOffset=0;renderCalendar(document.getElementById(\\x27content\\x27))">Go to Today</button></div>';
367
+ }
368
+
369
+ h += '<div id="calEvents"><div style="text-align:center;padding:30px"><div class="spinner"></div><div style="color:var(--dim);margin-top:8px">Loading events...</div></div></div>';
370
+ el.innerHTML = h;
371
+
372
+ apiGet('/api/calendar?date=' + dateStr).then(function(r) {
373
+ var ev = (r && r.events) || [];
374
+ var ce = document.getElementById('calEvents');
375
+ if (!ce) return;
376
+ if (ev.length === 0) {
377
+ ce.innerHTML = '<div class="card" style="text-align:center;color:var(--dim);padding:30px">No events on ' + esc(dayName) + '</div>';
378
+ return;
379
+ }
380
+ var out = '<div style="color:var(--cyan);font-size:11px;margin-bottom:8px">' + ev.length + ' event' + (ev.length > 1 ? 's' : '') + '</div>';
381
+ ev.forEach(function(x) {
382
+ var timeStr = x.isAllDay ? 'All day' : fmtTime(x.start) + ' — ' + fmtTime(x.end);
383
+ out += '<div class="card" style="padding:14px">' +
384
+ '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">' +
385
+ '<span style="color:var(--amber);font-weight:700;font-size:13px">' + esc(timeStr) + '</span>' +
386
+ '</div>' +
387
+ '<div style="color:var(--bright);font-size:14px;font-weight:600;margin-bottom:4px">' + esc(x.summary) + '</div>';
388
+ if (x.location) {
389
+ out += '<div style="color:var(--dim);font-size:11px">📍 ' + esc(x.location) + '</div>';
390
+ }
391
+ if (x.attendees && x.attendees.length > 0) {
392
+ var names = x.attendees.map(function(a) { return a.name || a.email }).join(', ');
393
+ out += '<div style="color:var(--dim);font-size:11px;margin-top:4px">👥 ' + esc(names) + '</div>';
394
+ }
395
+ if (x.description) {
396
+ out += '<div style="color:var(--dim);font-size:11px;margin-top:4px;border-top:1px solid var(--border);padding-top:6px">' + esc(x.description.slice(0, 200)) + '</div>';
397
+ }
398
+ if (x.hangoutLink) {
399
+ out += '<div style="margin-top:6px"><a href="' + esc(x.hangoutLink) + '" target="_blank" style="color:var(--cyan);font-size:11px">🔗 Join video call</a></div>';
400
+ }
401
+ out += '</div>';
361
402
  });
362
- ce.innerHTML=out;
403
+ ce.innerHTML = out;
363
404
  });
364
405
  }
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'));
369
- }
370
406
 
371
407
  // ---- AGENTS ----
372
408
  function renderAgents(el){