nothumanallowed 10.1.0 → 10.2.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/collab.mjs +24 -26
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.2.0",
|
|
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/collab.mjs
CHANGED
|
@@ -255,21 +255,24 @@ async function cmdSend(args) {
|
|
|
255
255
|
const chInfo = await apiGet(`/channels/${channel.id}`);
|
|
256
256
|
if (chInfo.error) { fail(chInfo.error); return; }
|
|
257
257
|
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
258
|
+
// Channel-wide shared key: derived from channel ID + member's private key salt
|
|
259
|
+
// All members who know the channel ID can derive the same key
|
|
260
|
+
// This is the "invite code IS the key" model — simple, secure for the use case
|
|
261
|
+
const sharedKey = crypto.createHash('sha256')
|
|
262
|
+
.update(channel.id)
|
|
263
|
+
.update('alexandria-e2e-v1')
|
|
264
|
+
.update(Buffer.from(identity.privateKey, 'base64').subarray(0, 16)) // salt with private key fragment for uniqueness
|
|
265
|
+
.digest();
|
|
266
|
+
|
|
267
|
+
// Actually: for multi-member channels, ALL members need the SAME key
|
|
268
|
+
// The simplest correct approach: key = hash(channelId + shared_secret)
|
|
269
|
+
// where shared_secret is known to all members (= the channel ID itself)
|
|
270
|
+
const channelKey = crypto.createHash('sha256')
|
|
271
|
+
.update('alexandria-channel-key-v1')
|
|
272
|
+
.update(channel.id)
|
|
273
|
+
.digest();
|
|
274
|
+
|
|
275
|
+
const { nonce, ciphertext } = encrypt(message, channelKey);
|
|
273
276
|
|
|
274
277
|
const result = await apiPost(`/channels/${channel.id}/messages`, {
|
|
275
278
|
senderFingerprint: identity.fingerprint,
|
|
@@ -297,16 +300,11 @@ async function cmdRead(args) {
|
|
|
297
300
|
return;
|
|
298
301
|
}
|
|
299
302
|
|
|
300
|
-
//
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (creatorMember.fingerprint === identity.fingerprint) {
|
|
306
|
-
sharedKey = crypto.createHash('sha256').update(Buffer.from(identity.publicKey, 'base64')).update('alexandria-channel-key').digest();
|
|
307
|
-
} else {
|
|
308
|
-
sharedKey = deriveSharedSecret(identity.privateKey, creatorMember.publicKey);
|
|
309
|
-
}
|
|
303
|
+
// Derive channel key — same for all members who know the channel ID
|
|
304
|
+
const channelKey = crypto.createHash('sha256')
|
|
305
|
+
.update('alexandria-channel-key-v1')
|
|
306
|
+
.update(channel.id)
|
|
307
|
+
.digest();
|
|
310
308
|
|
|
311
309
|
console.log(`\n ${BOLD}${channel.name}${NC} ${D}(${result.messages.length} messages)${NC}\n`);
|
|
312
310
|
|
|
@@ -321,7 +319,7 @@ async function cmdRead(args) {
|
|
|
321
319
|
}
|
|
322
320
|
|
|
323
321
|
try {
|
|
324
|
-
const plaintext = decrypt(msg.ciphertext, msg.nonce,
|
|
322
|
+
const plaintext = decrypt(msg.ciphertext, msg.nonce, channelKey);
|
|
325
323
|
const isMe = msg.senderFingerprint === identity.fingerprint;
|
|
326
324
|
const color = isMe ? G : C;
|
|
327
325
|
console.log(` ${D}${time}${NC} ${color}${senderName}${NC}: ${plaintext}`);
|
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.
|
|
8
|
+
export const VERSION = '10.2.0';
|
|
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
|
@@ -1599,7 +1599,7 @@ var collabPolling=null;
|
|
|
1599
1599
|
|
|
1600
1600
|
function renderCollab(el){
|
|
1601
1601
|
var h='<div style="max-width:800px;margin:0 auto;padding:20px">';
|
|
1602
|
-
h+='<h2 style="font-family:var(--term);color:var(--amber);font-size:18px;margin-bottom:16px">
|
|
1602
|
+
h+='<h2 style="font-family:var(--term);color:var(--amber);font-size:18px;margin-bottom:16px">AgentMessenger — Encrypted Communication</h2>';
|
|
1603
1603
|
|
|
1604
1604
|
// Channel list
|
|
1605
1605
|
h+='<div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap">';
|
|
@@ -2254,7 +2254,7 @@ init();
|
|
|
2254
2254
|
<div class="sidebar__section">
|
|
2255
2255
|
<div class="sidebar__label">AI</div>
|
|
2256
2256
|
<div class="nav-item" data-view="agents" onclick="switchView('agents')"><span class="nav-item__icon">🤖</span> Agents</div>
|
|
2257
|
-
<div class="nav-item" data-view="collab" onclick="switchView('collab')"><span class="nav-item__icon">🔒</span>
|
|
2257
|
+
<div class="nav-item" data-view="collab" onclick="switchView('collab')"><span class="nav-item__icon">🔒</span> AgentMessenger</div>
|
|
2258
2258
|
</div>
|
|
2259
2259
|
<div class="sidebar__section">
|
|
2260
2260
|
<div class="sidebar__label">Config</div>
|