nothumanallowed 3.1.1 → 3.3.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/commands/ui.mjs +54 -32
- package/src/services/web-ui.mjs +412 -758
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.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/commands/ui.mjs
CHANGED
|
@@ -14,8 +14,8 @@ import fs from 'fs';
|
|
|
14
14
|
import path from 'path';
|
|
15
15
|
import { loadConfig } from '../config.mjs';
|
|
16
16
|
import { callLLM, callAgent, parseAgentFile } from '../services/llm.mjs';
|
|
17
|
-
import { getUnreadImportant } from '../services/google-gmail.mjs';
|
|
18
|
-
import { getTodayEvents } from '../services/google-calendar.mjs';
|
|
17
|
+
import { getUnreadImportant, getMessage, listMessages, sendEmail, createDraft } from '../services/google-gmail.mjs';
|
|
18
|
+
import { getTodayEvents, getUpcomingEvents, createEvent, updateEvent, getEventsForDate } from '../services/google-calendar.mjs';
|
|
19
19
|
import {
|
|
20
20
|
getTasks,
|
|
21
21
|
addTask,
|
|
@@ -87,19 +87,7 @@ RULES:
|
|
|
87
87
|
- Dates: today is {{TODAY}}. The user's timezone is {{TIMEZONE}}.
|
|
88
88
|
`.trim();
|
|
89
89
|
|
|
90
|
-
// ──
|
|
91
|
-
|
|
92
|
-
import {
|
|
93
|
-
listMessages,
|
|
94
|
-
getMessage,
|
|
95
|
-
sendEmail,
|
|
96
|
-
createDraft,
|
|
97
|
-
} from '../services/google-gmail.mjs';
|
|
98
|
-
|
|
99
|
-
import {
|
|
100
|
-
getUpcomingEvents,
|
|
101
|
-
createEvent,
|
|
102
|
-
} from '../services/google-calendar.mjs';
|
|
90
|
+
// ── Tool execution (all imports are at top of file) ──────────
|
|
103
91
|
|
|
104
92
|
function parseActions(text) {
|
|
105
93
|
const actions = [];
|
|
@@ -189,6 +177,40 @@ async function executeTool(action, params, config) {
|
|
|
189
177
|
});
|
|
190
178
|
return `Event "${params.summary}" created for ${fmtTime(params.start)} - ${fmtTime(params.end)}.`;
|
|
191
179
|
}
|
|
180
|
+
case 'calendar_move': {
|
|
181
|
+
await updateEvent(config, 'primary', params.eventId, {
|
|
182
|
+
start: { dateTime: new Date(params.newStart).toISOString() },
|
|
183
|
+
end: { dateTime: new Date(params.newEnd).toISOString() },
|
|
184
|
+
});
|
|
185
|
+
return `Event ${params.eventId} moved to ${fmtTime(params.newStart)} - ${fmtTime(params.newEnd)}.`;
|
|
186
|
+
}
|
|
187
|
+
case 'calendar_tomorrow': {
|
|
188
|
+
const tomorrow = new Date();
|
|
189
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
190
|
+
const events = await getEventsForDate(config, tomorrow);
|
|
191
|
+
if (events.length === 0) return 'No events scheduled for tomorrow.';
|
|
192
|
+
return events.map((e, i) => {
|
|
193
|
+
const time = e.isAllDay ? 'All day' : `${fmtTime(e.start)} - ${fmtTime(e.end)}`;
|
|
194
|
+
return `${i + 1}. ${time} — ${e.summary}${e.location ? ' @ ' + e.location : ''}`;
|
|
195
|
+
}).join('\n');
|
|
196
|
+
}
|
|
197
|
+
case 'task_move': {
|
|
198
|
+
const { moveTask } = await import('../services/task-store.mjs');
|
|
199
|
+
const today = new Date().toISOString().split('T')[0];
|
|
200
|
+
const toDate = params.toDate === 'tomorrow'
|
|
201
|
+
? new Date(new Date().setDate(new Date().getDate() + 1)).toISOString().split('T')[0]
|
|
202
|
+
: params.toDate;
|
|
203
|
+
const moved = moveTask(params.id, today, toDate);
|
|
204
|
+
return moved ? `Task #${params.id} moved to ${toDate}.` : `Task #${params.id} not found.`;
|
|
205
|
+
}
|
|
206
|
+
case 'notify_remind': {
|
|
207
|
+
const delay = params.atTime ? Math.max(0, new Date(params.atTime).getTime() - Date.now()) : 60000;
|
|
208
|
+
setTimeout(async () => {
|
|
209
|
+
const { notify } = await import('../services/notification.mjs');
|
|
210
|
+
notify('Reminder', params.message, config);
|
|
211
|
+
}, delay);
|
|
212
|
+
return `Reminder set: "${params.message}" at ${params.atTime || 'in 1 minute'}.`;
|
|
213
|
+
}
|
|
192
214
|
case 'task_list': {
|
|
193
215
|
const tasks = getTasks();
|
|
194
216
|
if (tasks.length === 0) return 'No tasks for today.';
|
|
@@ -268,7 +290,9 @@ function sendJSON(res, statusCode, data) {
|
|
|
268
290
|
function sendHTML(res, html) {
|
|
269
291
|
res.writeHead(200, {
|
|
270
292
|
'Content-Type': 'text/html; charset=utf-8',
|
|
271
|
-
'Cache-Control': 'no-cache',
|
|
293
|
+
'Cache-Control': 'no-store, no-cache, must-revalidate, max-age=0',
|
|
294
|
+
'Pragma': 'no-cache',
|
|
295
|
+
'Expires': '0',
|
|
272
296
|
});
|
|
273
297
|
res.end(html);
|
|
274
298
|
}
|
|
@@ -526,28 +550,26 @@ export async function cmdUI(args) {
|
|
|
526
550
|
const { textParts, actions } = parseActions(response);
|
|
527
551
|
const textResponse = textParts.join('\n\n');
|
|
528
552
|
|
|
529
|
-
// Execute
|
|
553
|
+
// Execute tool actions — all actions are now executed directly
|
|
530
554
|
let toolResult = null;
|
|
555
|
+
let executedAction = null;
|
|
531
556
|
if (actions.length > 0) {
|
|
532
557
|
const { action, params } = actions[0];
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
]);
|
|
539
|
-
if (safeActions.has(action)) {
|
|
540
|
-
try {
|
|
541
|
-
toolResult = await executeTool(action, params, config);
|
|
542
|
-
} catch (e) {
|
|
543
|
-
toolResult = `Error: ${e.message}`;
|
|
544
|
-
}
|
|
545
|
-
} else {
|
|
546
|
-
toolResult = `[Action "${action}" requires confirmation. Use nha chat in terminal for write operations.]`;
|
|
558
|
+
executedAction = action;
|
|
559
|
+
try {
|
|
560
|
+
toolResult = await executeTool(action, params, config);
|
|
561
|
+
} catch (e) {
|
|
562
|
+
toolResult = `Error executing ${action}: ${e.message}`;
|
|
547
563
|
}
|
|
548
564
|
}
|
|
549
565
|
|
|
550
|
-
|
|
566
|
+
// Append tool result to response so user sees what actually happened
|
|
567
|
+
let fullResponse = textResponse || '';
|
|
568
|
+
if (toolResult && executedAction) {
|
|
569
|
+
fullResponse += '\n\n---\n' + executedAction + ' result: ' + (typeof toolResult === 'object' ? JSON.stringify(toolResult, null, 2) : String(toolResult));
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
sendJSON(res, 200, { response: fullResponse, toolResult, actions });
|
|
551
573
|
} catch (e) {
|
|
552
574
|
sendJSON(res, 200, { response: null, error: e.message });
|
|
553
575
|
}
|