nothumanallowed 10.3.0 → 10.3.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/ui.mjs +29 -3
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "10.3.
|
|
3
|
+
"version": "10.3.2",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 53 tools. Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, GitHub, Notion, Slack, voice chat, 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -383,17 +383,43 @@ export async function cmdUI(args) {
|
|
|
383
383
|
|
|
384
384
|
if (collabAction === 'send' && method === 'POST') {
|
|
385
385
|
const body = await parseBody(req);
|
|
386
|
-
//
|
|
387
|
-
|
|
386
|
+
// Encrypt with the same channel key used by CLI
|
|
387
|
+
const channelKey = crypto.createHash('sha256').update('alexandria-channel-key-v1').update(body.channelId).digest();
|
|
388
|
+
const nonce = crypto.randomBytes(12);
|
|
389
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', channelKey, nonce);
|
|
390
|
+
const encrypted = Buffer.concat([cipher.update(body.message, 'utf-8'), cipher.final()]);
|
|
391
|
+
const tag = cipher.getAuthTag();
|
|
392
|
+
const ciphertext = Buffer.concat([encrypted, tag]).toString('base64');
|
|
393
|
+
|
|
388
394
|
const r = await fetch(ALEX_API + '/channels/' + body.channelId + '/messages', {
|
|
389
395
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
390
|
-
body: JSON.stringify({ senderFingerprint: identity.fingerprint, nonce:
|
|
396
|
+
body: JSON.stringify({ senderFingerprint: identity.fingerprint, nonce: nonce.toString('base64'), ciphertext, type: 'text' }),
|
|
391
397
|
});
|
|
392
398
|
sendJSON(res, 200, await r.json());
|
|
393
399
|
logRequest(method, pathname, 200, Date.now() - start);
|
|
394
400
|
return;
|
|
395
401
|
}
|
|
396
402
|
|
|
403
|
+
if (collabAction === 'delete' && method === 'POST') {
|
|
404
|
+
const body = await parseBody(req);
|
|
405
|
+
// Remove from local channels file
|
|
406
|
+
const chFile = path.join(collabDir, 'channels.json');
|
|
407
|
+
let localChannels = [];
|
|
408
|
+
if (fs.existsSync(chFile)) { try { localChannels = JSON.parse(fs.readFileSync(chFile, 'utf-8')); } catch {} }
|
|
409
|
+
localChannels = localChannels.filter(c => c.id !== body.channelId);
|
|
410
|
+
fs.writeFileSync(chFile, JSON.stringify(localChannels, null, 2), { mode: 0o600 });
|
|
411
|
+
// Try to delete from server too
|
|
412
|
+
try {
|
|
413
|
+
await fetch(ALEX_API + '/channels/' + body.channelId, {
|
|
414
|
+
method: 'DELETE', headers: { 'Content-Type': 'application/json' },
|
|
415
|
+
body: JSON.stringify({ fingerprint: identity.fingerprint }),
|
|
416
|
+
});
|
|
417
|
+
} catch {}
|
|
418
|
+
sendJSON(res, 200, { ok: true });
|
|
419
|
+
logRequest(method, pathname, 200, Date.now() - start);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
397
423
|
if (collabAction === 'publish' && method === 'POST') {
|
|
398
424
|
const body = await parseBody(req);
|
|
399
425
|
// Load conversation and publish as public channel
|
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 = '10.3.
|
|
8
|
+
export const VERSION = '10.3.2';
|
|
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
|
@@ -1644,6 +1644,7 @@ function renderCollabChannelList(){
|
|
|
1644
1644
|
h+='<div onclick="collabSelect(\\x27'+ch.id+'\\x27)" style="padding:8px 12px;cursor:pointer;border-left:3px solid '+(active?'var(--amber)':'transparent')+';background:'+(active?'var(--bg2)':'transparent')+';margin-bottom:2px;border-radius:0 6px 6px 0">';
|
|
1645
1645
|
h+='<span style="font-size:12px;color:var(--fg)">'+esc(ch.name)+'</span>';
|
|
1646
1646
|
h+='<span style="font-size:9px;color:var(--dim);margin-left:8px">'+ch.id.slice(0,8)+'...</span>';
|
|
1647
|
+
h+='<button onclick="event.stopPropagation();collabDeleteChannel(\\x27'+ch.id+'\\x27)" style="float:right;background:none;border:none;color:var(--red);cursor:pointer;font-size:10px;font-family:var(--mono);opacity:0.5" title="Delete channel">del</button>';
|
|
1647
1648
|
h+='</div>';
|
|
1648
1649
|
}
|
|
1649
1650
|
el.innerHTML=h;
|
|
@@ -1675,6 +1676,18 @@ function collabJoinChannel(){
|
|
|
1675
1676
|
});
|
|
1676
1677
|
}
|
|
1677
1678
|
|
|
1679
|
+
function collabDeleteChannel(id){
|
|
1680
|
+
if(!confirm('Delete this channel? Messages will be lost.'))return;
|
|
1681
|
+
// Remove from local file
|
|
1682
|
+
collabChannels=collabChannels.filter(function(c){return c.id!==id});
|
|
1683
|
+
apiPost('/api/collab/channels',{id:'__delete__'+id}).catch(function(){});
|
|
1684
|
+
// Delete from server
|
|
1685
|
+
fetch(API+'/api/collab/delete',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({channelId:id})}).catch(function(){});
|
|
1686
|
+
if(collabActiveChannel===id)collabActiveChannel=null;
|
|
1687
|
+
renderCollabChannelList();
|
|
1688
|
+
var msgEl=document.getElementById('collabMessages');
|
|
1689
|
+
if(msgEl)msgEl.innerHTML='<div style="text-align:center;color:var(--dim);padding:40px;font-size:12px">Channel deleted</div>';
|
|
1690
|
+
}
|
|
1678
1691
|
function collabSelect(id){
|
|
1679
1692
|
collabActiveChannel=id;
|
|
1680
1693
|
collabLoadMessages();
|