nothumanallowed 13.2.58 → 13.2.60
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 +39 -6
- package/src/config.mjs +3 -0
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +33 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.2.
|
|
3
|
+
"version": "13.2.60",
|
|
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/commands/ui.mjs
CHANGED
|
@@ -2877,24 +2877,57 @@ export async function cmdUI(args) {
|
|
|
2877
2877
|
sendToken('[Reading GitHub...] ');
|
|
2878
2878
|
try {
|
|
2879
2879
|
const gh = await import('../services/github.mjs');
|
|
2880
|
-
|
|
2881
|
-
|
|
2880
|
+
if (!config.github?.token) {
|
|
2881
|
+
toolData = 'GitHub token not configured. Run: nha config set github-token YOUR_PAT';
|
|
2882
|
+
} else {
|
|
2883
|
+
const parts = [];
|
|
2884
|
+
// Notifications (always available)
|
|
2885
|
+
try {
|
|
2886
|
+
const notifs = await withTimeout(gh.listNotifications(config, 15), 'GitHubAgent-notifs');
|
|
2887
|
+
if (notifs) parts.push('## GitHub Notifications\n' + notifs);
|
|
2888
|
+
} catch (e) { /* skip */ }
|
|
2889
|
+
// Issues/PRs on configured repo if available
|
|
2890
|
+
const repo = config.github?.defaultRepo || '';
|
|
2891
|
+
if (repo) {
|
|
2892
|
+
try {
|
|
2893
|
+
const issues = await withTimeout(gh.listIssues(config, repo, 'open', 10), 'GitHubAgent-issues');
|
|
2894
|
+
if (issues) parts.push('## Open Issues (' + repo + ')\n' + issues);
|
|
2895
|
+
} catch (e) { /* skip */ }
|
|
2896
|
+
try {
|
|
2897
|
+
const prs = await withTimeout(gh.listPRs(config, repo, 'open', 10), 'GitHubAgent-prs');
|
|
2898
|
+
if (prs) parts.push('## Open PRs (' + repo + ')\n' + prs);
|
|
2899
|
+
} catch (e) { /* skip */ }
|
|
2900
|
+
}
|
|
2901
|
+
toolData = parts.length > 0 ? parts.join('\n\n') : 'No GitHub data available.';
|
|
2902
|
+
}
|
|
2882
2903
|
} catch (e) { toolData = `GitHub read failed: ${e.message}`; }
|
|
2883
2904
|
|
|
2884
2905
|
} else if (agent === 'NotionAgent') {
|
|
2885
2906
|
sendToken('[Searching Notion...] ');
|
|
2886
2907
|
try {
|
|
2887
2908
|
const nt = await import('../services/notion.mjs');
|
|
2888
|
-
|
|
2889
|
-
|
|
2909
|
+
if (!config.notion?.token) {
|
|
2910
|
+
toolData = 'Notion token not configured. Run: nha config set notion-token YOUR_TOKEN';
|
|
2911
|
+
} else {
|
|
2912
|
+
const results = await withTimeout(nt.search(config, stepPrompt, 10), 'NotionAgent');
|
|
2913
|
+
toolData = typeof results === 'string' ? results : JSON.stringify(results);
|
|
2914
|
+
}
|
|
2890
2915
|
} catch (e) { toolData = `Notion search failed: ${e.message}`; }
|
|
2891
2916
|
|
|
2892
2917
|
} else if (agent === 'SlackAgent') {
|
|
2893
2918
|
sendToken('[Reading Slack...] ');
|
|
2894
2919
|
try {
|
|
2895
2920
|
const sl = await import('../services/slack.mjs');
|
|
2896
|
-
|
|
2897
|
-
|
|
2921
|
+
if (!config.slack?.token) {
|
|
2922
|
+
toolData = 'Slack token not configured. Run: nha config set slack-token xoxb-YOUR_TOKEN';
|
|
2923
|
+
} else {
|
|
2924
|
+
const parts = [];
|
|
2925
|
+
try {
|
|
2926
|
+
const channels = await withTimeout(sl.listChannels(config, 10), 'SlackAgent-channels');
|
|
2927
|
+
if (channels) parts.push('## Slack Channels\n' + (typeof channels === 'string' ? channels : JSON.stringify(channels)));
|
|
2928
|
+
} catch (e) { /* skip */ }
|
|
2929
|
+
toolData = parts.length > 0 ? parts.join('\n\n') : 'No Slack data available.';
|
|
2930
|
+
}
|
|
2898
2931
|
} catch (e) { toolData = `Slack read failed: ${e.message}`; }
|
|
2899
2932
|
|
|
2900
2933
|
} else if (agent === 'DriveAgent') {
|
package/src/config.mjs
CHANGED
|
@@ -102,6 +102,7 @@ const DEFAULT_CONFIG = {
|
|
|
102
102
|
},
|
|
103
103
|
github: {
|
|
104
104
|
token: '',
|
|
105
|
+
defaultRepo: '',
|
|
105
106
|
},
|
|
106
107
|
notion: {
|
|
107
108
|
token: '',
|
|
@@ -264,6 +265,8 @@ export function setConfigValue(key, value) {
|
|
|
264
265
|
'proactive-deadlines': 'ops.proactive.deadlines',
|
|
265
266
|
'github-token': 'github.token',
|
|
266
267
|
'gh-token': 'github.token',
|
|
268
|
+
'github-repo': 'github.defaultRepo',
|
|
269
|
+
'gh-repo': 'github.defaultRepo',
|
|
267
270
|
'notion-token': 'notion.token',
|
|
268
271
|
'slack-token': 'slack.token',
|
|
269
272
|
'name': 'profile.name',
|
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 = '13.2.
|
|
8
|
+
export const VERSION = '13.2.60';
|
|
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
|
@@ -1180,15 +1180,19 @@ function loadMonthEvents(){
|
|
|
1180
1180
|
function calPrev(){calMonth--;if(calMonth<0){calMonth=11;calYear--}renderCalendar(document.getElementById('content'))}
|
|
1181
1181
|
function calNext(){calMonth++;if(calMonth>11){calMonth=0;calYear++}renderCalendar(document.getElementById('content'))}
|
|
1182
1182
|
|
|
1183
|
+
var _calDayEvts=[];
|
|
1184
|
+
var _calDayStr='';
|
|
1183
1185
|
function openDayDetail(dateStr){
|
|
1184
1186
|
var evts=calEventsCache[dateStr]||[];
|
|
1187
|
+
_calDayEvts=evts;
|
|
1188
|
+
_calDayStr=dateStr;
|
|
1185
1189
|
var dayLabel=new Date(dateStr+'T12:00:00').toLocaleDateString('en',{weekday:'long',month:'long',day:'numeric',year:'numeric'});
|
|
1186
1190
|
|
|
1187
1191
|
function buildDayHtml(){
|
|
1188
1192
|
var h='<h2 style="color:var(--green);margin-bottom:4px">'+esc(dayLabel)+'</h2>';
|
|
1189
1193
|
h+='<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">';
|
|
1190
1194
|
h+='<span style="color:var(--dim);font-size:11px">'+dateStr+'</span>';
|
|
1191
|
-
h+='<button onclick="openEventForm(null,
|
|
1195
|
+
h+='<button onclick="openEventForm(null,_calDayStr)" style="margin-left:auto;background:var(--green3);color:var(--bg);padding:5px 12px;border-radius:var(--r);font-size:12px;font-weight:700">+ Add Event</button>';
|
|
1192
1196
|
h+='</div>';
|
|
1193
1197
|
if(evts.length===0){
|
|
1194
1198
|
h+='<div style="color:var(--dim);padding:20px;text-align:center">No events on this day</div>';
|
|
@@ -1202,8 +1206,8 @@ function openDayDetail(dateStr){
|
|
|
1202
1206
|
h+='<div style="color:var(--bright);font-size:15px;font-weight:700;margin-bottom:6px">'+esc(x.summary)+'</div></div>';
|
|
1203
1207
|
if(x.id){
|
|
1204
1208
|
h+='<div style="display:flex;gap:4px;flex-shrink:0">';
|
|
1205
|
-
h+='<button onclick="
|
|
1206
|
-
h+='<button onclick="
|
|
1209
|
+
h+='<button onclick="openEventFormByIdx('+idx+')" style="background:var(--bg2);border:1px solid var(--border);color:var(--text);padding:3px 8px;border-radius:4px;font-size:11px">Edit</button>';
|
|
1210
|
+
h+='<button onclick="deleteCalEventByIdx('+idx+')" style="background:var(--bg2);border:1px solid var(--red);color:var(--red);padding:3px 8px;border-radius:4px;font-size:11px">Delete</button>';
|
|
1207
1211
|
h+='</div>';
|
|
1208
1212
|
}
|
|
1209
1213
|
h+='</div>';
|
|
@@ -1253,10 +1257,20 @@ function refreshDayDetail(dateStr){
|
|
|
1253
1257
|
|
|
1254
1258
|
function deleteCalEvent(calId,eventId,dateStr){
|
|
1255
1259
|
if(!confirm('Delete this event?'))return;
|
|
1256
|
-
apiPost('/api/calendar/'+encodeURIComponent(calId)+'/'+encodeURIComponent(eventId),
|
|
1260
|
+
apiPost('/api/calendar/'+encodeURIComponent(calId)+'/'+encodeURIComponent(eventId),{},'DELETE').then(function(){
|
|
1257
1261
|
refreshDayDetail(dateStr);
|
|
1258
1262
|
}).catch(function(e){alert('Error: '+e.message);});
|
|
1259
1263
|
}
|
|
1264
|
+
function deleteCalEventByIdx(idx){
|
|
1265
|
+
var x=_calDayEvts[idx];if(!x)return;
|
|
1266
|
+
var calId=x.calendarId||'primary';
|
|
1267
|
+
deleteCalEvent(calId,x.id,_calDayStr);
|
|
1268
|
+
}
|
|
1269
|
+
function openEventFormByIdx(idx){
|
|
1270
|
+
var x=_calDayEvts[idx];if(!x)return;
|
|
1271
|
+
var calId=x.calendarId||'primary';
|
|
1272
|
+
openEventForm({id:x.id,calId:calId,summary:x.summary,description:x.description||'',location:x.location||'',start:x.start,end:x.end,isAllDay:x.isAllDay},_calDayStr);
|
|
1273
|
+
}
|
|
1260
1274
|
|
|
1261
1275
|
function openEventForm(evt,dateStr){
|
|
1262
1276
|
var isEdit=evt&&evt.id;
|
|
@@ -1326,7 +1340,7 @@ function renderGitHub(el){
|
|
|
1326
1340
|
// Header: user profile + repo input
|
|
1327
1341
|
var userHtml='';
|
|
1328
1342
|
if(user&&user.login){
|
|
1329
|
-
userHtml='<div style="display:flex;align-items:center;gap:10px;margin-bottom:14px;padding:10px 14px;background:var(--bg2);border-radius:var(--r);border:1px solid var(--border)">'+(user.avatar?'<img src="'+esc(user.avatar)+'" style="width:36px;height:36px;border-radius:50%;object-fit:cover" alt="">':'')+'<div><div style="font-weight:700;font-size:13px;color:var(--green)">@'+esc(user.login)+'</div>'+(user.name?'<div style="font-size:11px;color:var(--dim)">'+esc(user.name)+'</div>':'')+'</div></div>';
|
|
1343
|
+
userHtml='<div style="display:flex;align-items:center;gap:10px;margin-bottom:14px;padding:10px 14px;background:var(--bg2);border-radius:var(--r);border:1px solid var(--border)">'+(user.avatar?'<img src="'+esc(user.avatar)+'" style="width:36px;height:36px;border-radius:50%;object-fit:cover" alt="">':'')+'<div style="flex:1"><div style="font-weight:700;font-size:13px;color:var(--green)">@'+esc(user.login)+'</div>'+(user.name?'<div style="font-size:11px;color:var(--dim)">'+esc(user.name)+'</div>':'')+'</div><button onclick="disconnectService(\\x27github-token\\x27,function(el){ghData=null;renderGitHub(el)})" style="background:var(--bg3);border:1px solid var(--red);color:var(--red);padding:4px 10px;border-radius:var(--r);font-size:11px">Disconnect</button></div>';
|
|
1330
1344
|
}
|
|
1331
1345
|
var h=userHtml+'<div style="display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap"><input type="text" id="ghRepo" placeholder="owner/repo" value="'+esc(ghRepo)+'" style="flex:1;min-width:180px;font-size:13px;padding:10px 14px" onkeydown="if(event.key===\\x27Enter\\x27)loadGhIssues()"><button onclick="loadGhIssues()" style="background:var(--green3);color:var(--bg);padding:8px 16px;border-radius:var(--r);font-weight:700;font-size:12px">Issues</button><button onclick="loadGhPRs()" style="background:var(--cyan);color:var(--bg);padding:8px 16px;border-radius:var(--r);font-weight:700;font-size:12px">PRs</button></div>';
|
|
1332
1346
|
// My repos as clickable pills
|
|
@@ -1366,17 +1380,19 @@ function renderGitHub(el){
|
|
|
1366
1380
|
renderGhData(r);
|
|
1367
1381
|
});
|
|
1368
1382
|
}
|
|
1369
|
-
function loadGhIssues(){var inp=document.getElementById('ghRepo');if(!inp||!inp.value.trim())return;ghRepo=inp.value.trim();var el=document.getElementById('content');el.innerHTML='<div style="text-align:center;padding:40px"><div class="spinner"></div></div>';apiGet('/api/github/issues?repo='+encodeURIComponent(ghRepo)).then(function(r){if(ghData){ghData.issues=r.issues||[];ghData.prs=ghData.prs||[];ghData.repo=r.repo}else{ghData={issues:r.issues||[],prs:[],notifications:[]}}renderGitHub(document.getElementById('content'))})}
|
|
1383
|
+
function loadGhIssues(){var inp=document.getElementById('ghRepo');if(!inp||!inp.value.trim())return;ghRepo=inp.value.trim();apiPost('/api/config',{key:'github-repo',value:ghRepo}).catch(function(){});var el=document.getElementById('content');el.innerHTML='<div style="text-align:center;padding:40px"><div class="spinner"></div></div>';apiGet('/api/github/issues?repo='+encodeURIComponent(ghRepo)).then(function(r){if(ghData){ghData.issues=r.issues||[];ghData.prs=ghData.prs||[];ghData.repo=r.repo}else{ghData={issues:r.issues||[],prs:[],notifications:[]}}renderGitHub(document.getElementById('content'))})}
|
|
1370
1384
|
function loadGhPRs(){var inp=document.getElementById('ghRepo');if(!inp||!inp.value.trim())return;ghRepo=inp.value.trim();var el=document.getElementById('content');el.innerHTML='<div style="text-align:center;padding:40px"><div class="spinner"></div></div>';apiGet('/api/github/prs?repo='+encodeURIComponent(ghRepo)).then(function(r){if(ghData){ghData.prs=r.prs||[];ghData.issues=ghData.issues||[];ghData.repo=r.repo}else{ghData={prs:r.prs||[],issues:[],notifications:[]}}renderGitHub(document.getElementById('content'))})}
|
|
1371
1385
|
function ghMarkRead(){apiPost('/api/github/mark-read',{}).then(function(){if(ghData)ghData.notifications=[];renderGitHub(document.getElementById('content'))})}
|
|
1372
1386
|
|
|
1373
1387
|
// ---- NOTION ----
|
|
1374
1388
|
function renderNotion(el){
|
|
1375
1389
|
apiGet('/api/notion/search?q=').then(function(r){
|
|
1376
|
-
var
|
|
1377
|
-
|
|
1390
|
+
var isOk=!(r&&r.error);
|
|
1391
|
+
var banner=isOk?'':''+setupBanner('Notion','nha config set notion-token YOUR_INTEGRATION_TOKEN')+'<div style="color:var(--dim);font-size:12px;padding:8px 0">Get an Integration Token from notion.so/my-integrations → New integration → Internal → copy Secret</div>';
|
|
1392
|
+
var disconnectBtn=isOk?'<button onclick="disconnectService(\\x27notion-token\\x27,renderNotion)" style="background:var(--bg3);border:1px solid var(--red);color:var(--red);padding:4px 10px;border-radius:var(--r);font-size:11px;margin-bottom:12px">Disconnect Notion</button>':'';
|
|
1393
|
+
el.innerHTML=banner+disconnectBtn+'<div style="display:flex;gap:8px;margin-bottom:16px"><input type="text" id="notionQuery" placeholder="Search Notion pages..." style="flex:1;font-size:13px;padding:10px 14px" onkeydown="if(event.key===\\x27Enter\\x27)searchNotion()">'+(isOk?'<button onclick="searchNotion()" style="background:var(--green3);color:var(--bg);padding:8px 16px;border-radius:var(--r);font-weight:700;font-size:12px">Search</button>':'<button style="background:var(--bg3);color:var(--dim);padding:8px 16px;border-radius:var(--r);font-size:12px" disabled>Search</button>')+'</div><div id="notionResults"></div>';
|
|
1378
1394
|
}).catch(function(){
|
|
1379
|
-
el.innerHTML=setupBanner('Notion','nha config set notion-token YOUR_INTEGRATION_TOKEN')+'<div style="display:flex;gap:8px;margin-bottom:16px"><input type="text" id="notionQuery" placeholder="Search Notion pages..." style="flex:1;font-size:13px;padding:10px 14px"><button style="background:var(--
|
|
1395
|
+
el.innerHTML=setupBanner('Notion','nha config set notion-token YOUR_INTEGRATION_TOKEN')+'<div style="display:flex;gap:8px;margin-bottom:16px"><input type="text" id="notionQuery" placeholder="Search Notion pages..." style="flex:1;font-size:13px;padding:10px 14px"><button style="background:var(--bg3);color:var(--dim);padding:8px 16px;border-radius:var(--r);font-size:12px" disabled>Search</button></div>';
|
|
1380
1396
|
});
|
|
1381
1397
|
}
|
|
1382
1398
|
function searchNotion(){
|
|
@@ -1399,6 +1415,13 @@ function loadNotionPage(id){
|
|
|
1399
1415
|
}
|
|
1400
1416
|
|
|
1401
1417
|
// ---- SLACK ----
|
|
1418
|
+
function disconnectService(configKey,renderFn){
|
|
1419
|
+
if(!confirm('Remove this connection? You can reconnect anytime.'))return;
|
|
1420
|
+
apiPost('/api/config',{key:configKey,value:''}).then(function(){
|
|
1421
|
+
var el=document.getElementById('content');
|
|
1422
|
+
if(el&&renderFn)renderFn(el);
|
|
1423
|
+
}).catch(function(){});
|
|
1424
|
+
}
|
|
1402
1425
|
function setupBanner(service,cmd){return '<div style="display:flex;align-items:center;gap:12px;padding:12px 16px;background:var(--bg2);border:1px solid var(--border);border-left:3px solid var(--amber);border-radius:var(--r);margin-bottom:14px;font-size:12px"><span style="font-size:20px">🔒</span><div><div style="color:var(--fg);font-weight:600;margin-bottom:2px">'+esc(service)+' not configured</div><div style="color:var(--dim);font-family:var(--mono);font-size:11px">'+esc(cmd)+'</div></div></div>';}
|
|
1403
1426
|
var slackData=null;
|
|
1404
1427
|
function renderSlack(el){
|
|
@@ -1407,7 +1430,7 @@ function renderSlack(el){
|
|
|
1407
1430
|
if(r&&r.error){el.innerHTML=setupBanner('Slack','nha config set slack-token xoxb-YOUR_TOKEN')+'<div style="color:var(--dim);font-size:12px;padding:8px 0">Get a Bot Token from api.slack.com/apps → OAuth & Permissions → Bot Token Scopes: channels:read, channels:history, users:read</div>';return}
|
|
1408
1431
|
slackData=r;
|
|
1409
1432
|
var channels=r.channels||[];
|
|
1410
|
-
var h='<div class="section-title">Channels ('+channels.length+')</div>';
|
|
1433
|
+
var h='<div style="display:flex;align-items:center;margin-bottom:8px"><div class="section-title" style="margin:0;flex:1">Channels ('+channels.length+')</div><button onclick="disconnectService(\\x27slack-token\\x27,renderSlack)" style="background:var(--bg3);border:1px solid var(--red);color:var(--red);padding:4px 10px;border-radius:var(--r);font-size:11px">Disconnect</button></div>';
|
|
1411
1434
|
if(channels.length===0){h+='<div class="card" style="text-align:center;color:var(--dim);padding:20px">No channels found</div>'}
|
|
1412
1435
|
channels.forEach(function(c){h+='<div class="card" style="padding:10px 14px;cursor:pointer" onclick="loadSlackChannel(\\x27'+esc(c.id)+'\\x27,\\x27'+esc(c.name)+'\\x27)"><span style="color:var(--green);font-weight:700">#'+esc(c.name)+'</span> <span style="font-size:10px;color:var(--dim)">'+c.members+' members</span>'+(c.purpose?'<div style="font-size:11px;color:var(--dim);margin-top:2px">'+esc(c.purpose)+'</div>':'')+'</div>'});
|
|
1413
1436
|
h+='<div id="slackMessages"></div>';
|