let-them-talk 3.1.1 → 3.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/LICENSE +21 -0
- package/dashboard.html +4 -4
- package/dashboard.js +11 -4
- package/logo.png +0 -0
- package/package.json +11 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Dekelelz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dashboard.html
CHANGED
|
@@ -2810,7 +2810,7 @@ function renderAgents(agents) {
|
|
|
2810
2810
|
}
|
|
2811
2811
|
|
|
2812
2812
|
var avatarHtml = info.avatar
|
|
2813
|
-
? '<img class="agent-avatar-img" src="' + info.avatar + '" alt="' + escapeHtml(name) + '" onerror="this.style.display=\'none\'">'
|
|
2813
|
+
? '<img class="agent-avatar-img" src="' + escapeHtml(info.avatar) + '" alt="' + escapeHtml(name) + '" onerror="this.style.display=\'none\'">'
|
|
2814
2814
|
: '<div class="agent-avatar" style="background:' + color + '">' + initial(name) + '</div>';
|
|
2815
2815
|
var displayName = info.display_name || name;
|
|
2816
2816
|
var roleHtml = info.role ? '<span class="role-badge">' + escapeHtml(info.role) + '</span>' : '';
|
|
@@ -3755,7 +3755,7 @@ textarea.addEventListener('input', function() {
|
|
|
3755
3755
|
function getMsgAvatar(name, color) {
|
|
3756
3756
|
var agent = cachedAgents[name];
|
|
3757
3757
|
if (agent && agent.avatar) {
|
|
3758
|
-
return '<img class="msg-avatar-img" src="' + agent.avatar + '" alt="' + escapeHtml(name) + '" onerror="this.outerHTML=\'<div class="msg-avatar" style="background:' + color + '">' + initial(name) + '</div>\'">';
|
|
3758
|
+
return '<img class="msg-avatar-img" src="' + escapeHtml(agent.avatar) + '" alt="' + escapeHtml(name) + '" onerror="this.outerHTML=\'<div class="msg-avatar" style="background:' + color + '">' + initial(name) + '</div>\'">';
|
|
3759
3759
|
}
|
|
3760
3760
|
return '<div class="msg-avatar" style="background:' + color + '">' + initial(name) + '</div>';
|
|
3761
3761
|
}
|
|
@@ -4323,7 +4323,7 @@ function updateTypingIndicator(agents) {
|
|
|
4323
4323
|
var info = agents[keys[i]];
|
|
4324
4324
|
// Agent is alive, not listening, and was recently active (processing a message)
|
|
4325
4325
|
if (info.alive && !info.is_listening && info.status === 'active') {
|
|
4326
|
-
typing.push(info.display_name || keys[i]);
|
|
4326
|
+
typing.push(escapeHtml(info.display_name || keys[i]));
|
|
4327
4327
|
}
|
|
4328
4328
|
}
|
|
4329
4329
|
var bar = document.getElementById('typing-bar');
|
|
@@ -4729,7 +4729,7 @@ function doLaunch() {
|
|
|
4729
4729
|
}).then(function(r) { return r.json(); }).then(function(data) {
|
|
4730
4730
|
if (data.error) {
|
|
4731
4731
|
resultEl.className = 'launch-result error';
|
|
4732
|
-
resultEl.innerHTML = data.error;
|
|
4732
|
+
resultEl.innerHTML = escapeHtml(data.error);
|
|
4733
4733
|
return;
|
|
4734
4734
|
}
|
|
4735
4735
|
resultEl.className = 'launch-result success';
|
package/dashboard.js
CHANGED
|
@@ -3,7 +3,7 @@ const http = require('http');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
|
-
const { exec } = require('child_process');
|
|
6
|
+
const { exec, spawn } = require('child_process');
|
|
7
7
|
|
|
8
8
|
const PORT = parseInt(process.env.AGENT_BRIDGE_PORT || '3000', 10);
|
|
9
9
|
let LAN_MODE = process.env.AGENT_BRIDGE_LAN === 'true';
|
|
@@ -139,6 +139,9 @@ function getDefaultAvatar(name) {
|
|
|
139
139
|
function apiHistory(query) {
|
|
140
140
|
const projectPath = query.get('project') || null;
|
|
141
141
|
const branch = query.get('branch') || null;
|
|
142
|
+
if (branch && !/^[a-zA-Z0-9_-]{1,64}$/.test(branch)) {
|
|
143
|
+
return { error: 'Invalid branch name' };
|
|
144
|
+
}
|
|
142
145
|
const histFile = branch && branch !== 'main'
|
|
143
146
|
? filePath(`branch-${branch}-history.jsonl`, projectPath)
|
|
144
147
|
: filePath('history.jsonl', projectPath);
|
|
@@ -615,8 +618,7 @@ function apiLaunchAgent(body) {
|
|
|
615
618
|
|
|
616
619
|
// Try to launch terminal on Windows
|
|
617
620
|
if (process.platform === 'win32') {
|
|
618
|
-
|
|
619
|
-
exec(`start cmd /k "cd /d "${escapedDir}" && ${cliCmd}"`, { cwd: projectDir });
|
|
621
|
+
spawn('cmd', ['/c', 'start', 'cmd', '/k', `cd /d "${projectDir}" && ${cliCmd}`], { cwd: projectDir, shell: false, detached: true, stdio: 'ignore' });
|
|
620
622
|
return { success: true, launched: true, cli, project_dir: projectDir, prompt: launchPrompt };
|
|
621
623
|
}
|
|
622
624
|
|
|
@@ -662,7 +664,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
662
664
|
const allowedOrigin = `http://localhost:${PORT}`;
|
|
663
665
|
const reqOrigin = req.headers.origin;
|
|
664
666
|
if (LAN_MODE && reqOrigin) {
|
|
665
|
-
res.setHeader('Access-Control-Allow-Origin',
|
|
667
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
666
668
|
} else if (reqOrigin === allowedOrigin || reqOrigin === `http://127.0.0.1:${PORT}`) {
|
|
667
669
|
res.setHeader('Access-Control-Allow-Origin', reqOrigin);
|
|
668
670
|
}
|
|
@@ -794,6 +796,11 @@ const server = http.createServer(async (req, res) => {
|
|
|
794
796
|
else if (url.pathname === '/api/workspaces' && req.method === 'GET') {
|
|
795
797
|
const projectPath = url.searchParams.get('project') || null;
|
|
796
798
|
const agentParam = url.searchParams.get('agent');
|
|
799
|
+
if (agentParam && !/^[a-zA-Z0-9]{1,20}$/.test(agentParam)) {
|
|
800
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
801
|
+
res.end(JSON.stringify({ error: 'Invalid agent name' }));
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
797
804
|
const dataDir = resolveDataDir(projectPath);
|
|
798
805
|
const wsDir = path.join(dataDir, 'workspaces');
|
|
799
806
|
const result = {};
|
package/logo.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "let-them-talk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "MCP message broker + web dashboard for inter-agent communication. Let AI CLI agents talk to each other.",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,14 +9,20 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node server.js",
|
|
12
|
-
"dashboard": "node dashboard.js"
|
|
12
|
+
"dashboard": "node dashboard.js",
|
|
13
|
+
"test": "echo \"No tests yet\""
|
|
14
|
+
},
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=16.0.0"
|
|
13
17
|
},
|
|
14
18
|
"files": [
|
|
15
19
|
"server.js",
|
|
16
20
|
"dashboard.js",
|
|
17
21
|
"dashboard.html",
|
|
18
22
|
"cli.js",
|
|
19
|
-
"templates/"
|
|
23
|
+
"templates/",
|
|
24
|
+
"logo.png",
|
|
25
|
+
"LICENSE"
|
|
20
26
|
],
|
|
21
27
|
"keywords": [
|
|
22
28
|
"mcp",
|
|
@@ -33,7 +39,7 @@
|
|
|
33
39
|
],
|
|
34
40
|
"repository": {
|
|
35
41
|
"type": "git",
|
|
36
|
-
"url": "https://github.com/Dekelelz/let-them-talk.git"
|
|
42
|
+
"url": "git+https://github.com/Dekelelz/let-them-talk.git"
|
|
37
43
|
},
|
|
38
44
|
"homepage": "https://github.com/Dekelelz/let-them-talk",
|
|
39
45
|
"bugs": {
|
|
@@ -42,6 +48,6 @@
|
|
|
42
48
|
"author": "Dekelelz",
|
|
43
49
|
"license": "MIT",
|
|
44
50
|
"dependencies": {
|
|
45
|
-
"@modelcontextprotocol/sdk": "
|
|
51
|
+
"@modelcontextprotocol/sdk": "1.12.1"
|
|
46
52
|
}
|
|
47
53
|
}
|