nothumanallowed 8.9.2 → 9.0.1
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 +75 -1
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +36 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.1",
|
|
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,25 @@ 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
|
+
|
|
293
312
|
// POST /api/contacts — create contact
|
|
294
313
|
if (method === 'POST' && pathname === '/api/contacts') {
|
|
295
314
|
try {
|
|
@@ -837,7 +856,62 @@ export async function cmdUI(args) {
|
|
|
837
856
|
}
|
|
838
857
|
}
|
|
839
858
|
|
|
840
|
-
// Handle
|
|
859
|
+
// Handle PDF attachment — send as document to Claude (native PDF support)
|
|
860
|
+
if (body.pdfBase64 && body.pdfName) {
|
|
861
|
+
try {
|
|
862
|
+
const provider = config.llm.provider || 'anthropic';
|
|
863
|
+
const apiKey = config.llm.apiKey;
|
|
864
|
+
const model = config.llm.model;
|
|
865
|
+
const pdfPrompt = body.message || `Read and analyze this PDF document "${body.pdfName}". Extract all text content, summarize key information.`;
|
|
866
|
+
let pdfResponse = '';
|
|
867
|
+
|
|
868
|
+
if (provider === 'anthropic') {
|
|
869
|
+
const r = await fetch('https://api.anthropic.com/v1/messages', {
|
|
870
|
+
method: 'POST',
|
|
871
|
+
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' },
|
|
872
|
+
body: JSON.stringify({
|
|
873
|
+
model: model || 'claude-sonnet-4-20250514', max_tokens: 8192, system: enrichedSystemPrompt,
|
|
874
|
+
messages: [{ role: 'user', content: [
|
|
875
|
+
{ type: 'document', source: { type: 'base64', media_type: 'application/pdf', data: body.pdfBase64 } },
|
|
876
|
+
{ type: 'text', text: pdfPrompt },
|
|
877
|
+
]}],
|
|
878
|
+
}),
|
|
879
|
+
});
|
|
880
|
+
if (!r.ok) throw new Error(`Anthropic ${r.status}: ${(await r.text()).slice(0, 200)}`);
|
|
881
|
+
const d = await r.json();
|
|
882
|
+
pdfResponse = d.content?.[0]?.text || '';
|
|
883
|
+
} else if (provider === 'gemini') {
|
|
884
|
+
const m = model || 'gemini-2.0-flash';
|
|
885
|
+
const r = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${m}:generateContent?key=${apiKey}`, {
|
|
886
|
+
method: 'POST',
|
|
887
|
+
headers: { 'Content-Type': 'application/json' },
|
|
888
|
+
body: JSON.stringify({
|
|
889
|
+
system_instruction: { parts: [{ text: enrichedSystemPrompt }] },
|
|
890
|
+
contents: [{ parts: [
|
|
891
|
+
{ inline_data: { mime_type: 'application/pdf', data: body.pdfBase64 } },
|
|
892
|
+
{ text: pdfPrompt },
|
|
893
|
+
]}],
|
|
894
|
+
generationConfig: { maxOutputTokens: 8192 },
|
|
895
|
+
}),
|
|
896
|
+
});
|
|
897
|
+
if (!r.ok) throw new Error(`Gemini ${r.status}`);
|
|
898
|
+
const d = await r.json();
|
|
899
|
+
pdfResponse = d.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
900
|
+
} else {
|
|
901
|
+
pdfResponse = `PDF reading requires Anthropic (Claude) or Gemini. Your provider "${provider}" does not support native PDF documents.`;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
sendJSON(res, 200, { response: pdfResponse });
|
|
905
|
+
logRequest(method, pathname, 200, Date.now() - start);
|
|
906
|
+
return;
|
|
907
|
+
} catch (e) {
|
|
908
|
+
sendJSON(res, 200, { response: null, error: `PDF error: ${e.message}` });
|
|
909
|
+
logRequest(method, pathname, 200, Date.now() - start);
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// Handle text file attachment
|
|
841
915
|
if (body.fileContent && body.fileName) {
|
|
842
916
|
const filePrompt = body.message
|
|
843
917
|
? `User asks about file "${body.fileName}": ${body.message}\n\nFile content:\n${body.fileContent.slice(0, 8000)}`
|
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 = '
|
|
8
|
+
export const VERSION = '9.0.1';
|
|
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
|
@@ -340,14 +340,28 @@ var chatAttachedImage=null;
|
|
|
340
340
|
|
|
341
341
|
function handleChatFile(input){
|
|
342
342
|
var file=input.files&&input.files[0];if(!file)return;
|
|
343
|
-
var
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
343
|
+
var isPDF=file.name.toLowerCase().endsWith('.pdf')||file.type==='application/pdf';
|
|
344
|
+
if(isPDF){
|
|
345
|
+
// PDF: read as base64 and send as document to LLM
|
|
346
|
+
var reader=new FileReader();
|
|
347
|
+
reader.onload=function(e){
|
|
348
|
+
var base64=e.target.result.split(',')[1];
|
|
349
|
+
chatAttachedFile={name:file.name,size:file.size,content:null,base64:base64,mimeType:'application/pdf',isPDF:true};
|
|
350
|
+
chatAttachedImage=null;
|
|
351
|
+
document.getElementById('chatAttachInfo').style.display='';
|
|
352
|
+
document.getElementById('chatAttachName').textContent='📎 '+file.name+' ('+Math.round(file.size/1024)+' KB)';
|
|
353
|
+
};
|
|
354
|
+
reader.readAsDataURL(file);
|
|
355
|
+
}else{
|
|
356
|
+
var reader=new FileReader();
|
|
357
|
+
reader.onload=function(e){
|
|
358
|
+
chatAttachedFile={name:file.name,size:file.size,content:e.target.result};
|
|
359
|
+
chatAttachedImage=null;
|
|
360
|
+
document.getElementById('chatAttachInfo').style.display='';
|
|
361
|
+
document.getElementById('chatAttachName').textContent='📎 '+file.name+' ('+Math.round(file.size/1024)+' KB)';
|
|
362
|
+
};
|
|
363
|
+
reader.readAsText(file);
|
|
364
|
+
}
|
|
351
365
|
}
|
|
352
366
|
|
|
353
367
|
function handleChatImage(input){
|
|
@@ -385,7 +399,13 @@ function sendChat(){
|
|
|
385
399
|
chatHistory.push({role:'assistant',content:'Thinking...'});renderMessages();
|
|
386
400
|
|
|
387
401
|
var payload={message:msg||'Analyze this attachment',history:chatHistory.slice(0,-1)};
|
|
388
|
-
if(chatAttachedFile){
|
|
402
|
+
if(chatAttachedFile){
|
|
403
|
+
if(chatAttachedFile.isPDF&&chatAttachedFile.base64){
|
|
404
|
+
payload.pdfBase64=chatAttachedFile.base64;payload.pdfName=chatAttachedFile.name;
|
|
405
|
+
}else{
|
|
406
|
+
payload.fileContent=chatAttachedFile.content;payload.fileName=chatAttachedFile.name;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
389
409
|
if(chatAttachedImage){payload.imageBase64=chatAttachedImage.base64;payload.imageMimeType=chatAttachedImage.mimeType;payload.imageName=chatAttachedImage.name;}
|
|
390
410
|
clearChatAttach();
|
|
391
411
|
|
|
@@ -480,6 +500,13 @@ function renderEmails(el){
|
|
|
480
500
|
var openEmailId=null;
|
|
481
501
|
function openEmail(id){
|
|
482
502
|
openEmailId=id;
|
|
503
|
+
// Mark as read locally + on server
|
|
504
|
+
var emailObj=dash.emails.find(function(e){return e.id===id});
|
|
505
|
+
if(emailObj&&emailObj.isUnread){
|
|
506
|
+
emailObj.isUnread=false;
|
|
507
|
+
updateBadges();
|
|
508
|
+
apiPost('/api/email/mark-read',{messageId:id}).catch(function(){});
|
|
509
|
+
}
|
|
483
510
|
var el=document.getElementById('content');
|
|
484
511
|
el.innerHTML='<div style="text-align:center;padding:40px"><div class="spinner"></div><div style="color:var(--dim)">Loading email...</div></div>';
|
|
485
512
|
apiPost('/api/email/read',{messageId:id}).then(function(r){
|