nothumanallowed 6.5.0 → 6.5.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/chat.mjs +33 -6
- package/src/commands/ui.mjs +16 -2
- package/src/commands/voice.mjs +10 -0
- package/src/config.mjs +12 -1
- package/src/constants.mjs +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "6.5.
|
|
3
|
+
"version": "6.5.2",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents for security, code, DevOps, data & daily ops. Per-agent memory, Telegram + Discord auto-responder, proactive intelligence daemon, voice chat, plugin system.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/chat.mjs
CHANGED
|
@@ -125,12 +125,15 @@ TOOLS:
|
|
|
125
125
|
18. schedule_draft_email(clientName: string, subject: string, location: string, durationMinutes: number, dateFrom: string, dateTo: string)
|
|
126
126
|
Same as schedule_meeting but also generates a professional email proposing the top 3 slots to the client.
|
|
127
127
|
|
|
128
|
-
19.
|
|
128
|
+
19. calendar_find(query: string, daysAhead?: number)
|
|
129
|
+
Search for a calendar event by name/keyword in the next N days (default 7). Returns matching events with their IDs.
|
|
130
|
+
ALWAYS use this FIRST when the user wants to modify an event — you need the eventId.
|
|
131
|
+
|
|
132
|
+
20. calendar_update(eventId: string, summary?: string, location?: string, description?: string, start?: string, end?: string)
|
|
129
133
|
Update ANY field of an existing calendar event: title, location, description, start time, end time.
|
|
130
|
-
|
|
131
|
-
Only include fields that need to change. ALWAYS confirm with the user before updating.
|
|
134
|
+
You MUST call calendar_find first to get the eventId. Only include fields that need to change. ALWAYS confirm before updating.
|
|
132
135
|
|
|
133
|
-
|
|
136
|
+
21. maps_directions(from: string, to: string)
|
|
134
137
|
Generate a Google Maps directions link between two locations. Returns a clickable URL.
|
|
135
138
|
Use this when the user asks for directions, route, or "how to get to" somewhere.
|
|
136
139
|
|
|
@@ -360,6 +363,30 @@ async function executeTool(action, params, config) {
|
|
|
360
363
|
return `${proposal}\n\n--- DRAFT EMAIL ---\n\n${email}`;
|
|
361
364
|
}
|
|
362
365
|
|
|
366
|
+
// ── Calendar Find (search event by name) ────────────────────────────
|
|
367
|
+
case 'calendar_find': {
|
|
368
|
+
const { listEvents: listEventsRouter } = await import('../services/mail-router.mjs');
|
|
369
|
+
const query = (params.query || '').toLowerCase();
|
|
370
|
+
const daysAhead = params.daysAhead || 7;
|
|
371
|
+
const from = new Date();
|
|
372
|
+
const to = new Date(from.getTime() + daysAhead * 86400000);
|
|
373
|
+
const events = await listEventsRouter(config, 'primary', from, to);
|
|
374
|
+
|
|
375
|
+
const matches = events.filter(e =>
|
|
376
|
+
(e.summary || '').toLowerCase().includes(query) ||
|
|
377
|
+
(e.description || '').toLowerCase().includes(query)
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
if (matches.length === 0) return `No events found matching "${params.query}" in the next ${daysAhead} days.`;
|
|
381
|
+
|
|
382
|
+
return matches.map((e, i) => {
|
|
383
|
+
const time = e.isAllDay ? 'All day' : `${formatTime(e.start)} - ${formatTime(e.end)}`;
|
|
384
|
+
const date = e.start.split('T')[0];
|
|
385
|
+
const loc = e.location ? ` | Location: ${e.location}` : '';
|
|
386
|
+
return `${i + 1}. [eventId: ${e.id}] ${date} ${time} — ${e.summary}${loc}`;
|
|
387
|
+
}).join('\n');
|
|
388
|
+
}
|
|
389
|
+
|
|
363
390
|
// ── Calendar Update (modify any field of existing event) ──────────────
|
|
364
391
|
case 'calendar_update': {
|
|
365
392
|
const { updateEvent: updateCal } = await import('../services/mail-router.mjs');
|
|
@@ -398,10 +425,10 @@ async function executeTool(action, params, config) {
|
|
|
398
425
|
function formatEvents(events) {
|
|
399
426
|
return events.map((e, i) => {
|
|
400
427
|
const time = e.isAllDay ? 'All day' : `${formatTime(e.start)} - ${formatTime(e.end)}`;
|
|
401
|
-
const location = e.location ? ` | ${e.location}` : '';
|
|
428
|
+
const location = e.location ? ` | Location: ${e.location}` : '';
|
|
402
429
|
const link = e.hangoutLink ? ` | ${e.hangoutLink}` : '';
|
|
403
430
|
const cal = e.calendarName ? ` (${e.calendarName})` : '';
|
|
404
|
-
return `${i + 1}. ${time} — ${e.summary}${location}${link}${cal}`;
|
|
431
|
+
return `${i + 1}. [ID:${e.id}] ${time} — ${e.summary}${location}${link}${cal}`;
|
|
405
432
|
}).join('\n');
|
|
406
433
|
}
|
|
407
434
|
|
package/src/commands/ui.mjs
CHANGED
|
@@ -173,7 +173,7 @@ async function executeTool(action, params, config) {
|
|
|
173
173
|
if (events.length === 0) return 'No events scheduled for today.';
|
|
174
174
|
return events.map((e, i) => {
|
|
175
175
|
const time = e.isAllDay ? 'All day' : `${fmtTime(e.start)} - ${fmtTime(e.end)}`;
|
|
176
|
-
return `${i + 1}. ${time} — ${e.summary}${e.location ? ' @ ' + e.location : ''}`;
|
|
176
|
+
return `${i + 1}. [ID:${e.id}] ${time} — ${e.summary}${e.location ? ' @ ' + e.location : ''}`;
|
|
177
177
|
}).join('\n');
|
|
178
178
|
}
|
|
179
179
|
case 'calendar_upcoming': {
|
|
@@ -209,7 +209,7 @@ async function executeTool(action, params, config) {
|
|
|
209
209
|
if (events.length === 0) return 'No events scheduled for tomorrow.';
|
|
210
210
|
return events.map((e, i) => {
|
|
211
211
|
const time = e.isAllDay ? 'All day' : `${fmtTime(e.start)} - ${fmtTime(e.end)}`;
|
|
212
|
-
return `${i + 1}. ${time} — ${e.summary}${e.location ? ' @ ' + e.location : ''}`;
|
|
212
|
+
return `${i + 1}. [ID:${e.id}] ${time} — ${e.summary}${e.location ? ' @ ' + e.location : ''}`;
|
|
213
213
|
}).join('\n');
|
|
214
214
|
}
|
|
215
215
|
case 'task_move': {
|
|
@@ -306,6 +306,20 @@ async function executeTool(action, params, config) {
|
|
|
306
306
|
return `${proposal}\n\n--- DRAFT EMAIL ---\n\n${email}`;
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
case 'calendar_find': {
|
|
310
|
+
const { listEvents: listEventsR } = await import('../services/mail-router.mjs');
|
|
311
|
+
const query = (params.query || '').toLowerCase();
|
|
312
|
+
const daysAhead = params.daysAhead || 7;
|
|
313
|
+
const from = new Date();
|
|
314
|
+
const to = new Date(from.getTime() + daysAhead * 86400000);
|
|
315
|
+
const events = await listEventsR(config, 'primary', from, to);
|
|
316
|
+
const matches = events.filter(e => (e.summary || '').toLowerCase().includes(query) || (e.description || '').toLowerCase().includes(query));
|
|
317
|
+
if (matches.length === 0) return `No events matching "${params.query}" in the next ${daysAhead} days.`;
|
|
318
|
+
return matches.map((e, i) => {
|
|
319
|
+
const time = e.isAllDay ? 'All day' : `${fmtTime(e.start)} - ${fmtTime(e.end)}`;
|
|
320
|
+
return `${i + 1}. [eventId: ${e.id}] ${e.start.split('T')[0]} ${time} — ${e.summary}${e.location ? ' @ ' + e.location : ''}`;
|
|
321
|
+
}).join('\n');
|
|
322
|
+
}
|
|
309
323
|
case 'calendar_update': {
|
|
310
324
|
const { updateEvent: updateCal } = await import('../services/mail-router.mjs');
|
|
311
325
|
const patch = {};
|
package/src/commands/voice.mjs
CHANGED
|
@@ -218,6 +218,16 @@ async function executeTool(action, params, config) {
|
|
|
218
218
|
});
|
|
219
219
|
return formatSlotProposal(slots, params.clientName || 'the client', params.subject || 'meeting', params.location || '');
|
|
220
220
|
}
|
|
221
|
+
case 'calendar_find': {
|
|
222
|
+
const { listEvents: listEventsR } = await import('../services/mail-router.mjs');
|
|
223
|
+
const query = (params.query || '').toLowerCase();
|
|
224
|
+
const from = new Date();
|
|
225
|
+
const to = new Date(from.getTime() + 7 * 86400000);
|
|
226
|
+
const events = await listEventsR(config, 'primary', from, to);
|
|
227
|
+
const matches = events.filter(e => (e.summary || '').toLowerCase().includes(query));
|
|
228
|
+
if (matches.length === 0) return 'No events matching that name found this week.';
|
|
229
|
+
return matches.map((e, i) => `${i + 1}. Event ID ${e.id}, ${e.start.split('T')[0]}, ${e.summary}`).join('. ');
|
|
230
|
+
}
|
|
221
231
|
case 'calendar_update': {
|
|
222
232
|
const { updateEvent: updateCal } = await import('../services/mail-router.mjs');
|
|
223
233
|
const patch = {};
|
package/src/config.mjs
CHANGED
|
@@ -123,7 +123,18 @@ const DEFAULT_CONFIG = {
|
|
|
123
123
|
export function loadConfig() {
|
|
124
124
|
if (fs.existsSync(CONFIG_FILE)) {
|
|
125
125
|
try {
|
|
126
|
-
|
|
126
|
+
const saved = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
|
|
127
|
+
// Deep merge with defaults so new config sections (profile, responder, etc.)
|
|
128
|
+
// are always present even if the file was created before they existed
|
|
129
|
+
const merged = structuredClone(DEFAULT_CONFIG);
|
|
130
|
+
for (const [key, value] of Object.entries(saved)) {
|
|
131
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value) && typeof merged[key] === 'object' && merged[key] !== null) {
|
|
132
|
+
merged[key] = { ...merged[key], ...value };
|
|
133
|
+
} else {
|
|
134
|
+
merged[key] = value;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return merged;
|
|
127
138
|
} catch {
|
|
128
139
|
return structuredClone(DEFAULT_CONFIG);
|
|
129
140
|
}
|
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 = '6.5.
|
|
8
|
+
export const VERSION = '6.5.2';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|