nothumanallowed 14.1.66 → 14.1.68
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/constants.mjs +1 -1
- package/src/server/routes/email.mjs +10 -3
- package/src/server/routes/studio.mjs +12 -0
- package/src/services/email-db.mjs +39 -39
- package/src/ui-dist/assets/index-Dx-Cr-r8.js +689 -0
- package/src/ui-dist/index.html +1 -1
- package/src/ui-dist/assets/index-BTaR8zr-.js +0 -684
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "14.1.
|
|
3
|
+
"version": "14.1.68",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
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 = '14.1.
|
|
8
|
+
export const VERSION = '14.1.68';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -440,17 +440,24 @@ export function register(router) {
|
|
|
440
440
|
|
|
441
441
|
router.get('/api/imap/messages', async (req, res) => {
|
|
442
442
|
try {
|
|
443
|
-
const
|
|
443
|
+
const emailDb = await import('../../services/email-db.mjs');
|
|
444
|
+
if (!emailDb.SQLITE_AVAILABLE) {
|
|
445
|
+
return sendJSON(res, 200, { messages: [], total: 0, error: 'SQLite not available' });
|
|
446
|
+
}
|
|
444
447
|
const url = new URL(req.url, 'http://localhost');
|
|
445
448
|
const accountId = url.searchParams.get('accountId');
|
|
449
|
+
if (!accountId) return sendJSON(res, 200, { messages: [], total: 0 });
|
|
446
450
|
const labelId = url.searchParams.get('labelId') || null;
|
|
447
451
|
const folder = url.searchParams.get('folder') || null;
|
|
448
452
|
const limit = parseInt(url.searchParams.get('limit') || '50');
|
|
449
453
|
const offset = parseInt(url.searchParams.get('offset') || '0');
|
|
450
454
|
const search = url.searchParams.get('search') || '';
|
|
451
|
-
const result = listMessages(accountId, labelId, limit, offset, search, folder);
|
|
455
|
+
const result = emailDb.listMessages(accountId, labelId, limit, offset, search, folder);
|
|
452
456
|
sendJSON(res, 200, { messages: result.messages ?? result, total: result.total ?? 0 });
|
|
453
|
-
} catch (e) {
|
|
457
|
+
} catch (e) {
|
|
458
|
+
console.error('[/api/imap/messages] Error:', e.message);
|
|
459
|
+
sendJSON(res, 200, { messages: [], total: 0, error: e.message });
|
|
460
|
+
}
|
|
454
461
|
});
|
|
455
462
|
|
|
456
463
|
router.get('/api/imap/message', async (req, res) => {
|
|
@@ -215,12 +215,24 @@ export function register(router) {
|
|
|
215
215
|
const contextBlock = context ? `\n\n## CONTEXT FROM PREVIOUS STEPS:\n${context.slice(0, 8000)}` : '';
|
|
216
216
|
const proposalContextBlock = body.proposalContext ? `\n\n## OTHER AGENTS' PROPOSALS (CROSS-READING):\n${body.proposalContext.slice(0, 6000)}` : '';
|
|
217
217
|
|
|
218
|
+
const formatInstructions = `\n\nFORMATTING RULES (CRITICAL — your output will be rendered as HTML):
|
|
219
|
+
- Use MARKDOWN TABLES with | pipes | for ALL tabular data. Example:
|
|
220
|
+
| Header 1 | Header 2 | Header 3 |
|
|
221
|
+
|----------|----------|----------|
|
|
222
|
+
| data | data | data |
|
|
223
|
+
- NEVER use ASCII art boxes (┌─┐│└─┘╔═╗║╚═╝). They render as ugly <pre> blocks.
|
|
224
|
+
- NEVER use ASCII art charts/graphs (├─●──┤). Describe data in tables instead.
|
|
225
|
+
- Use **bold**, *italic*, headers (## ##), bullet points, numbered lists, blockquotes (>).
|
|
226
|
+
- For emphasis boxes, use blockquotes: > **Key insight:** text here
|
|
227
|
+
- Write COMPLETE content under every heading — never leave a section empty.`;
|
|
228
|
+
|
|
218
229
|
const sysParts = [
|
|
219
230
|
agentSysDef || `You are ${agent}, a specialist AI agent in NHA Studio. Respond entirely in ${language}. Today is ${today}.`,
|
|
220
231
|
`\n\n## WORKFLOW GOAL: ${task}`,
|
|
221
232
|
contextBlock,
|
|
222
233
|
proposalContextBlock,
|
|
223
234
|
stepDef?.prompt ? `\n\n## YOUR SPECIFIC TASK:\n${stepDef.prompt}` : '',
|
|
235
|
+
formatInstructions,
|
|
224
236
|
];
|
|
225
237
|
const systemPrompt = sysParts.join('');
|
|
226
238
|
const userMessage = stepDef?.prompt || task;
|
|
@@ -571,51 +571,51 @@ export function listMessages(accountId, labelId, limit, offset, search, folder)
|
|
|
571
571
|
const params = [accountId];
|
|
572
572
|
|
|
573
573
|
if (labelId) {
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
574
|
+
let labelFilterApplied = false;
|
|
575
|
+
try {
|
|
576
|
+
const lbl = db.prepare('SELECT system_type FROM email_labels WHERE id = ?').get(labelId);
|
|
577
|
+
if (lbl?.system_type) {
|
|
578
|
+
// System label — find matching folders by folder_type and name patterns
|
|
579
|
+
const knownNames = {
|
|
580
|
+
inbox: ['inbox'],
|
|
581
|
+
sent: ['sent', 'sent messages', 'sent items', 'posta inviata', 'inviati', 'inviata'],
|
|
582
|
+
drafts: ['drafts', 'draft', 'bozze'],
|
|
583
|
+
spam: ['spam', 'junk', 'junk e-mail', 'posta indesiderata'],
|
|
584
|
+
trash: ['trash', 'cestino', 'deleted', 'deleted messages', 'deleted items'],
|
|
585
|
+
starred: ['starred'],
|
|
586
|
+
archived: ['archived', 'archive', 'all mail'],
|
|
587
|
+
};
|
|
588
|
+
const names = knownNames[lbl.system_type] || [lbl.system_type];
|
|
589
|
+
|
|
590
|
+
// For inbox, use exact path match to avoid INBOX.Sent etc.
|
|
591
|
+
let folderIds = [];
|
|
592
|
+
if (lbl.system_type === 'inbox') {
|
|
593
|
+
const exact = db.prepare('SELECT id FROM email_folders WHERE account_id = ? AND UPPER(path) = ?').get(accountId, 'INBOX');
|
|
594
|
+
if (exact) folderIds = [exact.id];
|
|
595
|
+
}
|
|
596
|
+
// For other types, match by folder_type or name LIKE
|
|
597
|
+
if (folderIds.length === 0) {
|
|
598
|
+
const nameConditions = names.map(() => 'LOWER(f.path) LIKE ? OR LOWER(f.name) LIKE ?').join(' OR ');
|
|
599
|
+
const sql = `SELECT id FROM email_folders f WHERE f.account_id = ? AND (f.folder_type = ? OR ${nameConditions})`;
|
|
600
|
+
const sqlParams = [accountId, lbl.system_type, ...names.flatMap(n => [`%${n}%`, `%${n}%`])];
|
|
601
|
+
folderIds = db.prepare(sql).all(...sqlParams).map(f => f.id);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
if (folderIds.length > 0) {
|
|
605
|
+
const ph = folderIds.map(() => '?').join(',');
|
|
606
|
+
where += ` AND (m.folder_id IN (${ph}) OR EXISTS (SELECT 1 FROM email_message_labels j WHERE j.message_id = m.id AND j.label_id = ?))`;
|
|
607
|
+
params.push(...folderIds, labelId);
|
|
608
|
+
labelFilterApplied = true;
|
|
609
|
+
}
|
|
601
610
|
}
|
|
611
|
+
} catch { /* email_folders table might not exist on older DBs */ }
|
|
602
612
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
where += ` AND (m.folder_id IN (${placeholders}) OR EXISTS (SELECT 1 FROM email_message_labels j WHERE j.message_id = m.id AND j.label_id = ?))`;
|
|
606
|
-
params.push(...filtered.map(f => f.id), labelId);
|
|
607
|
-
} else {
|
|
608
|
-
// No folder found at all — fallback to message_labels join + LIKE on path
|
|
609
|
-
where += ' AND (EXISTS (SELECT 1 FROM email_message_labels j WHERE j.message_id = m.id AND j.label_id = ?) OR LOWER(m.imap_folder_path) LIKE ?)';
|
|
610
|
-
params.push(labelId, `%${lbl.system_type}%`);
|
|
611
|
-
}
|
|
612
|
-
} else {
|
|
613
|
-
// Custom label — only use message_labels join
|
|
613
|
+
if (!labelFilterApplied) {
|
|
614
|
+
// Fallback: use message_labels join only
|
|
614
615
|
where += ' AND EXISTS (SELECT 1 FROM email_message_labels j WHERE j.message_id = m.id AND j.label_id = ?)';
|
|
615
616
|
params.push(labelId);
|
|
616
617
|
}
|
|
617
618
|
} else if (folder) {
|
|
618
|
-
// Filter by folder path (used by Gmail — messages stored with imap_folder_path like INBOX, SENT, etc.)
|
|
619
619
|
where += ' AND m.imap_folder_path = ?';
|
|
620
620
|
params.push(folder.toUpperCase());
|
|
621
621
|
}
|