let-them-talk 3.1.0 → 3.1.1

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/dashboard.html CHANGED
@@ -3061,6 +3061,8 @@ function renderMessages(messages) {
3061
3061
  if (m.acked) badges += '<span class="badge badge-ack">ACK</span>';
3062
3062
  if (m.thread_id) badges += '<span class="badge badge-thread">Thread</span>';
3063
3063
 
3064
+ var msgAvatarHtml = getMsgAvatar(m.from, color);
3065
+
3064
3066
  if (isSystem) {
3065
3067
  html += '<div class="message system-msg' + newClass + '">' +
3066
3068
  '<div class="msg-body">' +
@@ -3068,8 +3070,6 @@ function renderMessages(messages) {
3068
3070
  '</div></div>';
3069
3071
  lastFrom = '';
3070
3072
  lastTo = '';
3071
- var msgAvatarHtml = getMsgAvatar(m.from, color);
3072
-
3073
3073
  } else if (m.type === 'handoff') {
3074
3074
  html += '<div class="message handoff-msg' + newClass + '">' +
3075
3075
  buildMsgActions(m.id) +
@@ -4205,7 +4205,13 @@ function addProject() {
4205
4205
  if (res.success) {
4206
4206
  input.value = '';
4207
4207
  input.classList.remove('visible');
4208
+ // Auto-switch to the newly added project
4209
+ activeProject = res.project.path;
4208
4210
  loadProjects();
4211
+ setTimeout(function() {
4212
+ document.getElementById('project-select').value = activeProject;
4213
+ switchProject();
4214
+ }, 200);
4209
4215
  } else {
4210
4216
  alert(res.error || 'Failed to add project');
4211
4217
  }
@@ -4599,6 +4605,8 @@ function renderPhoneModalContent() {
4599
4605
  }
4600
4606
 
4601
4607
  var url = 'http://' + lanState.lan_ip + ':' + lanState.port;
4608
+ // Include active project so the phone shows the same view
4609
+ if (activeProject) url += '?project=' + encodeURIComponent(activeProject);
4602
4610
  var qrUrl = 'https://api.qrserver.com/v1/create-qr-code/?size=180x180&color=58a6ff&bgcolor=0d1117&data=' + encodeURIComponent(url);
4603
4611
 
4604
4612
  el.innerHTML =
@@ -4614,6 +4622,7 @@ function renderPhoneModalContent() {
4614
4622
 
4615
4623
  function copyPhoneUrl() {
4616
4624
  var url = 'http://' + lanState.lan_ip + ':' + lanState.port;
4625
+ if (activeProject) url += '?project=' + encodeURIComponent(activeProject);
4617
4626
  navigator.clipboard.writeText(url).then(function() {
4618
4627
  var btn = document.querySelector('.phone-url-copy');
4619
4628
  btn.textContent = 'Copied!';
@@ -4786,6 +4795,16 @@ function initSSE() {
4786
4795
  }
4787
4796
 
4788
4797
  // ==================== INIT ====================
4798
+
4799
+ // Auto-select project from URL param (for phone access links)
4800
+ (function() {
4801
+ var params = new URLSearchParams(window.location.search);
4802
+ var projectFromUrl = params.get('project');
4803
+ if (projectFromUrl) {
4804
+ activeProject = projectFromUrl;
4805
+ }
4806
+ })();
4807
+
4789
4808
  loadProjects();
4790
4809
  poll();
4791
4810
  initSSE();
package/dashboard.js CHANGED
@@ -10,12 +10,17 @@ let LAN_MODE = process.env.AGENT_BRIDGE_LAN === 'true';
10
10
 
11
11
  function getLanIP() {
12
12
  const interfaces = os.networkInterfaces();
13
+ let fallback = null;
13
14
  for (const name of Object.keys(interfaces)) {
14
15
  for (const iface of interfaces[name]) {
15
- if (iface.family === 'IPv4' && !iface.internal) return iface.address;
16
+ if (iface.family === 'IPv4' && !iface.internal) {
17
+ // Prefer real LAN IPs (192.168.x, 10.x, 172.16-31.x) over link-local (169.254.x)
18
+ if (!iface.address.startsWith('169.254.')) return iface.address;
19
+ if (!fallback) fallback = iface.address;
20
+ }
16
21
  }
17
22
  }
18
- return null;
23
+ return fallback;
19
24
  }
20
25
  const DEFAULT_DATA_DIR = process.env.AGENT_BRIDGE_DATA || path.join(process.cwd(), '.agent-bridge');
21
26
  const HTML_FILE = path.join(__dirname, 'dashboard.html');
@@ -306,6 +311,14 @@ function apiAddProject(body) {
306
311
  const name = body.name || path.basename(absPath);
307
312
  if (projects.find(p => p.path === absPath)) return { error: 'Project already added' };
308
313
 
314
+ // Create .agent-bridge directory if it doesn't exist
315
+ const abDir = path.join(absPath, '.agent-bridge');
316
+ if (!fs.existsSync(abDir)) fs.mkdirSync(abDir, { recursive: true });
317
+
318
+ // Set up MCP config so agents can use it
319
+ const serverPath = path.join(__dirname, 'server.js').replace(/\\/g, '/');
320
+ ensureMCPConfig('claude', serverPath, absPath);
321
+
309
322
  projects.push({ name, path: absPath, added_at: new Date().toISOString() });
310
323
  saveProjects(projects);
311
324
  return { success: true, project: { name, path: absPath } };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "let-them-talk",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
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": {