botmux 2.13.2 → 2.15.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.
Files changed (87) hide show
  1. package/dist/cli.js +56 -11
  2. package/dist/cli.js.map +1 -1
  3. package/dist/core/command-handler.d.ts.map +1 -1
  4. package/dist/core/command-handler.js +10 -4
  5. package/dist/core/command-handler.js.map +1 -1
  6. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  7. package/dist/core/dashboard-ipc-server.js +65 -3
  8. package/dist/core/dashboard-ipc-server.js.map +1 -1
  9. package/dist/core/dashboard-rows.d.ts.map +1 -1
  10. package/dist/core/dashboard-rows.js +6 -1
  11. package/dist/core/dashboard-rows.js.map +1 -1
  12. package/dist/core/scheduler.d.ts +1 -0
  13. package/dist/core/scheduler.d.ts.map +1 -1
  14. package/dist/core/scheduler.js +1 -0
  15. package/dist/core/scheduler.js.map +1 -1
  16. package/dist/core/session-manager.d.ts.map +1 -1
  17. package/dist/core/session-manager.js +90 -52
  18. package/dist/core/session-manager.js.map +1 -1
  19. package/dist/core/types.d.ts +18 -2
  20. package/dist/core/types.d.ts.map +1 -1
  21. package/dist/core/types.js +14 -3
  22. package/dist/core/types.js.map +1 -1
  23. package/dist/core/worker-pool.d.ts.map +1 -1
  24. package/dist/core/worker-pool.js +22 -22
  25. package/dist/core/worker-pool.js.map +1 -1
  26. package/dist/daemon.d.ts.map +1 -1
  27. package/dist/daemon.js +185 -90
  28. package/dist/daemon.js.map +1 -1
  29. package/dist/dashboard/operator-selector.d.ts +17 -0
  30. package/dist/dashboard/operator-selector.d.ts.map +1 -0
  31. package/dist/dashboard/operator-selector.js +37 -0
  32. package/dist/dashboard/operator-selector.js.map +1 -0
  33. package/dist/dashboard/web/groups.d.ts.map +1 -1
  34. package/dist/dashboard/web/groups.js +61 -7
  35. package/dist/dashboard/web/groups.js.map +1 -1
  36. package/dist/dashboard-web/app.js +60 -53
  37. package/dist/dashboard-web/style.css +10 -1
  38. package/dist/dashboard.js +119 -34
  39. package/dist/dashboard.js.map +1 -1
  40. package/dist/im/lark/card-handler.js +8 -8
  41. package/dist/im/lark/card-handler.js.map +1 -1
  42. package/dist/im/lark/client.d.ts +27 -0
  43. package/dist/im/lark/client.d.ts.map +1 -1
  44. package/dist/im/lark/client.js +102 -8
  45. package/dist/im/lark/client.js.map +1 -1
  46. package/dist/im/lark/event-dispatcher.d.ts +42 -4
  47. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  48. package/dist/im/lark/event-dispatcher.js +121 -47
  49. package/dist/im/lark/event-dispatcher.js.map +1 -1
  50. package/dist/services/groups-store.d.ts +22 -0
  51. package/dist/services/groups-store.d.ts.map +1 -1
  52. package/dist/services/groups-store.js +39 -1
  53. package/dist/services/groups-store.js.map +1 -1
  54. package/dist/services/schedule-store.d.ts +1 -0
  55. package/dist/services/schedule-store.d.ts.map +1 -1
  56. package/dist/services/schedule-store.js +1 -0
  57. package/dist/services/schedule-store.js.map +1 -1
  58. package/dist/services/session-store.d.ts +12 -0
  59. package/dist/services/session-store.d.ts.map +1 -1
  60. package/dist/services/session-store.js +19 -2
  61. package/dist/services/session-store.js.map +1 -1
  62. package/dist/setup/detect-platform.d.ts +14 -0
  63. package/dist/setup/detect-platform.d.ts.map +1 -0
  64. package/dist/setup/detect-platform.js +139 -0
  65. package/dist/setup/detect-platform.js.map +1 -0
  66. package/dist/setup/ensure-fonts.d.ts +13 -0
  67. package/dist/setup/ensure-fonts.d.ts.map +1 -0
  68. package/dist/setup/ensure-fonts.js +225 -0
  69. package/dist/setup/ensure-fonts.js.map +1 -0
  70. package/dist/setup/ensure-tmux.d.ts +11 -0
  71. package/dist/setup/ensure-tmux.d.ts.map +1 -0
  72. package/dist/setup/ensure-tmux.js +151 -0
  73. package/dist/setup/ensure-tmux.js.map +1 -0
  74. package/dist/setup/index.d.ts +9 -0
  75. package/dist/setup/index.d.ts.map +1 -0
  76. package/dist/setup/index.js +35 -0
  77. package/dist/setup/index.js.map +1 -0
  78. package/dist/types.d.ts +12 -0
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/utils/bot-mention-dedup.d.ts +26 -0
  81. package/dist/utils/bot-mention-dedup.d.ts.map +1 -0
  82. package/dist/utils/bot-mention-dedup.js +56 -0
  83. package/dist/utils/bot-mention-dedup.js.map +1 -0
  84. package/dist/utils/screenshot-renderer.d.ts.map +1 -1
  85. package/dist/utils/screenshot-renderer.js +12 -5
  86. package/dist/utils/screenshot-renderer.js.map +1 -1
  87. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- "use strict";(()=>{var v=class{sessions=new Map;schedules=new Map;online=!0;listeners=new Set;upsertSessions(t){for(let i of t)this.sessions.set(i.sessionId,i);this.emit()}upsertSchedules(t){for(let i of t)this.schedules.set(i.id,i);this.emit()}applySse(t,i){if(t==="session.spawned")this.sessions.set(i.session.sessionId,i.session);else if(t==="session.update"){let u=this.sessions.get(i.sessionId);u&&this.sessions.set(i.sessionId,{...u,...i.patch})}else if(t==="session.exited"){let u=this.sessions.get(i.sessionId);u&&this.sessions.set(i.sessionId,{...u,status:"closed"})}else if(t==="schedule.created")this.schedules.set(i.schedule.id,i.schedule);else if(t==="schedule.updated"){let u=this.schedules.get(i.id);u&&this.schedules.set(i.id,{...u,...i.patch})}else if(t==="schedule.deleted")this.schedules.delete(i.id);else return;this.emit()}setOnline(t){this.online!==t&&(this.online=t,this.emit())}on(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(){for(let t of this.listeners)t()}},m=new v;async function A(){let[n,t]=await Promise.all([fetch("/api/sessions").then(f=>f.json()),fetch("/api/schedules").then(f=>f.json())]);m.upsertSessions(n.sessions??[]),m.upsertSchedules(t.schedules??[]);let i=new EventSource("/events"),u=["session.spawned","session.update","session.exited","schedule.created","schedule.updated","schedule.deleted","schedule.fired","heartbeat"];for(let f of u)i.addEventListener(f,s=>{try{let h=JSON.parse(s.data);m.applySse(f,h.body??h)}catch{}});i.onerror=()=>m.setOnline(!1),i.onopen=()=>m.setOnline(!0)}var _=`
1
+ "use strict";(()=>{var A=class{sessions=new Map;schedules=new Map;online=!0;listeners=new Set;upsertSessions(t){for(let r of t)this.sessions.set(r.sessionId,r);this.emit()}upsertSchedules(t){for(let r of t)this.schedules.set(r.id,r);this.emit()}applySse(t,r){if(t==="session.spawned")this.sessions.set(r.session.sessionId,r.session);else if(t==="session.update"){let u=this.sessions.get(r.sessionId);u&&this.sessions.set(r.sessionId,{...u,...r.patch})}else if(t==="session.exited"){let u=this.sessions.get(r.sessionId);u&&this.sessions.set(r.sessionId,{...u,status:"closed"})}else if(t==="schedule.created")this.schedules.set(r.schedule.id,r.schedule);else if(t==="schedule.updated"){let u=this.schedules.get(r.id);u&&this.schedules.set(r.id,{...u,...r.patch})}else if(t==="schedule.deleted")this.schedules.delete(r.id);else return;this.emit()}setOnline(t){this.online!==t&&(this.online=t,this.emit())}on(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(){for(let t of this.listeners)t()}},b=new A;async function N(){let[o,t]=await Promise.all([fetch("/api/sessions").then(g=>g.json()),fetch("/api/schedules").then(g=>g.json())]);b.upsertSessions(o.sessions??[]),b.upsertSchedules(t.schedules??[]);let r=new EventSource("/events"),u=["session.spawned","session.update","session.exited","schedule.created","schedule.updated","schedule.deleted","schedule.fired","heartbeat"];for(let g of u)r.addEventListener(g,n=>{try{let f=JSON.parse(n.data);b.applySse(g,f.body??f)}catch{}});r.onerror=()=>b.setOnline(!1),r.onopen=()=>b.setOnline(!0)}var G=`
2
2
  <form id="filters" class="filters">
3
3
  <input type="search" name="q" placeholder="search workingDir / title / ids" />
4
4
  <select name="cli" multiple size="4">
@@ -30,34 +30,34 @@
30
30
  <tbody></tbody>
31
31
  </table>
32
32
  <dialog id="drawer"></dialog>
33
- `;function q(n){if(!n)return"-";let t=Date.now()-n;return t<6e4?"now":t<36e5?Math.floor(t/6e4)+"m":t<864e5?Math.floor(t/36e5)+"h":Math.floor(t/864e5)+"d"}function p(n){return n.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}var j="\u{1FA9E}",L="\u{1F4CD}",G="\u{1F5A5}\uFE0F";function N(n){n.innerHTML=_;let t=n.querySelector("#sessions-table tbody"),i=n.querySelector("#filters"),u=n.querySelector("#drawer");function f(e){return`<tr data-id="${p(e.sessionId)}">
34
- <td>${p(e.botName??"")}</td>
35
- <td><span class="badge cli-${p(e.cliId??"unknown")}">${p(e.cliId??"unknown")}</span></td>
36
- <td><span class="status status-${p(e.status)}">${p(e.status)}</span></td>
37
- <td>${p((e.title??"").slice(0,40))}</td>
38
- <td title="${p(e.workingDir??"")}">${p((e.workingDir??"").slice(-30))}</td>
39
- <td>${q(e.spawnedAt)}</td>
40
- <td>${q(e.lastMessageAt)}</td>
41
- <td>${e.adopt?j:""}</td>
33
+ `;function R(o){if(!o)return"-";let t=Date.now()-o;return t<6e4?"now":t<36e5?Math.floor(t/6e4)+"m":t<864e5?Math.floor(t/36e5)+"h":Math.floor(t/864e5)+"d"}function h(o){return o.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}var J="\u{1FA9E}",M="\u{1F4CD}",z="\u{1F5A5}\uFE0F";function D(o){o.innerHTML=G;let t=o.querySelector("#sessions-table tbody"),r=o.querySelector("#filters"),u=o.querySelector("#drawer");function g(e){return`<tr data-id="${h(e.sessionId)}">
34
+ <td>${h(e.botName??"")}</td>
35
+ <td><span class="badge cli-${h(e.cliId??"unknown")}">${h(e.cliId??"unknown")}</span></td>
36
+ <td><span class="status status-${h(e.status)}">${h(e.status)}</span></td>
37
+ <td>${h((e.title??"").slice(0,40))}</td>
38
+ <td title="${h(e.workingDir??"")}">${h((e.workingDir??"").slice(-30))}</td>
39
+ <td>${R(e.spawnedAt)}</td>
40
+ <td>${R(e.lastMessageAt)}</td>
41
+ <td>${e.adopt?J:""}</td>
42
42
  <td><button class="open">\u22EF</button></td>
43
- </tr>`}function s(){let e=new FormData(i),l=(e.get("q")??"").toLowerCase(),a=e.getAll("cli"),r=e.get("status"),d=e.get("adopt"),g=!!e.get("active");return[...m.sessions.values()].filter(o=>!a.length||a.includes(o.cliId??"unknown")).filter(o=>!r||o.status===r).filter(o=>!d||d==="yes"==!!o.adopt).filter(o=>!g||o.status!=="closed").filter(o=>!l||JSON.stringify(o).toLowerCase().includes(l)).sort((o,b)=>(b.lastMessageAt??0)-(o.lastMessageAt??0))}function h(){t.innerHTML=s().map(f).join("")}function w(e){let l=e.status==="closed";u.innerHTML=`
43
+ </tr>`}function n(){let e=new FormData(r),p=(e.get("q")??"").toLowerCase(),i=e.getAll("cli"),s=e.get("status"),a=e.get("adopt"),$=!!e.get("active");return[...b.sessions.values()].filter(l=>!i.length||i.includes(l.cliId??"unknown")).filter(l=>!s||l.status===s).filter(l=>!a||a==="yes"==!!l.adopt).filter(l=>!$||l.status!=="closed").filter(l=>!p||JSON.stringify(l).toLowerCase().includes(p)).sort((l,c)=>(c.lastMessageAt??0)-(l.lastMessageAt??0))}function f(){t.innerHTML=n().map(g).join("")}function w(e){let p=e.status==="closed";u.innerHTML=`
44
44
  <article>
45
45
  <header>
46
- <h3>${p(e.title??e.sessionId)}</h3>
47
- <code>${p(e.sessionId)}</code> <button data-copy="${p(e.sessionId)}">copy</button>
46
+ <h3>${h(e.title??e.sessionId)}</h3>
47
+ <code>${h(e.sessionId)}</code> <button data-copy="${h(e.sessionId)}">copy</button>
48
48
  </header>
49
- <p><b>bot:</b> ${p(e.botName??"-")} \xB7 <b>cli:</b> ${p(e.cliId??"?")} \xB7 <b>status:</b> ${p(e.status)}</p>
50
- <p><b>chatId:</b> <code>${p(e.chatId)}</code> <button data-copy="${p(e.chatId)}">copy</button></p>
51
- <p><b>rootMessageId:</b> <code>${p(e.rootMessageId??"")}</code> <button data-copy="${p(e.rootMessageId??"")}">copy</button></p>
52
- ${e.threadId?`<p><b>threadId:</b> <code>${p(e.threadId)}</code></p>`:""}
53
- <p><b>workingDir:</b> ${p(e.workingDir??"-")}</p>
49
+ <p><b>bot:</b> ${h(e.botName??"-")} \xB7 <b>cli:</b> ${h(e.cliId??"?")} \xB7 <b>status:</b> ${h(e.status)}</p>
50
+ <p><b>chatId:</b> <code>${h(e.chatId)}</code> <button data-copy="${h(e.chatId)}">copy</button></p>
51
+ <p><b>rootMessageId:</b> <code>${h(e.rootMessageId??"")}</code> <button data-copy="${h(e.rootMessageId??"")}">copy</button></p>
52
+ ${e.threadId?`<p><b>threadId:</b> <code>${h(e.threadId)}</code></p>`:""}
53
+ <p><b>workingDir:</b> ${h(e.workingDir??"-")}</p>
54
54
  <div class="actions">
55
- <button id="locate-btn" type="button">${L} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898</button>
56
- ${e.webPort?`<a class="btn-link" href="http://${p(location.hostname)}:${e.webPort}" target="_blank">${G} \u6253\u5F00 xterm</a>`:""}
57
- ${l?"":'<button id="close-btn" type="button" class="contrast">\u5173\u95ED\u4F1A\u8BDD</button>'}
55
+ <button id="locate-btn" type="button">${M} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898</button>
56
+ ${e.webPort?`<a class="btn-link" href="http://${h(location.hostname)}:${e.webPort}" target="_blank">${z} \u6253\u5F00 xterm</a>`:""}
57
+ ${p?"":'<button id="close-btn" type="button" class="contrast">\u5173\u95ED\u4F1A\u8BDD</button>'}
58
58
  </div>
59
59
  <form method="dialog"><button>\u5173\u95ED</button></form>
60
- </article>`,u.querySelectorAll("[data-copy]").forEach(d=>{d.onclick=()=>{navigator.clipboard.writeText(d.dataset.copy??""),d.textContent="copied",setTimeout(()=>{d.textContent="copy"},800)}});let a=u.querySelector("#locate-btn");a&&(a.onclick=async()=>{a.disabled=!0,a.textContent=`${L} \u53D1\u9001\u4E2D...`;try{let d=await fetch(`/api/sessions/${encodeURIComponent(e.sessionId)}/locate`,{method:"POST"}),g=await d.json();if(g.ok){let o=30;a.textContent=`${L} (\u51B7\u5374 ${o}s)`;let b=setInterval(()=>{o-=1,o<=0?(clearInterval(b),a.disabled=!1,a.textContent=`${L} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898`):a.textContent=`${L} (\u51B7\u5374 ${o}s)`},1e3)}else{let o=g.error??d.status;alert("Locate failed: "+o),a.disabled=!1,a.textContent=`${L} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898`}}catch(d){alert("Locate error: "+d),a.disabled=!1,a.textContent=`${L} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898`}});let r=u.querySelector("#close-btn");r&&(r.onclick=async()=>{if(confirm("\u5173\u95ED\u8FD9\u4E2A\u4F1A\u8BDD?")){r.disabled=!0;try{await fetch(`/api/sessions/${encodeURIComponent(e.sessionId)}/close`,{method:"POST"})}finally{u.close()}}}),u.showModal()}t.addEventListener("click",e=>{let l=e.target.closest("tr[data-id]");if(!l)return;let a=l.dataset.id,r=m.sessions.get(a);r&&w(r)}),i.addEventListener("input",h),m.on(h),h()}var J=`
60
+ </article>`,u.querySelectorAll("[data-copy]").forEach(a=>{a.onclick=()=>{navigator.clipboard.writeText(a.dataset.copy??""),a.textContent="copied",setTimeout(()=>{a.textContent="copy"},800)}});let i=u.querySelector("#locate-btn");i&&(i.onclick=async()=>{i.disabled=!0,i.textContent=`${M} \u53D1\u9001\u4E2D...`;try{let a=await fetch(`/api/sessions/${encodeURIComponent(e.sessionId)}/locate`,{method:"POST"}),$=await a.json();if($.ok){let l=30;i.textContent=`${M} (\u51B7\u5374 ${l}s)`;let c=setInterval(()=>{l-=1,l<=0?(clearInterval(c),i.disabled=!1,i.textContent=`${M} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898`):i.textContent=`${M} (\u51B7\u5374 ${l}s)`},1e3)}else{let l=$.error??a.status;alert("Locate failed: "+l),i.disabled=!1,i.textContent=`${M} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898`}}catch(a){alert("Locate error: "+a),i.disabled=!1,i.textContent=`${M} \u5B9A\u4F4D\u5230\u98DE\u4E66\u8BDD\u9898`}});let s=u.querySelector("#close-btn");s&&(s.onclick=async()=>{if(confirm("\u5173\u95ED\u8FD9\u4E2A\u4F1A\u8BDD?")){s.disabled=!0;try{await fetch(`/api/sessions/${encodeURIComponent(e.sessionId)}/close`,{method:"POST"})}finally{u.close()}}}),u.showModal()}t.addEventListener("click",e=>{let p=e.target.closest("tr[data-id]");if(!p)return;let i=p.dataset.id,s=b.sessions.get(i);s&&w(s)}),r.addEventListener("input",f),b.on(f),f()}var W=`
61
61
  <form id="sched-filters" class="filters">
62
62
  <input type="search" name="q" placeholder="search name / prompt / workingDir" />
63
63
  <select name="kind">
@@ -75,19 +75,19 @@
75
75
  </tr></thead>
76
76
  <tbody id="schedules-tbody"></tbody>
77
77
  </table>
78
- `;function E(n){return n.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}function B(n){if(!n)return"\u2014";try{return new Date(n).toLocaleString()}catch{return n}}function D(n){n.innerHTML=J;let t=n.querySelector("#schedules-tbody"),i=n.querySelector("#sched-filters");function u(){let s=new FormData(i),h=(s.get("q")??"").toLowerCase(),w=s.get("kind"),e=!!s.get("enabled");return[...m.schedules.values()].filter(l=>!w||l.parsed?.kind===w).filter(l=>!e||l.enabled).filter(l=>!h||JSON.stringify(l).toLowerCase().includes(h)).sort((l,a)=>{if(l.enabled!==a.enabled)return l.enabled?-1:1;let r=l.nextRunAt?Date.parse(l.nextRunAt):1/0,d=a.nextRunAt?Date.parse(a.nextRunAt):1/0;return r-d})}function f(){t.innerHTML=u().map(s=>`<tr data-id="${E(s.id)}">
79
- <td>${E(s.name??s.id)}</td>
80
- <td>${E(s.botName??s.larkAppId??"-")}</td>
81
- <td><code>${E(s.parsed?.display??"?")}</code></td>
82
- <td>${B(s.nextRunAt)}</td>
83
- <td>${B(s.lastRunAt)} ${s.lastStatus==="error"?"\u26A0\uFE0F":""}</td>
84
- <td>${s.repeat?`${s.repeat.completed}/${s.repeat.times??"\u221E"}`:"\u2014"}</td>
85
- <td>${s.enabled?"\u2713":"\u2717"}</td>
78
+ `;function C(o){return o.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}function O(o){if(!o)return"\u2014";try{return new Date(o).toLocaleString()}catch{return o}}function P(o){o.innerHTML=W;let t=o.querySelector("#schedules-tbody"),r=o.querySelector("#sched-filters");function u(){let n=new FormData(r),f=(n.get("q")??"").toLowerCase(),w=n.get("kind"),e=!!n.get("enabled");return[...b.schedules.values()].filter(p=>!w||p.parsed?.kind===w).filter(p=>!e||p.enabled).filter(p=>!f||JSON.stringify(p).toLowerCase().includes(f)).sort((p,i)=>{if(p.enabled!==i.enabled)return p.enabled?-1:1;let s=p.nextRunAt?Date.parse(p.nextRunAt):1/0,a=i.nextRunAt?Date.parse(i.nextRunAt):1/0;return s-a})}function g(){t.innerHTML=u().map(n=>`<tr data-id="${C(n.id)}">
79
+ <td>${C(n.name??n.id)}</td>
80
+ <td>${C(n.botName??n.larkAppId??"-")}</td>
81
+ <td><code>${C(n.parsed?.display??"?")}</code></td>
82
+ <td>${O(n.nextRunAt)}</td>
83
+ <td>${O(n.lastRunAt)} ${n.lastStatus==="error"?"\u26A0\uFE0F":""}</td>
84
+ <td>${n.repeat?`${n.repeat.completed}/${n.repeat.times??"\u221E"}`:"\u2014"}</td>
85
+ <td>${n.enabled?"\u2713":"\u2717"}</td>
86
86
  <td class="actions-cell">
87
87
  <button data-op="run" type="button">Run now</button>
88
- ${s.enabled?'<button data-op="pause" type="button">Pause</button>':'<button data-op="resume" type="button">Resume</button>'}
88
+ ${n.enabled?'<button data-op="pause" type="button">Pause</button>':'<button data-op="resume" type="button">Resume</button>'}
89
89
  </td>
90
- </tr>`).join("")||'<tr><td colspan="8" class="empty">No schedules.</td></tr>'}t.addEventListener("click",async s=>{let h=s.target.closest("button[data-op]");if(!h)return;let w=h.closest("tr[data-id]");if(!w)return;let e=w.dataset.id,l=h.dataset.op;h.disabled=!0;let a=h.textContent;h.textContent="...";try{let r=await fetch(`/api/schedules/${encodeURIComponent(e)}/${l}`,{method:"POST"}),d=await r.json().catch(()=>({}));(!r.ok||d.ok===!1)&&alert(`Failed: ${r.status} ${d?.error??""}`.trim())}catch(r){alert("Network error: "+r)}finally{h.disabled=!1,h.textContent=a}}),i.addEventListener("input",f),m.on(f),f()}var I={chats:[],bots:[]},U=`
90
+ </tr>`).join("")||'<tr><td colspan="8" class="empty">No schedules.</td></tr>'}t.addEventListener("click",async n=>{let f=n.target.closest("button[data-op]");if(!f)return;let w=f.closest("tr[data-id]");if(!w)return;let e=w.dataset.id,p=f.dataset.op;f.disabled=!0;let i=f.textContent;f.textContent="...";try{let s=await fetch(`/api/schedules/${encodeURIComponent(e)}/${p}`,{method:"POST"}),a=await s.json().catch(()=>({}));(!s.ok||a.ok===!1)&&alert(`Failed: ${s.status} ${a?.error??""}`.trim())}catch(s){alert("Network error: "+s)}finally{f.disabled=!1,f.textContent=i}}),r.addEventListener("input",g),b.on(g),g()}var T={chats:[],bots:[]},K=`
91
91
  <form id="g-filters" class="filters">
92
92
  <input type="search" name="q" placeholder="search chat name / id / owner" />
93
93
  <label><input type="checkbox" name="missing"> missing-bot only</label>
@@ -99,7 +99,7 @@
99
99
  <tbody id="g-body"></tbody>
100
100
  </table>
101
101
  <dialog id="g-drawer"></dialog>
102
- `;function y(n){return n.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}async function H(){I=await(await fetch("/api/groups")).json()}async function P(n){n.innerHTML=U;let t=n.querySelector("#g-head"),i=n.querySelector("#g-body"),u=n.querySelector("#g-filters"),f=n.querySelector("#g-refresh"),s=n.querySelector("#g-drawer");f.onclick=async()=>{f.disabled=!0;try{await H(),l()}finally{f.disabled=!1}};let h=n.querySelector("#g-create");h.onclick=()=>w(),await H();function w(){let a=I.bots;if(a.length===0){alert("No bots online. Restart the daemon first.");return}s.innerHTML=`
102
+ `;function m(o){return o.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}async function x(){T=await(await fetch("/api/groups")).json()}async function j(o){o.innerHTML=K;let t=o.querySelector("#g-head"),r=o.querySelector("#g-body"),u=o.querySelector("#g-filters"),g=o.querySelector("#g-refresh"),n=o.querySelector("#g-drawer");g.onclick=async()=>{g.disabled=!0;try{await x(),i()}finally{g.disabled=!1}};let f=o.querySelector("#g-create");f.onclick=()=>w(),await x();function w(){let s=T.bots;if(s.length===0){alert("No bots online. Restart the daemon first.");return}n.innerHTML=`
103
103
  <article>
104
104
  <header><h3>Create new group</h3></header>
105
105
  <p>Pick bots to invite. The dashboard auto-selects an online daemon as the chat creator/owner; the rest are added as members in the same call.</p>
@@ -110,10 +110,10 @@
110
110
  </label>
111
111
  <fieldset>
112
112
  <legend>Bots</legend>
113
- ${a.map(r=>`
113
+ ${s.map(a=>`
114
114
  <label class="checkbox-row">
115
- <input type="checkbox" name="bot" value="${y(r.larkAppId)}">
116
- ${y(r.botName??r.larkAppId)} <small>(${y(r.larkAppId)})</small>
115
+ <input type="checkbox" name="bot" value="${m(a.larkAppId)}">
116
+ ${m(a.botName??a.larkAppId)} <small>(${m(a.larkAppId)})</small>
117
117
  </label>
118
118
  `).join("")}
119
119
  </fieldset>
@@ -122,30 +122,37 @@
122
122
  <button type="button" id="g-create-cancel">Cancel</button>
123
123
  </div>
124
124
  </form>
125
- </article>`,s.showModal(),s.querySelector("#g-create-cancel").onclick=()=>s.close(),s.querySelector("#g-createform").onsubmit=async r=>{r.preventDefault();let d=new FormData(r.target),g=(d.get("name")??"").trim(),o=d.getAll("bot");if(o.length===0){alert("Pick at least one bot.");return}let b=r.target.querySelector("button[type=submit]");b&&(b.disabled=!0,b.textContent="Creating...");try{let c=await fetch("/api/groups/create",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:g||void 0,larkAppIds:o})}),$=await c.json();if($.ok&&$.chatId){let M=$.invalidBotIds??[],k=M.length?`
126
-
127
- Invalid bot ids: ${M.join(", ")}`:"";alert(`Group created.
128
- chatId: ${$.chatId}
129
- creator: ${$.creator??"?"}${k}`),await H(),l()}else alert(`Failed: ${$.error??c.status}`)}catch(c){alert("Network error: "+c)}finally{s.close()}}}function e(){t.innerHTML=`<tr>
125
+ </article>`,n.showModal(),n.querySelector("#g-create-cancel").onclick=()=>n.close(),n.querySelector("#g-createform").onsubmit=async a=>{a.preventDefault();let $=new FormData(a.target),l=($.get("name")??"").trim(),c=$.getAll("bot");if(c.length===0){alert("Pick at least one bot.");return}let y=a.target.querySelector("button[type=submit]");y&&(y.disabled=!0,y.textContent="Creating...");try{let d=await fetch("/api/groups/create",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:l||void 0,larkAppIds:c})}),I=await d.json();I.ok&&I.chatId?(e(I),x().then(i).catch(()=>{})):(alert(`Failed: ${I.error??d.status}`),n.close())}catch(d){alert("Network error: "+d),n.close()}}}function e(s){let a=String(s.chatId),$=`https://applink.feishu.cn/client/chat/open?openChatId=${encodeURIComponent(a)}`,l=s.invalidBotIds??[],c=s.invalidUserIds??[],y=s.autoInvitedOpenId,d=!!s.autoInviteRejected,I=s.ownerTransferredTo,v=s.transferError,L=s.notifyMessageId,k=s.notifyError,E;if(y){let H=I?"<br><small>\u7FA4\u4E3B\u5DF2\u4ECE\u673A\u5668\u4EBA\u8F6C\u8BA9\u7ED9\u4F60\u3002</small>":v?`<br><small class="hint-warn-inline">\u26A0 \u81EA\u52A8\u8F6C\u8BA9\u7FA4\u4E3B\u5931\u8D25\uFF08${m(v)}\uFF09\uFF0C\u4F60\u73B0\u5728\u662F\u6210\u5458\u4F46\u7FA4\u4E3B\u4ECD\u662F\u673A\u5668\u4EBA\u3002</small>`:"",U=L?`<br><small>\u673A\u5668\u4EBA\u5DF2\u5728\u7FA4\u91CC @ \u4E86\u4F60\uFF08\u6D88\u606F id <code>${m(L)}</code>\uFF09\uFF0C\u770B\u98DE\u4E66\u901A\u77E5\u5C31\u80FD\u8FDB\u7FA4\u3002</small>`:k?`<br><small class="hint-warn-inline">\u26A0 \u81EA\u52A8 @ \u901A\u77E5\u5931\u8D25\uFF08${m(k)}\uFF09\uFF0C\u65B0\u7FA4\u53EF\u80FD\u4E0D\u4F1A\u4E3B\u52A8\u51FA\u73B0\u5728\u4F60\u4FA7\u8FB9\u680F\uFF0C\u5EFA\u8BAE\u4ECE\u4E0B\u9762\u6309\u94AE\u8DF3\u8FDB\u53BB\u3002</small>`:"";E=`<p class="hint-ok">\u5DF2\u81EA\u52A8\u9080\u8BF7\u4F60\uFF08<code>${m(y)}</code>\uFF09\u4F5C\u4E3A\u6210\u5458\u3002${H}${U}</p>`}else d?E='<p class="hint-warn">\u98DE\u4E66\u62D2\u7EDD\u4E86\u81EA\u52A8\u9080\u8BF7\uFF08\u4F60\u7684 open_id \u5728\u521B\u5EFA\u8005 bot \u7684 scope \u4E0B\u4E0D\u53EF\u7528\uFF09\u3002<strong>\u4F60\u76EE\u524D\u4E0D\u662F\u65B0\u7FA4\u6210\u5458</strong>\uFF0C\u9700\u8981\u8BA9\u7FA4\u91CC\u7684\u67D0\u4E2A\u673A\u5668\u4EBA\u624B\u52A8\u628A\u4F60\u52A0\u8FDB\u6765\u3002</p>':E='<p class="hint-warn">\u6CA1\u5728 dashboard \u7F13\u5B58\u91CC\u627E\u5230 ownerOpenId\uFF0C<strong>\u6CA1\u6709\u81EA\u52A8\u9080\u8BF7\u4F60</strong>\u3002\u70B9\u5F00\u4E0B\u9762\u94FE\u63A5\u524D\uFF0C\u5148\u8BA9\u7FA4\u91CC\u4EFB\u4E00\u673A\u5668\u4EBA\u624B\u52A8\u628A\u4F60\u52A0\u8FDB\u53BB\u3002</p>';let S=[l.length?`<li>\u65E0\u6548 bot id: <code>${l.map(m).join(", ")}</code></li>`:"",c.length?`<li>\u65E0\u6548\u7528\u6237 open_id: <code>${c.map(m).join(", ")}</code></li>`:""].filter(Boolean).join("");n.innerHTML=`
126
+ <article>
127
+ <header><h3>\u7FA4\u521B\u5EFA\u6210\u529F</h3></header>
128
+ <p><b>chatId:</b> <code>${m(a)}</code> <button type="button" data-copy="${m(a)}">copy</button></p>
129
+ <p><b>\u521B\u5EFA\u8005:</b> <code>${m(s.creator??"?")}</code></p>
130
+ ${E}
131
+ ${S?`<ul>${S}</ul>`:""}
132
+ <div class="actions">
133
+ <a class="btn-link primary" href="${$}" target="_blank" rel="noopener">\u2197 \u6253\u5F00\u65B0\u7FA4</a>
134
+ <button type="button" id="g-create-close">\u5173\u95ED</button>
135
+ </div>
136
+ </article>`,n.querySelectorAll("[data-copy]").forEach(H=>{H.onclick=()=>{navigator.clipboard.writeText(H.dataset.copy??""),H.textContent="copied",setTimeout(()=>{H.textContent="copy"},800)}}),n.querySelector("#g-create-close").onclick=()=>n.close()}function p(){t.innerHTML=`<tr>
130
137
  <th>chat</th>
131
- ${I.bots.map(a=>`<th>${y(a.botName??a.larkAppId)}</th>`).join("")}
138
+ ${T.bots.map(s=>`<th>${m(s.botName??s.larkAppId)}</th>`).join("")}
132
139
  <th>actions</th>
133
- </tr>`}function l(){e();let a=new FormData(u),r=(a.get("q")??"").toLowerCase(),d=!!a.get("missing"),g=I.chats.filter(o=>!r||(o.name??"").toLowerCase().includes(r)||o.chatId.toLowerCase().includes(r)||(o.ownerId??"").toLowerCase().includes(r)).filter(o=>!d||o.memberBots.some(b=>!b.inChat));if(g.length===0){i.innerHTML=`<tr><td colspan="${I.bots.length+2}" class="empty">No chats match the filter.</td></tr>`;return}i.innerHTML=g.map(o=>`<tr data-chat="${y(o.chatId)}">
140
+ </tr>`}function i(){p();let s=new FormData(u),a=(s.get("q")??"").toLowerCase(),$=!!s.get("missing"),l=T.chats.filter(c=>!a||(c.name??"").toLowerCase().includes(a)||c.chatId.toLowerCase().includes(a)||(c.ownerId??"").toLowerCase().includes(a)).filter(c=>!$||c.memberBots.some(y=>!y.inChat));if(l.length===0){r.innerHTML=`<tr><td colspan="${T.bots.length+2}" class="empty">No chats match the filter.</td></tr>`;return}r.innerHTML=l.map(c=>`<tr data-chat="${m(c.chatId)}">
134
141
  <td>
135
- <strong>${y(o.name??o.chatId)}</strong><br>
136
- <small><code>${y(o.chatId)}</code></small>
142
+ <strong>${m(c.name??c.chatId)}</strong><br>
143
+ <small><code>${m(c.chatId)}</code></small>
137
144
  </td>
138
- ${I.bots.map(b=>{let c=o.memberBots.find(k=>k.larkAppId===b.larkAppId),$=c?c.error?"!":c.inChat?"\u2713":"\u2717":"?";return`<td class="${c?c.error?"cell-error":c.inChat?"cell-in":"cell-out":"cell-unknown"}" title="${y(c?.error??"")}">${$}</td>`}).join("")}
145
+ ${T.bots.map(y=>{let d=c.memberBots.find(L=>L.larkAppId===y.larkAppId),I=d?d.error?"!":d.inChat?"\u2713":"\u2717":"?";return`<td class="${d?d.error?"cell-error":d.inChat?"cell-in":"cell-out":"cell-unknown"}" title="${m(d?.error??"")}">${I}</td>`}).join("")}
139
146
  <td><button class="add-bots" type="button">Add bots</button></td>
140
- </tr>`).join("")}l(),i.addEventListener("click",async a=>{let r=a.target.closest("button.add-bots");if(!r)return;let g=r.closest("tr[data-chat]").dataset.chat,o=I.chats.find(c=>c.chatId===g);if(!o)return;let b=o.memberBots.filter(c=>!c.inChat);if(!b.length){alert("All configured bots are already in this chat.");return}s.innerHTML=`
147
+ </tr>`).join("")}i(),r.addEventListener("click",async s=>{let a=s.target.closest("button.add-bots");if(!a)return;let l=a.closest("tr[data-chat]").dataset.chat,c=T.chats.find(d=>d.chatId===l);if(!c)return;let y=c.memberBots.filter(d=>!d.inChat);if(!y.length){alert("All configured bots are already in this chat.");return}n.innerHTML=`
141
148
  <article>
142
- <header><h3>Add bots to ${y(o.name??o.chatId)}</h3></header>
149
+ <header><h3>Add bots to ${m(c.name??c.chatId)}</h3></header>
143
150
  <p>Select bots to add. The dashboard will pick a bot that's already in the chat as the proxy.</p>
144
151
  <form id="g-addform">
145
- ${b.map(c=>`
152
+ ${y.map(d=>`
146
153
  <label class="checkbox-row">
147
- <input type="checkbox" name="bot" value="${y(c.larkAppId)}">
148
- ${y(c.botName??c.larkAppId)} <small>(${y(c.larkAppId)})</small>
154
+ <input type="checkbox" name="bot" value="${m(d.larkAppId)}">
155
+ ${m(d.botName??d.larkAppId)} <small>(${m(d.larkAppId)})</small>
149
156
  </label>
150
157
  `).join("")}
151
158
  <div class="actions">
@@ -153,5 +160,5 @@ creator: ${$.creator??"?"}${k}`),await H(),l()}else alert(`Failed: ${$.error??c.
153
160
  <button type="button" id="g-cancel">Cancel</button>
154
161
  </div>
155
162
  </form>
156
- </article>`,s.showModal(),s.querySelector("#g-cancel").onclick=()=>s.close(),s.querySelector("#g-addform").onsubmit=async c=>{c.preventDefault();let M=new FormData(c.target).getAll("bot");if(M.length===0){alert("Pick at least one bot.");return}try{let T=await(await fetch(`/api/groups/${encodeURIComponent(g)}/add-bots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({larkAppIds:M})})).json();if(T.error==="no_proxy_bot")alert("No bot is currently in this chat \u2014 add one manually in Feishu first, then retry.");else if(T.result){let F=T.result.map(S=>`${S.id}: ${S.ok?"OK":`failed (${S.error??"unknown"})`}`).join(`
157
- `);alert(F),await H(),l()}else alert(`Unexpected response: ${JSON.stringify(T)}`)}catch(k){alert("Network error: "+k)}finally{s.close()}}}),u.addEventListener("input",l)}var C=document.getElementById("root");function R(){let n=location.hash||"#/";n.startsWith("#/groups")?P(C):n.startsWith("#/schedules")?D(C):N(C);for(let t of document.querySelectorAll("header nav a"))t.classList.toggle("active",t.getAttribute("href")===(n||"#/")||n==="#/"&&t.dataset.route==="sessions")}var x=document.getElementById("status");function O(){x&&(x.textContent=m.online?"\u25CF live":"\u25CF disconnected",x.className="status "+(m.online?"online":"offline"))}m.on(O);O();(async()=>{try{await A()}catch(n){console.error("botmux dashboard bootstrap failed",n),m.setOnline(!1)}window.addEventListener("hashchange",R),R()})();})();
163
+ </article>`,n.showModal(),n.querySelector("#g-cancel").onclick=()=>n.close(),n.querySelector("#g-addform").onsubmit=async d=>{d.preventDefault();let v=new FormData(d.target).getAll("bot");if(v.length===0){alert("Pick at least one bot.");return}try{let k=await(await fetch(`/api/groups/${encodeURIComponent(l)}/add-bots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({larkAppIds:v})})).json();if(k.error==="no_proxy_bot")alert("No bot is currently in this chat \u2014 add one manually in Feishu first, then retry.");else if(k.result){let E=k.result.map(S=>`${S.id}: ${S.ok?"OK":`failed (${S.error??"unknown"})`}`).join(`
164
+ `);alert(E),await x(),i()}else alert(`Unexpected response: ${JSON.stringify(k)}`)}catch(L){alert("Network error: "+L)}finally{n.close()}}}),u.addEventListener("input",i)}var q=document.getElementById("root");function _(){let o=location.hash||"#/";o.startsWith("#/groups")?j(q):o.startsWith("#/schedules")?P(q):D(q);for(let t of document.querySelectorAll("header nav a"))t.classList.toggle("active",t.getAttribute("href")===(o||"#/")||o==="#/"&&t.dataset.route==="sessions")}var B=document.getElementById("status");function F(){B&&(B.textContent=b.online?"\u25CF live":"\u25CF disconnected",B.className="status "+(b.online?"online":"offline"))}b.on(F);F();(async()=>{try{await N()}catch(o){console.error("botmux dashboard bootstrap failed",o),b.setOnline(!1)}window.addEventListener("hashchange",_),_()})();})();
@@ -21,7 +21,12 @@ table { border-collapse: collapse; width: 100%; font-variant-numeric: tabular-nu
21
21
  th, td { padding: 0.4rem 0.6rem; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
22
22
  th { background: var(--header-bg); font-weight: 600; }
23
23
  tr[data-id]:hover { background: #f6f8fa; cursor: pointer; }
24
- button { padding: 0.25rem 0.6rem; border: 1px solid var(--border); background: white; border-radius: 4px; cursor: pointer; }
24
+ button { padding: 0.25rem 0.6rem; border: 1px solid var(--border); background: white; border-radius: 4px; cursor: pointer;
25
+ /* iOS Safari renders default <button> with -webkit-appearance: button which
26
+ can hide our text under a system gradient on small screens. Reset to
27
+ normalize so "Create" / "Cancel" / etc. render reliably across mobile. */
28
+ color: var(--fg); font-family: inherit; font-size: inherit; line-height: 1.2;
29
+ -webkit-appearance: none; appearance: none; }
25
30
  button:disabled { opacity: 0.5; cursor: default; }
26
31
  button.contrast { background: #cf222e; color: white; border-color: #cf222e; }
27
32
  .btn-link { display: inline-block; padding: 0.25rem 0.6rem; border: 1px solid var(--border); border-radius: 4px; text-decoration: none; color: var(--fg); }
@@ -55,3 +60,7 @@ dialog#g-drawer { border: none; border-radius: 8px; padding: 0; max-width: 600px
55
60
  dialog#g-drawer article { padding: 1rem 1.5rem; }
56
61
  dialog#g-drawer fieldset { margin: 0.5rem 0; padding: 0.4rem 0.8rem; border: 1px solid var(--border); border-radius: 4px; }
57
62
  dialog#g-drawer fieldset legend { padding: 0 0.3rem; color: var(--muted); font-size: 12px; }
63
+ .hint-ok { background: #ddf4e4; border-left: 3px solid #1a7f37; padding: 0.4rem 0.6rem; border-radius: 3px; margin: 0.5rem 0; font-size: 13px; }
64
+ .hint-warn { background: #fff8c5; border-left: 3px solid #bf8700; padding: 0.4rem 0.6rem; border-radius: 3px; margin: 0.5rem 0; font-size: 13px; }
65
+ .btn-link.primary { background: #1f6feb; color: white; border-color: #1f6feb; font-weight: 600; }
66
+ .hint-warn-inline { color: #9a6700; }
package/dist/dashboard.js CHANGED
@@ -9,6 +9,7 @@ import { config } from './config.js';
9
9
  import { generateToken, parseCookie, buildSetCookie, verifyHmac, } from './dashboard/auth.js';
10
10
  import { DaemonRegistry } from './dashboard/registry.js';
11
11
  import { Aggregator, subscribeDaemon } from './dashboard/aggregator.js';
12
+ import { pickOperatorForCreate } from './dashboard/operator-selector.js';
12
13
  const SECRET_PATH = join(homedir(), '.botmux', '.dashboard-secret');
13
14
  const REGISTRY_DIR = join(homedir(), '.botmux', 'data', 'dashboard-daemons');
14
15
  let activeToken = null;
@@ -27,28 +28,23 @@ mkdirSync(REGISTRY_DIR, { recursive: true });
27
28
  const registry = new DaemonRegistry(REGISTRY_DIR);
28
29
  const aggregator = new Aggregator();
29
30
  const subs = new Map();
30
- function syncSubscriptions() {
31
- const online = new Set(registry.list().map(d => d.larkAppId));
32
- // Open new subscriptions
33
- for (const d of registry.list()) {
34
- if (!subs.has(d.larkAppId)) {
35
- subs.set(d.larkAppId, subscribeDaemon(d, aggregator, e => logger.warn(`[aggregator] ${d.larkAppId}: ${e.message}`)));
36
- }
37
- }
38
- // Close subscriptions for offline daemons
39
- for (const [id, off] of subs) {
40
- if (!online.has(id)) {
41
- off();
42
- subs.delete(id);
43
- }
44
- }
45
- }
46
- await registry.start();
47
- registry.on(syncSubscriptions);
48
- syncSubscriptions();
49
- // Initial hydrate from each online daemon
50
- async function hydrate() {
51
- for (const d of registry.list()) {
31
+ const attaching = new Set(); // dedup concurrent attaches per appId
32
+ /**
33
+ * Attach to one daemon: hydrate its sessions/schedules into the aggregator,
34
+ * THEN open the SSE subscription. Order matters — hydrating after subscribe
35
+ * would let snapshot data clobber events that arrived between subscribe and
36
+ * the snapshot fetch.
37
+ *
38
+ * Idempotent: a second call for the same daemon while one is in flight is a
39
+ * no-op; a call after attach finished re-hydrates (useful when a daemon
40
+ * restarts and we want to refresh its slice of the cache).
41
+ */
42
+ async function attachDaemon(d) {
43
+ if (attaching.has(d.larkAppId))
44
+ return;
45
+ attaching.add(d.larkAppId);
46
+ try {
47
+ // 1. Hydrate snapshot (blocking — completes before we wire SSE)
52
48
  try {
53
49
  const [sRes, schRes] = await Promise.all([
54
50
  fetch(`http://127.0.0.1:${d.ipcPort}/api/sessions`),
@@ -62,9 +58,40 @@ async function hydrate() {
62
58
  catch (e) {
63
59
  logger.warn(`[dashboard] hydrate ${d.larkAppId}: ${e.message ?? e}`);
64
60
  }
61
+ // 2. Open SSE subscription if not already (idempotent)
62
+ if (!subs.has(d.larkAppId)) {
63
+ subs.set(d.larkAppId, subscribeDaemon(d, aggregator, e => logger.warn(`[aggregator] ${d.larkAppId}: ${e.message}`)));
64
+ }
65
+ }
66
+ finally {
67
+ attaching.delete(d.larkAppId);
68
+ }
69
+ }
70
+ function syncSubscriptions() {
71
+ const online = new Set(registry.list().map(d => d.larkAppId));
72
+ // Attach (hydrate + subscribe) any newly-online daemon. Fire-and-forget
73
+ // because the registry callback is sync and the attach is per-daemon
74
+ // independent.
75
+ for (const d of registry.list()) {
76
+ if (!subs.has(d.larkAppId)) {
77
+ void attachDaemon(d);
78
+ }
79
+ }
80
+ // Close subscriptions for daemons that went offline. Cache entries are
81
+ // intentionally retained — the user may still want to see the last-known
82
+ // state of those sessions/schedules in the dashboard.
83
+ for (const [id, off] of subs) {
84
+ if (!online.has(id)) {
85
+ off();
86
+ subs.delete(id);
87
+ }
65
88
  }
66
89
  }
67
- await hydrate();
90
+ await registry.start();
91
+ registry.on(syncSubscriptions);
92
+ // Initial attach for every daemon already known. Run in parallel so a slow
93
+ // daemon doesn't block the others.
94
+ await Promise.all(registry.list().map(attachDaemon));
68
95
  // ─── Static frontend ─────────────────────────────────────────────────────────
69
96
  // Path to the bundled frontend (sibling of dist/dashboard.js)
70
97
  const __dirname = dirname(new URL(import.meta.url).pathname);
@@ -198,7 +225,9 @@ const server = createServer(async (req, res) => {
198
225
  // Fan out: each online daemon returns the chats its bot is in.
199
226
  // Merge by chatId; populate memberBots with inChat flags for every configured bot.
200
227
  const out = new Map();
201
- const onlineBots = registry.list();
228
+ // Sort by botIndex so the matrix columns + the create-group bot picker
229
+ // both match the order in bots.json (fs.readdir order is unstable).
230
+ const onlineBots = [...registry.list()].sort((a, b) => a.botIndex - b.botIndex);
202
231
  await Promise.all(onlineBots.map(async (d) => {
203
232
  try {
204
233
  const r = await fetch(`http://127.0.0.1:${d.ipcPort}/api/groups`);
@@ -264,15 +293,18 @@ const server = createServer(async (req, res) => {
264
293
  res.end(await upstream.text());
265
294
  return;
266
295
  }
267
- // Create a new chat — pick any online daemon as the creator/owner.
296
+ // Create a new chat — pick a creator daemon and (optionally) auto-invite
297
+ // the operator into it. Cross-app scoping matters here: Lark `open_id` is
298
+ // app-scoped, so the operator's open_id and the creator daemon must come
299
+ // from the SAME bot. See pickOperatorForCreate / operator-selector.ts.
268
300
  if (req.method === 'POST' && url.pathname === '/api/groups/create') {
269
- let raw;
301
+ let parsed;
270
302
  try {
271
303
  const chunks = [];
272
304
  for await (const c of req)
273
305
  chunks.push(c);
274
- raw = Buffer.concat(chunks).toString('utf8') || '{}';
275
- JSON.parse(raw);
306
+ const raw = Buffer.concat(chunks).toString('utf8') || '{}';
307
+ parsed = JSON.parse(raw);
276
308
  }
277
309
  catch {
278
310
  return jsonRes(res, 400, { ok: false, error: 'bad_json' });
@@ -281,13 +313,66 @@ const server = createServer(async (req, res) => {
281
313
  if (online.length === 0) {
282
314
  return jsonRes(res, 503, { ok: false, error: 'no_online_daemon' });
283
315
  }
284
- // First online daemon = creator. The body's larkAppIds list may include
285
- // the creator; the daemon-side createChat filters that out before the
286
- // Feishu call.
287
- const creator = online[0];
288
- const upstream = await fetch(`http://127.0.0.1:${creator.ipcPort}/api/groups/create`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: raw });
316
+ const explicit = Array.isArray(parsed.userOpenIds)
317
+ ? parsed.userOpenIds.filter((x) => typeof x === 'string')
318
+ : [];
319
+ let creator = online[0]; // fallback when auto-detection fails
320
+ let autoInvited = null;
321
+ const merged = new Set(explicit);
322
+ if (explicit.length === 0) {
323
+ // Auto-detect operator. The selector binds open_id to the daemon that
324
+ // owns it, so we don't accidentally use bot B's open_id with bot A as
325
+ // creator (which would silently land in invalid_user_id_list).
326
+ const op = pickOperatorForCreate(aggregator.getSessions(), (id) => !!registry.getByAppId(id));
327
+ if (op) {
328
+ const matched = registry.getByAppId(op.larkAppId);
329
+ if (matched) {
330
+ creator = matched;
331
+ merged.add(op.openId);
332
+ autoInvited = op.openId;
333
+ }
334
+ }
335
+ }
336
+ const forwardBody = {
337
+ name: typeof parsed.name === 'string' ? parsed.name : undefined,
338
+ larkAppIds: parsed.larkAppIds,
339
+ userOpenIds: [...merged],
340
+ // Auto-transfer ownership to the auto-invited operator. Same
341
+ // app-scope guarantee as the invite — the open_id we resolved came
342
+ // from a session whose larkAppId is the creator daemon.
343
+ transferOwnerTo: autoInvited ?? undefined,
344
+ // Send an @-mention message into the new chat so the operator gets
345
+ // a Feishu push notification — being a chat member alone doesn't
346
+ // always surface the chat in their sidebar (esp. mobile). Same
347
+ // app-scope guarantee as transferOwnerTo.
348
+ notifyOwnerOpenId: autoInvited ?? undefined,
349
+ };
350
+ const upstream = await fetch(`http://127.0.0.1:${creator.ipcPort}/api/groups/create`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(forwardBody) });
351
+ const upstreamText = await upstream.text();
352
+ let upstreamJson = null;
353
+ try {
354
+ upstreamJson = JSON.parse(upstreamText);
355
+ }
356
+ catch { /* leave null */ }
357
+ if (upstreamJson && typeof upstreamJson === 'object') {
358
+ // If Lark rejected the invite (open_id wrong scope, banned user, etc.)
359
+ // null out autoInvitedOpenId so the frontend doesn't falsely claim
360
+ // success — the user actually isn't a member of the new chat.
361
+ const invalidUsers = Array.isArray(upstreamJson.invalidUserIds)
362
+ ? upstreamJson.invalidUserIds
363
+ : [];
364
+ if (autoInvited && invalidUsers.includes(autoInvited)) {
365
+ upstreamJson.autoInvitedOpenId = null;
366
+ upstreamJson.autoInviteRejected = true;
367
+ // ownerTransferredTo is already null from daemon (it skips transfer
368
+ // when invitee_rejected), so nothing more to do here.
369
+ }
370
+ else {
371
+ upstreamJson.autoInvitedOpenId = autoInvited;
372
+ }
373
+ }
289
374
  res.writeHead(upstream.status, { 'content-type': 'application/json' });
290
- res.end(await upstream.text());
375
+ res.end(upstreamJson ? JSON.stringify(upstreamJson) : upstreamText);
291
376
  return;
292
377
  }
293
378
  // Public SSE — relays aggregator's listener events
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAA6C,MAAM,WAAW,CAAC;AACpF,OAAO,EACL,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GACxE,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,GACvD,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAExE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;AACpE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE7E,IAAI,WAAW,GAAkB,IAAI,CAAC;AAEtC,SAAS,kBAAkB;IACzB,IAAI,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7E,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAChD,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,aAAa,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,CAAC,IAAI,CAAC,6CAA6C,WAAW,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;AACpC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;AAClD,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;AACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE3C,SAAS,iBAAiB;IACxB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9D,yBAAyB;IACzB,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CACN,CAAC,CAAC,SAAS,EACX,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CACjC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CACzD,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,0CAA0C;IAC1C,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAAC,GAAG,EAAE,CAAC;YAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;AACvB,QAAQ,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;AAC/B,iBAAiB,EAAE,CAAC;AAEpB,0CAA0C;AAC1C,KAAK,UAAU,OAAO;IACpB,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACvC,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,eAAe,CAAC;gBACnD,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,gBAAgB,CAAC;aACrD,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAyB,CAAC;YACnD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,EAA0B,CAAC;YACxD,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YAC1D,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;AACH,CAAC;AACD,MAAM,OAAO,EAAE,CAAC;AAEhB,gFAAgF;AAEhF,8DAA8D;AAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAEjD,MAAM,IAAI,GAA2B;IACnC,OAAO,EAAE,0BAA0B;IACnC,KAAK,EAAE,wBAAwB;IAC/B,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,eAAe;IACvB,QAAQ,EAAE,YAAY;CACvB,CAAC;AAEF,SAAS,WAAW,CAAC,IAAqB,EAAE,GAAmB,EAAE,QAAgB;IAC/E,MAAM,GAAG,GAAG,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3E,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC9B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;YAAE,OAAO,KAAK,CAAC;QAC/B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,0BAA0B,EAAE,CAAC,CAAC;QACxF,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF,SAAS,WAAW,CAAC,GAAoB,EAAE,GAAQ;IACjD,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,CAAC,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC;IACrC,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,OAAO,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAa;IACjE,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC9D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,SAAiB,EAAE,UAAkB,EAAE,IAAiB;IAExD,MAAM,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,EAAE;YAC1E,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;SAChD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,GAAG,UAAU,EAAE,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,CAAC;QAEjF,mCAAmC;QACnC,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,6DAA6D;QAC7D,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;YAC9D,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;YAC7C,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACnF,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;YACzD,CAAC;YACD,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACxE,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;YACzD,IAAI,CAAC,CAAC,CAAC,EAAE;gBAAE,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACjF,WAAW,GAAG,aAAa,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,UAAU,MAAM,CAAC,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,OAAO,WAAW,EAAE,CAAC;YACrG,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,oDAAoD;QACpD,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAChC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACnE,GAAG,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;YAC9F,OAAO;QACT,CAAC;QAED,wEAAwE;QACxE,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,YAAY,EAAE,cAAc,CAAC,GAAG,CAAC;gBACjC,UAAU,EAAE,GAAG,CAAC,QAAQ,IAAI,GAAG;aAChC,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAC1F,sCAAsC;YACtC,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;gBACpD,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC7B,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjB,IAAI,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC;gBAAE,OAAO;QAChD,CAAC;QAED,2EAA2E;QAE3E,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;YAC7D,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAC;YAC9D,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAA0B,CAAC;QAC/B,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC,EAAE,CAAC;YACpG,MAAM,GAAG,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK;gBAAE,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAC9E,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9F,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACvE,GAAG,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC,EAAE,CAAC;YACzG,MAAM,EAAE,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK;gBAAE,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC/E,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9F,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACvE,GAAG,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,4EAA4E;QAE5E,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC3D,+DAA+D;YAC/D,mFAAmF;YACnF,MAAM,GAAG,GAAG,IAAI,GAAG,EAAe,CAAC;YACnC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE;gBACzC,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC;oBAClE,IAAI,CAAC,CAAC,CAAC,EAAE;wBAAE,OAAO;oBAClB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAuB,CAAC;oBAC9C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;wBAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,EAAW,EAAE,CAAC;wBACnE,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;wBAClF,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAC,iDAAiD,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC,CAAC;YACJ,kFAAkF;YAClF,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC7E,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;oBAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;wBAC9B,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;oBACnF,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;gBACvB,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC/F,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;aAC5E,CAAC,CAAC;QACL,CAAC;QAED,IAAI,EAA2B,CAAC;QAChC,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC,EAAE,CAAC;YAC7F,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,uDAAuD;YACvD,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAa,EAAE,CAAC;gBAC5B,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,GAAG;oBAAE,MAAM,CAAC,IAAI,CAAC,CAAW,CAAC,CAAC;gBACpD,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;gBACrD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,kDAAkD;YAClD,IAAI,KAAyD,CAAC;YAC9D,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,eAAe,kBAAkB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;oBAC3G,IAAI,CAAC,CAAC,CAAC,EAAE;wBAAE,SAAS;oBACpB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAA0B,CAAC;oBACjD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;wBAAC,KAAK,GAAG,CAAC,CAAC;wBAAC,MAAM;oBAAC,CAAC;gBACrC,CAAC;gBAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;YACxB,CAAC;YACD,IAAI,CAAC,KAAK;gBAAE,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YAC3E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,oBAAoB,KAAK,CAAC,OAAO,eAAe,kBAAkB,CAAC,MAAM,CAAC,WAAW,EACrF,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAC/E,CAAC;YACF,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACvE,GAAG,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,mEAAmE;QACnE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,oBAAoB,EAAE,CAAC;YACnE,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAa,EAAE,CAAC;gBAC5B,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,GAAG;oBAAE,MAAM,CAAC,IAAI,CAAC,CAAW,CAAC,CAAC;gBACpD,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;gBACrD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC/B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,wEAAwE;YACxE,sEAAsE;YACtE,eAAe;YACf,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,oBAAoB,OAAO,CAAC,OAAO,oBAAoB,EACvD,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAC/E,CAAC;YACF,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACvE,GAAG,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,mDAAmD;QACnD,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACvD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,wBAAwB;gBACzC,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YACH,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;gBAC7B,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,IAAI,WAAW,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;YAC1G,CAAC,CAAC,CAAC;YACH,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;gBAC1B,GAAG,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;YACjF,CAAC,EAAE,MAAM,CAAC,CAAC;YACX,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,mEAAmE;QACnE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,WAAW;YAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE;IAC/D,MAAM,CAAC,IAAI,CAAC,4BAA4B,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5F,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,SAAS,QAAQ;IACf,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;IACb,QAAQ,CAAC,IAAI,EAAE,CAAC;IAChB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,8BAA8B;IAC9B,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;AACnD,CAAC;AACD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}