nothumanallowed 9.0.0 → 9.0.2
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/commands/ui.mjs +36 -2
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +26 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.2",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents + unified productivity suite. Gmail, Calendar, Drive, Contacts, Tasks, GitHub, Notion, Slack, voice chat, smart scheduler. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -290,6 +290,40 @@ export async function cmdUI(args) {
|
|
|
290
290
|
return;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
// POST /api/email/mark-read — mark email as read
|
|
294
|
+
if (method === 'POST' && pathname === '/api/email/mark-read') {
|
|
295
|
+
const body = await parseBody(req);
|
|
296
|
+
if (!body.messageId) {
|
|
297
|
+
sendJSON(res, 400, { error: 'messageId required' });
|
|
298
|
+
logRequest(method, pathname, 400, Date.now() - start);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
try {
|
|
302
|
+
const gmail = await import('../services/google-gmail.mjs');
|
|
303
|
+
await gmail.markAsRead(config, body.messageId);
|
|
304
|
+
sendJSON(res, 200, { ok: true });
|
|
305
|
+
} catch (e) {
|
|
306
|
+
sendJSON(res, 200, { ok: false, error: e.message });
|
|
307
|
+
}
|
|
308
|
+
logRequest(method, pathname, 200, Date.now() - start);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// POST /api/email/mark-all-read — mark ALL unread as read
|
|
313
|
+
if (method === 'POST' && pathname === '/api/email/mark-all-read') {
|
|
314
|
+
try {
|
|
315
|
+
const gmail = await import('../services/google-gmail.mjs');
|
|
316
|
+
const result = await gmail.markAllAsRead(config);
|
|
317
|
+
// Update local cache
|
|
318
|
+
dash.emails.forEach(e => { e.isUnread = false; });
|
|
319
|
+
sendJSON(res, 200, { ok: true, count: result.count });
|
|
320
|
+
} catch (e) {
|
|
321
|
+
sendJSON(res, 200, { ok: false, error: e.message });
|
|
322
|
+
}
|
|
323
|
+
logRequest(method, pathname, 200, Date.now() - start);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
293
327
|
// POST /api/contacts — create contact
|
|
294
328
|
if (method === 'POST' && pathname === '/api/contacts') {
|
|
295
329
|
try {
|
|
@@ -502,9 +536,9 @@ export async function cmdUI(args) {
|
|
|
502
536
|
} else {
|
|
503
537
|
// Show all recent inbox emails (read + unread)
|
|
504
538
|
const gm = await import('../services/google-gmail.mjs');
|
|
505
|
-
const msgRefs = await gm.listMessages(config, 'in:inbox',
|
|
539
|
+
const msgRefs = await gm.listMessages(config, 'in:inbox', 50);
|
|
506
540
|
emails = [];
|
|
507
|
-
for (const ref of msgRefs.slice(0,
|
|
541
|
+
for (const ref of msgRefs.slice(0, 50)) {
|
|
508
542
|
try {
|
|
509
543
|
const msg = await gm.getMessage(config, ref.id);
|
|
510
544
|
emails.push(msg);
|
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 = '9.0.
|
|
8
|
+
export const VERSION = '9.0.2';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -490,16 +490,40 @@ function refreshPlan(){
|
|
|
490
490
|
// ---- EMAILS ----
|
|
491
491
|
function renderEmails(el){
|
|
492
492
|
var e=dash.emails;
|
|
493
|
-
if(e.length===0){el.innerHTML='<div class="card" style="text-align:center;color:var(--dim);padding:30px">No
|
|
494
|
-
var
|
|
493
|
+
if(e.length===0){el.innerHTML='<div class="card" style="text-align:center;color:var(--dim);padding:30px">No emails</div>';return}
|
|
494
|
+
var unreadCount=e.filter(function(x){return x.isUnread}).length;
|
|
495
|
+
var h='<div style="display:flex;gap:8px;margin-bottom:10px;align-items:center">';
|
|
496
|
+
h+='<span style="font-size:12px;color:var(--dim)">'+e.length+' emails'+( unreadCount>0?' ('+unreadCount+' unread)':'')+'</span>';
|
|
497
|
+
if(unreadCount>0)h+='<button class="btn btn--secondary" style="font-size:10px;padding:4px 10px" onclick="markAllEmailsRead()">Mark all read</button>';
|
|
498
|
+
h+='</div>';
|
|
499
|
+
e.forEach(function(x){
|
|
495
500
|
var unreadStyle=x.isUnread?'border-left:3px solid var(--green);font-weight:700':'border-left:3px solid transparent;opacity:0.7';
|
|
496
501
|
h+='<div class="card email" style="cursor:pointer;'+unreadStyle+'" onclick="openEmail(\\x27'+esc(x.id)+'\\x27)"><div class="email__header"><span class="email__from">'+esc(x.from)+'</span><span class="email__date">'+esc(x.date)+(x.isUnread?' <span style="color:var(--green);font-size:9px">NEW</span>':'')+'</span></div><div class="email__subject">'+esc(x.subject)+'</div><div class="email__snippet" style="font-weight:400">'+esc((x.snippet||'').slice(0,150))+'</div></div>';
|
|
497
502
|
});
|
|
498
503
|
el.innerHTML=h;
|
|
499
504
|
}
|
|
505
|
+
function markAllEmailsRead(){
|
|
506
|
+
apiPost('/api/email/mark-all-read',{}).then(function(r){
|
|
507
|
+
if(r&&r.ok){
|
|
508
|
+
dash.emails.forEach(function(e){e.isUnread=false});
|
|
509
|
+
updateBadges();
|
|
510
|
+
renderEmails(document.getElementById('content'));
|
|
511
|
+
showToast('success','All Read','Marked '+( r.count||0)+' emails as read');
|
|
512
|
+
}else{
|
|
513
|
+
showToast('error','Error',r&&r.error||'Failed');
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
}
|
|
500
517
|
var openEmailId=null;
|
|
501
518
|
function openEmail(id){
|
|
502
519
|
openEmailId=id;
|
|
520
|
+
// Mark as read locally + on server
|
|
521
|
+
var emailObj=dash.emails.find(function(e){return e.id===id});
|
|
522
|
+
if(emailObj&&emailObj.isUnread){
|
|
523
|
+
emailObj.isUnread=false;
|
|
524
|
+
updateBadges();
|
|
525
|
+
apiPost('/api/email/mark-read',{messageId:id}).catch(function(){});
|
|
526
|
+
}
|
|
503
527
|
var el=document.getElementById('content');
|
|
504
528
|
el.innerHTML='<div style="text-align:center;padding:40px"><div class="spinner"></div><div style="color:var(--dim)">Loading email...</div></div>';
|
|
505
529
|
apiPost('/api/email/read',{messageId:id}).then(function(r){
|