botmux 2.106.0 → 2.107.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/dist/bot-registry.d.ts +25 -0
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +6 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +5 -0
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +27 -1
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +6 -0
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +25 -0
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/pending-response.d.ts +1 -0
- package/dist/core/pending-response.d.ts.map +1 -1
- package/dist/core/pending-response.js +1 -0
- package/dist/core/pending-response.js.map +1 -1
- package/dist/core/resource-monitor/attribution.d.ts +70 -0
- package/dist/core/resource-monitor/attribution.d.ts.map +1 -0
- package/dist/core/resource-monitor/attribution.js +222 -0
- package/dist/core/resource-monitor/attribution.js.map +1 -0
- package/dist/core/resource-monitor/procfs.d.ts +22 -0
- package/dist/core/resource-monitor/procfs.d.ts.map +1 -0
- package/dist/core/resource-monitor/procfs.js +134 -0
- package/dist/core/resource-monitor/procfs.js.map +1 -0
- package/dist/core/resource-monitor/ring-buffer.d.ts +15 -0
- package/dist/core/resource-monitor/ring-buffer.d.ts.map +1 -0
- package/dist/core/resource-monitor/ring-buffer.js +61 -0
- package/dist/core/resource-monitor/ring-buffer.js.map +1 -0
- package/dist/core/resource-monitor/runtime.d.ts +31 -0
- package/dist/core/resource-monitor/runtime.d.ts.map +1 -0
- package/dist/core/resource-monitor/runtime.js +92 -0
- package/dist/core/resource-monitor/runtime.js.map +1 -0
- package/dist/core/resource-monitor/top-selector.d.ts +18 -0
- package/dist/core/resource-monitor/top-selector.d.ts.map +1 -0
- package/dist/core/resource-monitor/top-selector.js +57 -0
- package/dist/core/resource-monitor/top-selector.js.map +1 -0
- package/dist/core/resource-monitor/types.d.ts +181 -0
- package/dist/core/resource-monitor/types.d.ts.map +1 -0
- package/dist/core/resource-monitor/types.js +2 -0
- package/dist/core/resource-monitor/types.js.map +1 -0
- package/dist/core/session-manager.d.ts +3 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +31 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/types.d.ts +1 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/daemon.d.ts +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +44 -22
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +1 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +1 -0
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/resource-monitor-service.d.ts +56 -0
- package/dist/dashboard/resource-monitor-service.d.ts.map +1 -0
- package/dist/dashboard/resource-monitor-service.js +446 -0
- package/dist/dashboard/resource-monitor-service.js.map +1 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js +160 -1
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-routes.js +18 -0
- package/dist/dashboard/web/dashboard-routes.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +274 -2
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/monitor-room-store.d.ts +20 -0
- package/dist/dashboard/web/monitor-room-store.d.ts.map +1 -0
- package/dist/dashboard/web/monitor-room-store.js +80 -0
- package/dist/dashboard/web/monitor-room-store.js.map +1 -0
- package/dist/dashboard/web/monitor-room.d.ts +31 -0
- package/dist/dashboard/web/monitor-room.d.ts.map +1 -0
- package/dist/dashboard/web/monitor-room.js +393 -0
- package/dist/dashboard/web/monitor-room.js.map +1 -0
- package/dist/dashboard/web/monitoring-page.d.ts +155 -0
- package/dist/dashboard/web/monitoring-page.d.ts.map +1 -0
- package/dist/dashboard/web/monitoring-page.js +189 -0
- package/dist/dashboard/web/monitoring-page.js.map +1 -0
- package/dist/dashboard/web/overview-page.d.ts.map +1 -1
- package/dist/dashboard/web/overview-page.js +108 -1
- package/dist/dashboard/web/overview-page.js.map +1 -1
- package/dist/dashboard/web/preferences.d.ts +3 -0
- package/dist/dashboard/web/preferences.d.ts.map +1 -1
- package/dist/dashboard/web/preferences.js +18 -0
- package/dist/dashboard/web/preferences.js.map +1 -1
- package/dist/dashboard/web/session-terminal.d.ts +7 -0
- package/dist/dashboard/web/session-terminal.d.ts.map +1 -0
- package/dist/dashboard/web/session-terminal.js +17 -0
- package/dist/dashboard/web/session-terminal.js.map +1 -0
- package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-page.js +2 -1
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts +4 -0
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +98 -17
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/skills-page.js +1 -1
- package/dist/dashboard/web/skills-page.js.map +1 -1
- package/dist/dashboard/web/substitute-targets.d.ts +30 -0
- package/dist/dashboard/web/substitute-targets.d.ts.map +1 -0
- package/dist/dashboard/web/substitute-targets.js +99 -0
- package/dist/dashboard/web/substitute-targets.js.map +1 -0
- package/dist/dashboard/web/ui.d.ts +1 -1
- package/dist/dashboard/web/ui.d.ts.map +1 -1
- package/dist/dashboard/web/ui.js +4 -1
- package/dist/dashboard/web/ui.js.map +1 -1
- package/dist/dashboard-web/app.js +3 -3
- package/dist/dashboard-web/chunks/bot-defaults-page-OCIHPGEU.js +438 -0
- package/dist/dashboard-web/chunks/chunk-3N2PPQVD.js +1 -0
- package/dist/dashboard-web/chunks/chunk-3UJYRR2Q.js +37 -0
- package/dist/dashboard-web/chunks/{chunk-VFCACTRF.js → chunk-PE6W3C2C.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-QW54DWU3.js +325 -0
- package/dist/dashboard-web/chunks/{connectors-VDOAKUW3.js → connectors-IGETYWCP.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-CX5AN4XG.js → groups-page-MYBS4ZYJ.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-DOMRL4S6.js → insights-page-UPA32V2S.js} +1 -1
- package/dist/dashboard-web/chunks/monitor-room-RFX4HPS5.js +51 -0
- package/dist/dashboard-web/chunks/monitoring-page-7T3BESZ2.js +1 -0
- package/dist/dashboard-web/chunks/overview-page-LJSBCQW4.js +1 -0
- package/dist/dashboard-web/chunks/{roles-page-3FEAH6S4.js → roles-page-ESURTVQH.js} +1 -1
- package/dist/dashboard-web/chunks/{schedules-CTQEA7IE.js → schedules-LML2ISOT.js} +1 -1
- package/dist/dashboard-web/chunks/sessions-YB73XOTU.js +1 -0
- package/dist/dashboard-web/chunks/sessions-page-MCO5QR7Z.js +1 -0
- package/dist/dashboard-web/chunks/{settings-page-R23I3IZG.js → settings-page-OSDKNVS3.js} +1 -1
- package/dist/dashboard-web/chunks/skills-page-PXBZJ6P6.js +2 -0
- package/dist/dashboard-web/chunks/{team-federation-page-ZKL3YMGN.js → team-federation-page-TTPVHFPX.js} +1 -1
- package/dist/dashboard-web/chunks/{workflows-4BYQQBFP.js → workflows-FCPM4S4D.js} +1 -1
- package/dist/dashboard-web/index.html +2 -1
- package/dist/dashboard-web/style.css +818 -8
- package/dist/dashboard.js +37 -0
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +8 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +8 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +18 -0
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +12 -2
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +3 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +59 -2
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/message-parser.d.ts +35 -0
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +56 -0
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/im/lark/substitute-command.d.ts +2 -0
- package/dist/im/lark/substitute-command.d.ts.map +1 -0
- package/dist/im/lark/substitute-command.js +51 -0
- package/dist/im/lark/substitute-command.js.map +1 -0
- package/dist/services/substitute-chat-toggle-store.d.ts +3 -0
- package/dist/services/substitute-chat-toggle-store.d.ts.map +1 -0
- package/dist/services/substitute-chat-toggle-store.js +58 -0
- package/dist/services/substitute-chat-toggle-store.js.map +1 -0
- package/dist/services/substitute-mode-normalize.d.ts +22 -0
- package/dist/services/substitute-mode-normalize.d.ts.map +1 -0
- package/dist/services/substitute-mode-normalize.js +56 -0
- package/dist/services/substitute-mode-normalize.js.map +1 -0
- package/dist/services/substitute-mode-store.d.ts +50 -0
- package/dist/services/substitute-mode-store.d.ts.map +1 -0
- package/dist/services/substitute-mode-store.js +115 -0
- package/dist/services/substitute-mode-store.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/worker.js +20 -1
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-3OIY7N76.js +0 -409
- package/dist/dashboard-web/chunks/chunk-BNEXMNQD.js +0 -31
- package/dist/dashboard-web/chunks/chunk-DKKOGZCG.js +0 -317
- package/dist/dashboard-web/chunks/overview-page-AZBAXVZ7.js +0 -1
- package/dist/dashboard-web/chunks/sessions-LVZCXO2Z.js +0 -1
- package/dist/dashboard-web/chunks/sessions-page-NHBJDSBC.js +0 -1
- package/dist/dashboard-web/chunks/skills-page-VUG3EPWX.js +0 -2
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function currentLocation() {
|
|
2
|
+
return typeof window === 'undefined' ? null : window.location;
|
|
3
|
+
}
|
|
4
|
+
export function sessionTerminalHref(s, loc = currentLocation()) {
|
|
5
|
+
if (!s?.webPort || !loc)
|
|
6
|
+
return null;
|
|
7
|
+
// On the central HTTPS machine domain, terminals must go through the same
|
|
8
|
+
// origin `/s/<session>` reverse proxy. Exposing a raw port would produce a
|
|
9
|
+
// dead link because the platform only proxies 443.
|
|
10
|
+
if (loc.protocol === 'https:') {
|
|
11
|
+
return s.proxyPort ? `${loc.origin}/s/${encodeURIComponent(s.sessionId)}` : null;
|
|
12
|
+
}
|
|
13
|
+
const port = s.proxyPort ?? s.webPort;
|
|
14
|
+
const suffix = s.proxyPort ? `/s/${encodeURIComponent(s.sessionId)}` : '';
|
|
15
|
+
return `http://${loc.hostname}:${port}${suffix}`;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=session-terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-terminal.js","sourceRoot":"","sources":["../../../src/dashboard/web/session-terminal.ts"],"names":[],"mappings":"AAMA,SAAS,eAAe;IACtB,OAAO,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,CAAM,EAAE,MAAsC,eAAe,EAAE;IACjG,IAAI,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACrC,0EAA0E;IAC1E,2EAA2E;IAC3E,mDAAmD;IACnD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,MAAM,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC;IACtC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,OAAO,UAAU,GAAG,CAAC,QAAQ,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions-page.d.ts","sourceRoot":"","sources":["../../../src/dashboard/web/sessions-page.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"sessions-page.d.ts","sourceRoot":"","sources":["../../../src/dashboard/web/sessions-page.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAoIrE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAElE"}
|
|
@@ -4,6 +4,7 @@ import { IDLE_CLEANUP_HOUR_OPTIONS } from '../session-cleanup.js';
|
|
|
4
4
|
import { mountReactPage } from './react-mount.js';
|
|
5
5
|
import { renderCliFilterGroup, SESSION_STATUS_OPTIONS, sessionStatusText, wireSessionsPage } from './sessions.js';
|
|
6
6
|
import { useT } from './react-hooks.js';
|
|
7
|
+
import { readStoredSessionsShowUnknownChats } from './preferences.js';
|
|
7
8
|
function SortHeader(props) {
|
|
8
9
|
return _jsx("th", { "data-sort": props.sort, "data-label": props.label, children: props.label });
|
|
9
10
|
}
|
|
@@ -20,7 +21,7 @@ function SessionsPage() {
|
|
|
20
21
|
return undefined;
|
|
21
22
|
return wireSessionsPage(hostRef.current);
|
|
22
23
|
}, []);
|
|
23
|
-
return (_jsxs("section", { className: "page", ref: hostRef, children: [_jsxs("div", { className: "page-heading", children: [_jsxs("div", { children: [_jsx("p", { className: "eyebrow", children: tr('nav.sessions') }), _jsx("h1", { children: tr('sessions.title') }), _jsx("p", { children: tr('sessions.subtitle') })] }), _jsxs("div", { className: "sessions-view-controls", children: [_jsx("span", { id: "kanban-team-stats", className: "kanban-team-stats", hidden: true }), _jsx("select", { id: "kanban-team", className: "kanban-team-select", "aria-label": tr('sessions.kanban.groupTeam'), hidden: true }), _jsxs("div", { className: "segmented kanban-groupby", id: "kanban-groupby", role: "group", "aria-label": tr('sessions.kanban.groupBy'), hidden: true, children: [_jsx("button", { type: "button", "data-groupby": "flow", children: tr('sessions.kanban.groupFlow') }), _jsx("button", { type: "button", "data-groupby": "team", children: tr('sessions.kanban.groupTeam') }), _jsx("button", { type: "button", "data-groupby": "bot", children: tr('sessions.kanban.groupBot') })] }), _jsxs("div", { className: "segmented sessions-view-toggle", role: "group", "aria-label": tr('sessions.viewMode'), children: [_jsx("button", { type: "button", "data-view": "kanban", children: tr('sessions.viewKanban') }), _jsx("button", { type: "button", "data-view": "board", children: tr('sessions.viewBoard') }), _jsx("button", { type: "button", "data-view": "table", children: tr('sessions.viewTable') })] })] })] }), _jsxs("form", { id: "filters", className: "filters sessions-filters", children: [_jsx("input", { type: "search", name: "q", placeholder: tr('sessions.search') }), _jsxs("select", { name: "status", children: [_jsx("option", { value: "", children: tr('sessions.anyStatus') }), SESSION_STATUS_OPTIONS.map(status => (_jsx("option", { value: status, children: sessionStatusText(status) }, status)))] }), _jsxs("select", { name: "adopt", children: [_jsx("option", { value: "", children: tr('sessions.adoptAny') }), _jsx("option", { value: "yes", children: tr('sessions.adoptYes') }), _jsx("option", { value: "no", children: tr('sessions.adoptNo') })] }), _jsx("span", { style: { display: 'contents' }, dangerouslySetInnerHTML: { __html: renderCliFilterGroup() } }), _jsxs("label", { className: "filter-toggle", children: [_jsx("input", { type: "checkbox", name: "active", defaultChecked: true }), " ", _jsx("span", { children: tr('sessions.activeOnly') })] })] }), _jsxs("div", { id: "idle-cleanup-bar", className: "idle-cleanup-bar", children: [_jsxs("div", { className: "idle-cleanup-summary", children: [_jsx("span", { className: "idle-cleanup-dot", "aria-hidden": "true" }), _jsx("span", { id: "idle-cleanup-count", className: "idle-cleanup-count" })] }), _jsxs("div", { className: "idle-cleanup-controls", children: [_jsx("span", { className: "idle-cleanup-label", children: tr('sessions.idleCleanupOlderThan') }), _jsx("div", { id: "idle-cleanup-threshold", className: "idle-cleanup-thresholds", role: "group", "aria-label": tr('sessions.idleCleanupThreshold'), children: IDLE_CLEANUP_HOUR_OPTIONS.map(hours => (_jsx("button", { type: "button", "data-hours": hours, "aria-pressed": hours === 24 ? 'true' : 'false', children: hours === 168 ? '7d' : `${hours}H` }, hours))) }), _jsx("button", { type: "button", id: "idle-cleanup-run", className: "contrast idle-cleanup-run", children: tr('sessions.idleCleanupRun') })] }), _jsx("span", { id: "idle-cleanup-status", className: "idle-cleanup-status", "aria-live": "polite" })] }), _jsxs("div", { id: "bulk-bar", className: "bulk-bar", hidden: true, children: [_jsx("span", { id: "bulk-count" }), _jsx("button", { type: "button", id: "bulk-lock", children: tr('sessions.lockSelected') }), _jsx("button", { type: "button", id: "bulk-unlock", children: tr('sessions.unlockSelected') }), _jsx("button", { type: "button", id: "bulk-close", className: "contrast", children: tr('sessions.closeSelected') }), _jsx("button", { type: "button", id: "bulk-clear", children: tr('sessions.clearSelection') })] }), _jsxs("table", { id: "sessions-table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: _jsx("input", { type: "checkbox", id: "select-all", title: tr('sessions.activeOnly') }) }), _jsx(SortHeader, { sort: "botName", label: tr('sessions.bot') }), _jsx(SortHeader, { sort: "cliId", label: tr('sessions.cli') }), _jsx(SortHeader, { sort: "status", label: tr('sessions.status') }), _jsx(SortHeader, { sort: "tokenIn", label: tr('sessions.tokenIn') }), _jsx(SortHeader, { sort: "tokenOut", label: tr('sessions.tokenOut') }), _jsx(SortHeader, { sort: "title", label: tr('sessions.titleCol') }), _jsx(SortHeader, { sort: "workingDir", label: tr('sessions.workingDir') }), _jsx(SortHeader, { sort: "spawnedAt", label: tr('sessions.created') }), _jsx(SortHeader, { sort: "lastMessageAt", label: tr('sessions.last') }), _jsx(SortHeader, { sort: "adopt", label: tr('sessions.adopt') }), _jsx("th", { children: tr('sessions.actions') })] }) }), _jsx("tbody", {})] }), _jsx("div", { id: "sessions-board", className: "sessions-board", hidden: true }), _jsx("div", { id: "sessions-kanban", className: "sessions-kanban", hidden: true }), _jsx("dialog", { id: "drawer" }), _jsx("dialog", { id: "term-modal", className: "term-modal" }), _jsx("dialog", { id: "history-modal", className: "history-modal" })] }));
|
|
24
|
+
return (_jsxs("section", { className: "page", ref: hostRef, children: [_jsxs("div", { className: "page-heading", children: [_jsxs("div", { children: [_jsx("p", { className: "eyebrow", children: tr('nav.sessions') }), _jsx("h1", { children: tr('sessions.title') }), _jsx("p", { children: tr('sessions.subtitle') })] }), _jsxs("div", { className: "sessions-view-controls", children: [_jsx("span", { id: "kanban-team-stats", className: "kanban-team-stats", hidden: true }), _jsx("select", { id: "kanban-team", className: "kanban-team-select", "aria-label": tr('sessions.kanban.groupTeam'), hidden: true }), _jsxs("div", { className: "segmented kanban-groupby", id: "kanban-groupby", role: "group", "aria-label": tr('sessions.kanban.groupBy'), hidden: true, children: [_jsx("button", { type: "button", "data-groupby": "flow", children: tr('sessions.kanban.groupFlow') }), _jsx("button", { type: "button", "data-groupby": "team", children: tr('sessions.kanban.groupTeam') }), _jsx("button", { type: "button", "data-groupby": "bot", children: tr('sessions.kanban.groupBot') })] }), _jsxs("div", { className: "segmented sessions-view-toggle", role: "group", "aria-label": tr('sessions.viewMode'), children: [_jsx("button", { type: "button", "data-view": "kanban", children: tr('sessions.viewKanban') }), _jsx("button", { type: "button", "data-view": "board", children: tr('sessions.viewBoard') }), _jsx("button", { type: "button", "data-view": "table", children: tr('sessions.viewTable') })] }), _jsx("button", { type: "button", id: "monitor-room-open", className: "monitor-room-open", children: tr('sessions.monitorRoom') })] })] }), _jsxs("form", { id: "filters", className: "filters sessions-filters", children: [_jsx("input", { type: "search", name: "q", placeholder: tr('sessions.search') }), _jsxs("select", { name: "status", children: [_jsx("option", { value: "", children: tr('sessions.anyStatus') }), SESSION_STATUS_OPTIONS.map(status => (_jsx("option", { value: status, children: sessionStatusText(status) }, status)))] }), _jsxs("select", { name: "adopt", children: [_jsx("option", { value: "", children: tr('sessions.adoptAny') }), _jsx("option", { value: "yes", children: tr('sessions.adoptYes') }), _jsx("option", { value: "no", children: tr('sessions.adoptNo') })] }), _jsx("select", { name: "chat", "aria-label": tr('sessions.location'), children: _jsx("option", { value: "", children: tr('sessions.chatAny') }) }), _jsx("span", { style: { display: 'contents' }, dangerouslySetInnerHTML: { __html: renderCliFilterGroup() } }), _jsxs("label", { className: "filter-toggle", children: [_jsx("input", { type: "checkbox", name: "showUnknownChats", defaultChecked: readStoredSessionsShowUnknownChats(typeof window === 'undefined' ? undefined : window.localStorage) }), " ", _jsx("span", { children: tr('sessions.showUnknownChats') })] }), _jsxs("label", { className: "filter-toggle", children: [_jsx("input", { type: "checkbox", name: "active", defaultChecked: true }), " ", _jsx("span", { children: tr('sessions.activeOnly') })] })] }), _jsxs("div", { id: "idle-cleanup-bar", className: "idle-cleanup-bar", children: [_jsxs("div", { className: "idle-cleanup-summary", children: [_jsx("span", { className: "idle-cleanup-dot", "aria-hidden": "true" }), _jsx("span", { id: "idle-cleanup-count", className: "idle-cleanup-count" })] }), _jsxs("div", { className: "idle-cleanup-controls", children: [_jsx("span", { className: "idle-cleanup-label", children: tr('sessions.idleCleanupOlderThan') }), _jsx("div", { id: "idle-cleanup-threshold", className: "idle-cleanup-thresholds", role: "group", "aria-label": tr('sessions.idleCleanupThreshold'), children: IDLE_CLEANUP_HOUR_OPTIONS.map(hours => (_jsx("button", { type: "button", "data-hours": hours, "aria-pressed": hours === 24 ? 'true' : 'false', children: hours === 168 ? '7d' : `${hours}H` }, hours))) }), _jsx("button", { type: "button", id: "idle-cleanup-run", className: "contrast idle-cleanup-run", children: tr('sessions.idleCleanupRun') })] }), _jsx("span", { id: "idle-cleanup-status", className: "idle-cleanup-status", "aria-live": "polite" })] }), _jsxs("div", { id: "bulk-bar", className: "bulk-bar", hidden: true, children: [_jsx("span", { id: "bulk-count" }), _jsx("button", { type: "button", id: "bulk-monitor-room", children: tr('sessions.addToMonitorRoom') }), _jsx("button", { type: "button", id: "bulk-lock", children: tr('sessions.lockSelected') }), _jsx("button", { type: "button", id: "bulk-unlock", children: tr('sessions.unlockSelected') }), _jsx("button", { type: "button", id: "bulk-close", className: "contrast", children: tr('sessions.closeSelected') }), _jsx("button", { type: "button", id: "bulk-clear", children: tr('sessions.clearSelection') })] }), _jsxs("table", { id: "sessions-table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: _jsx("input", { type: "checkbox", id: "select-all", title: tr('sessions.activeOnly') }) }), _jsx(SortHeader, { sort: "botName", label: tr('sessions.bot') }), _jsx(SortHeader, { sort: "cliId", label: tr('sessions.cli') }), _jsx(SortHeader, { sort: "status", label: tr('sessions.status') }), _jsx(SortHeader, { sort: "chat", label: tr('sessions.location') }), _jsx(SortHeader, { sort: "tokenIn", label: tr('sessions.tokenIn') }), _jsx(SortHeader, { sort: "tokenOut", label: tr('sessions.tokenOut') }), _jsx(SortHeader, { sort: "title", label: tr('sessions.titleCol') }), _jsx(SortHeader, { sort: "workingDir", label: tr('sessions.workingDir') }), _jsx(SortHeader, { sort: "spawnedAt", label: tr('sessions.created') }), _jsx(SortHeader, { sort: "lastMessageAt", label: tr('sessions.last') }), _jsx(SortHeader, { sort: "adopt", label: tr('sessions.adopt') }), _jsx("th", { children: tr('sessions.actions') })] }) }), _jsx("tbody", {})] }), _jsx("div", { id: "sessions-board", className: "sessions-board", hidden: true }), _jsx("div", { id: "sessions-kanban", className: "sessions-kanban", hidden: true }), _jsx("dialog", { id: "drawer" }), _jsx("dialog", { id: "term-modal", className: "term-modal" }), _jsx("dialog", { id: "history-modal", className: "history-modal" })] }));
|
|
24
25
|
}
|
|
25
26
|
export function renderSessionsPage(root) {
|
|
26
27
|
return mountReactPage(root, _jsx(SessionsPage, {}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions-page.js","sourceRoot":"","sources":["../../../src/dashboard/web/sessions-page.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAqB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"sessions-page.js","sourceRoot":"","sources":["../../../src/dashboard/web/sessions-page.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { sessionTerminalHref } from './session-terminal.js';
|
|
1
2
|
export declare const SESSION_STATUS_OPTIONS: string[];
|
|
2
3
|
export declare function sessionStatusText(status: unknown): string;
|
|
4
|
+
export declare function sessionLocationText(s: any): string;
|
|
5
|
+
export declare function isUnknownChatSession(s: any, resolveTitle?: (session: any) => string | null): boolean;
|
|
6
|
+
export declare const terminalHref: typeof sessionTerminalHref;
|
|
3
7
|
export declare function renderCliFilterGroup(): string;
|
|
4
8
|
export declare function restartConfirmMessage(s: any): string;
|
|
5
9
|
export declare function canRestartSession(s: any): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/dashboard/web/sessions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/dashboard/web/sessions.ts"],"names":[],"mappings":"AA2CA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAoE5D,eAAO,MAAM,sBAAsB,UASlC,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAKzD;AAkBD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAMlD;AAED,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,GAAG,EACN,YAAY,GAAE,CAAC,OAAO,EAAE,GAAG,KAAK,MAAM,GAAG,IAAuB,GAC/D,OAAO,CAGT;AAYD,eAAO,MAAM,YAAY,4BAAsB,CAAC;AAyFhD,wBAAgB,oBAAoB,IAAI,MAAM,CAY7C;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAYpD;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,GAAG,OAAO,CAEjD;AAsKD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ5D;AAkGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,CAGhE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,CAy/D9D"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// Sessions page: filter bar, status board/table, detail drawer with locate/resume/close.
|
|
2
|
-
import { KANBAN_TEAM_STORAGE_KEY, normalizeSessionsViewMode, readStoredBoardOrder, readStoredKanbanGroupBy, readStoredSessionsViewMode, writeStoredBoardOrder, writeStoredKanbanGroupBy, writeStoredSessionsViewMode, } from './preferences.js';
|
|
2
|
+
import { KANBAN_TEAM_STORAGE_KEY, normalizeSessionsViewMode, readStoredBoardOrder, readStoredKanbanGroupBy, readStoredSessionsShowUnknownChats, readStoredSessionsViewMode, writeStoredBoardOrder, writeStoredKanbanGroupBy, writeStoredSessionsShowUnknownChats, writeStoredSessionsViewMode, } from './preferences.js';
|
|
3
3
|
import { computeDropPosition, deriveKanbanColumn, effectiveKanbanPosition, } from './kanban-model.js';
|
|
4
4
|
import { store } from './store.js';
|
|
5
5
|
import { botDisplayName, botAvatarHtml, chatAvatarHtml, chatDisplayTitle, attentionWaitSince, escapeHtml, loadNameMaps, relTime, stripMentionPrefix, t, ui, } from './ui.js';
|
|
6
6
|
import { IDLE_CLEANUP_HOUR_OPTIONS, parseIdleCleanupHours, selectIdleCleanupCandidates, } from '../session-cleanup.js';
|
|
7
7
|
import { CLI_OPTIONS } from '../../setup/bot-config-editor.js';
|
|
8
|
+
import { addMonitorRoomSessionIds, monitorRoomUrl } from './monitor-room-store.js';
|
|
9
|
+
import { sessionTerminalHref } from './session-terminal.js';
|
|
8
10
|
function th(sort, label) {
|
|
9
11
|
return `<th data-sort="${sort}" data-label="${escapeHtml(label)}">${escapeHtml(label)}</th>`;
|
|
10
12
|
}
|
|
@@ -86,20 +88,31 @@ function repoBasename(workingDir) {
|
|
|
86
88
|
const parts = value.replace(/\\/g, '/').split('/').filter(Boolean);
|
|
87
89
|
return parts.at(-1) ?? value;
|
|
88
90
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
return
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
function sessionChatKindLabel(s) {
|
|
92
|
+
return s?.chatType === 'p2p' ? t('sessions.directChat') : t('sessions.groupChat');
|
|
93
|
+
}
|
|
94
|
+
export function sessionLocationText(s) {
|
|
95
|
+
const chatId = String(s?.chatId ?? '').trim();
|
|
96
|
+
const name = chatDisplayTitle(s);
|
|
97
|
+
if (name)
|
|
98
|
+
return `${sessionChatKindLabel(s)} · ${name}`;
|
|
99
|
+
if (chatId)
|
|
100
|
+
return `${sessionChatKindLabel(s)} · ${chatId}`;
|
|
101
|
+
return t('sessions.chatUnknown');
|
|
102
|
+
}
|
|
103
|
+
export function isUnknownChatSession(s, resolveTitle = chatDisplayTitle) {
|
|
104
|
+
const chatId = String(s?.chatId ?? '').trim();
|
|
105
|
+
return !!chatId && !resolveTitle(s);
|
|
106
|
+
}
|
|
107
|
+
function sessionLocationTitle(s) {
|
|
108
|
+
const label = sessionLocationText(s);
|
|
109
|
+
const chatId = String(s?.chatId ?? '').trim();
|
|
110
|
+
return chatId && !label.includes(chatId) ? `${label} · ${chatId}` : label;
|
|
102
111
|
}
|
|
112
|
+
function sessionSearchText(s) {
|
|
113
|
+
return `${JSON.stringify(s)} ${sessionLocationText(s)} ${sessionLocationTitle(s)}`.toLowerCase();
|
|
114
|
+
}
|
|
115
|
+
export const terminalHref = sessionTerminalHref;
|
|
103
116
|
// Cohesive icon set for the session-card action bar — stroke-based (CSS sets
|
|
104
117
|
// stroke:currentColor), 16px viewBox to match the sidebar nav glyphs. Icons
|
|
105
118
|
// instead of text labels keep the row a fixed width across locales: the EN
|
|
@@ -225,6 +238,7 @@ export function canRestartSession(s) {
|
|
|
225
238
|
return s.status !== 'closed' && !s.adopt && !s.pendingRepo;
|
|
226
239
|
}
|
|
227
240
|
function pageHtml() {
|
|
241
|
+
const showUnknownChatsChecked = readStoredSessionsShowUnknownChats(typeof window === 'undefined' ? undefined : window.localStorage) ? ' checked' : '';
|
|
228
242
|
return `<section class="page">
|
|
229
243
|
<div class="page-heading">
|
|
230
244
|
<div>
|
|
@@ -245,6 +259,7 @@ function pageHtml() {
|
|
|
245
259
|
<button type="button" data-view="board">${t('sessions.viewBoard')}</button>
|
|
246
260
|
<button type="button" data-view="table">${t('sessions.viewTable')}</button>
|
|
247
261
|
</div>
|
|
262
|
+
<button type="button" id="monitor-room-open" class="monitor-room-open">${t('sessions.monitorRoom')}</button>
|
|
248
263
|
</div>
|
|
249
264
|
</div>
|
|
250
265
|
<form id="filters" class="filters sessions-filters">
|
|
@@ -258,7 +273,11 @@ function pageHtml() {
|
|
|
258
273
|
<option value="yes">${t('sessions.adoptYes')}</option>
|
|
259
274
|
<option value="no">${t('sessions.adoptNo')}</option>
|
|
260
275
|
</select>
|
|
276
|
+
<select name="chat" aria-label="${t('sessions.location')}">
|
|
277
|
+
<option value="">${t('sessions.chatAny')}</option>
|
|
278
|
+
</select>
|
|
261
279
|
${renderCliFilterGroup()}
|
|
280
|
+
<label class="filter-toggle"><input type="checkbox" name="showUnknownChats"${showUnknownChatsChecked}> <span>${t('sessions.showUnknownChats')}</span></label>
|
|
262
281
|
<label class="filter-toggle"><input type="checkbox" name="active" checked> <span>${t('sessions.activeOnly')}</span></label>
|
|
263
282
|
</form>
|
|
264
283
|
<div id="idle-cleanup-bar" class="idle-cleanup-bar">
|
|
@@ -277,6 +296,7 @@ function pageHtml() {
|
|
|
277
296
|
</div>
|
|
278
297
|
<div id="bulk-bar" class="bulk-bar" hidden>
|
|
279
298
|
<span id="bulk-count"></span>
|
|
299
|
+
<button type="button" id="bulk-monitor-room">${t('sessions.addToMonitorRoom')}</button>
|
|
280
300
|
<button type="button" id="bulk-lock">${t('sessions.lockSelected')}</button>
|
|
281
301
|
<button type="button" id="bulk-unlock">${t('sessions.unlockSelected')}</button>
|
|
282
302
|
<button type="button" id="bulk-close" class="contrast">${t('sessions.closeSelected')}</button>
|
|
@@ -288,6 +308,7 @@ function pageHtml() {
|
|
|
288
308
|
${th('botName', t('sessions.bot'))}
|
|
289
309
|
${th('cliId', t('sessions.cli'))}
|
|
290
310
|
${th('status', t('sessions.status'))}
|
|
311
|
+
${th('chat', t('sessions.location'))}
|
|
291
312
|
${th('tokenIn', t('sessions.tokenIn'))}
|
|
292
313
|
${th('tokenOut', t('sessions.tokenOut'))}
|
|
293
314
|
${th('title', t('sessions.titleCol'))}
|
|
@@ -510,10 +531,13 @@ export function renderSessionsPage(root) {
|
|
|
510
531
|
export function wireSessionsPage(root) {
|
|
511
532
|
const tbody = root.querySelector('#sessions-table tbody');
|
|
512
533
|
const filtersForm = root.querySelector('#filters');
|
|
534
|
+
const chatSelect = root.querySelector('select[name="chat"]');
|
|
535
|
+
const showUnknownChatsInput = root.querySelector('input[name="showUnknownChats"]');
|
|
513
536
|
const drawer = root.querySelector('#drawer');
|
|
514
537
|
const selectAllBox = root.querySelector('#select-all');
|
|
515
538
|
const bulkBar = root.querySelector('#bulk-bar');
|
|
516
539
|
const bulkCountSpan = root.querySelector('#bulk-count');
|
|
540
|
+
const bulkMonitorRoomBtn = root.querySelector('#bulk-monitor-room');
|
|
517
541
|
const bulkLockBtn = root.querySelector('#bulk-lock');
|
|
518
542
|
const bulkUnlockBtn = root.querySelector('#bulk-unlock');
|
|
519
543
|
const bulkCloseBtn = root.querySelector('#bulk-close');
|
|
@@ -532,6 +556,7 @@ export function wireSessionsPage(root) {
|
|
|
532
556
|
const teamSelect = root.querySelector('#kanban-team');
|
|
533
557
|
const teamStats = root.querySelector('#kanban-team-stats');
|
|
534
558
|
const viewButtons = root.querySelectorAll('.sessions-view-toggle [data-view]');
|
|
559
|
+
const monitorRoomOpenBtn = root.querySelector('#monitor-room-open');
|
|
535
560
|
// 「创建会话」按钮 + 弹窗已提到全局顶栏,由 wireCreateSessionButton() 一次性接线(见 app.ts)。
|
|
536
561
|
const selected = new Set();
|
|
537
562
|
let sortKey = 'lastMessageAt';
|
|
@@ -545,6 +570,7 @@ export function wireSessionsPage(root) {
|
|
|
545
570
|
let lastBoardHtml = '';
|
|
546
571
|
let lastTableHtml = '';
|
|
547
572
|
let lastKanbanHtml = '';
|
|
573
|
+
let lastChatFilterHtml = '';
|
|
548
574
|
let boardAnimated = false;
|
|
549
575
|
// 看板交互态:拖拽中的卡片 id / 标题就地编辑中 —— 两者期间都跳过看板重绘,
|
|
550
576
|
// 否则 SSE 触发的 innerHTML 重建会把拖拽源/输入框拍没。
|
|
@@ -579,6 +605,9 @@ export function wireSessionsPage(root) {
|
|
|
579
605
|
})();
|
|
580
606
|
let idleCleanupBusy = false;
|
|
581
607
|
let idleCleanupHours = 24;
|
|
608
|
+
if (showUnknownChatsInput) {
|
|
609
|
+
showUnknownChatsInput.checked = readStoredSessionsShowUnknownChats(window.localStorage);
|
|
610
|
+
}
|
|
582
611
|
function selectedIdleCleanupHours() {
|
|
583
612
|
return idleCleanupHours;
|
|
584
613
|
}
|
|
@@ -849,11 +878,13 @@ export function wireSessionsPage(root) {
|
|
|
849
878
|
function rowHtml(s) {
|
|
850
879
|
const closed = s.status === 'closed';
|
|
851
880
|
const checked = selected.has(s.sessionId) ? 'checked' : '';
|
|
881
|
+
const location = sessionLocationText(s);
|
|
852
882
|
return `<tr data-id="${escapeHtml(s.sessionId)}">
|
|
853
883
|
<td><input type="checkbox" class="row-select" ${checked} ${closed ? 'disabled' : ''}></td>
|
|
854
884
|
<td>${escapeHtml(botDisplayName(s))}</td>
|
|
855
885
|
<td><span class="badge cli-${cssToken(s.cliId)}">${escapeHtml(s.cliId ?? 'unknown')}</span></td>
|
|
856
886
|
<td>${statusBadgeHtml(s.status)}${lockChipHtml(s)}</td>
|
|
887
|
+
<td class="session-location-cell" title="${escapeHtml(sessionLocationTitle(s))}">${escapeHtml(location)}</td>
|
|
857
888
|
<td class="token-cell">${formatTokenCount(s.tokenUsage?.in)}</td>
|
|
858
889
|
<td class="token-cell">${formatTokenCount(s.tokenUsage?.out)}</td>
|
|
859
890
|
<td title="${escapeHtml(String(s.title ?? ''))}">${escapeHtml(stripMentionPrefix(s.title ?? '').slice(0, 48))}</td>
|
|
@@ -1497,16 +1528,20 @@ export function wireSessionsPage(root) {
|
|
|
1497
1528
|
const cliFilterActive = cli.length > 0 && cli.length < CLI_FILTER_OPTIONS.length;
|
|
1498
1529
|
const status = f.get('status');
|
|
1499
1530
|
const adopt = f.get('adopt');
|
|
1531
|
+
const chat = f.get('chat');
|
|
1500
1532
|
const active = !!f.get('active');
|
|
1533
|
+
const showUnknownChats = !!f.get('showUnknownChats');
|
|
1501
1534
|
// 看板视图的「已完成」列收纳已关闭会话——「仅活跃」开关不再把它们整体
|
|
1502
1535
|
// 滤掉,否则该列永远是空的。
|
|
1503
1536
|
const keepClosed = viewMode === 'kanban';
|
|
1504
1537
|
const rows = [...store.sessions.values()]
|
|
1505
1538
|
.filter(s => !cliFilterActive || cli.includes(s.cliId ?? 'unknown'))
|
|
1539
|
+
.filter(s => showUnknownChats || !isUnknownChatSession(s))
|
|
1506
1540
|
.filter(s => !status || s.status === status)
|
|
1507
1541
|
.filter(s => !adopt || (adopt === 'yes') === !!s.adopt)
|
|
1542
|
+
.filter(s => !chat || String(s.chatId ?? '') === chat)
|
|
1508
1543
|
.filter(s => !active || keepClosed || s.status !== 'closed')
|
|
1509
|
-
.filter(s => !q ||
|
|
1544
|
+
.filter(s => !q || sessionSearchText(s).includes(q));
|
|
1510
1545
|
rows.sort(compareRows);
|
|
1511
1546
|
return rows;
|
|
1512
1547
|
}
|
|
@@ -1519,6 +1554,8 @@ export function wireSessionsPage(root) {
|
|
|
1519
1554
|
return tokenCount(s.tokenUsage?.out) ?? -1;
|
|
1520
1555
|
if (key === 'adopt')
|
|
1521
1556
|
return !!s.adopt;
|
|
1557
|
+
if (key === 'chat')
|
|
1558
|
+
return sessionLocationText(s).toLowerCase();
|
|
1522
1559
|
return String(s[key] ?? '').toLowerCase();
|
|
1523
1560
|
}
|
|
1524
1561
|
function compareRows(a, b) {
|
|
@@ -1550,6 +1587,7 @@ export function wireSessionsPage(root) {
|
|
|
1550
1587
|
const selectedRows = [...selected]
|
|
1551
1588
|
.map(id => store.sessions.get(id))
|
|
1552
1589
|
.filter((r) => !!r && r.status !== 'closed');
|
|
1590
|
+
bulkMonitorRoomBtn.disabled = selectedRows.length === 0;
|
|
1553
1591
|
bulkLockBtn.disabled = !selectedRows.some(r => !r.locked);
|
|
1554
1592
|
bulkUnlockBtn.disabled = !selectedRows.some(r => !!r.locked);
|
|
1555
1593
|
const selectable = rows.filter(r => r.status !== 'closed');
|
|
@@ -1599,7 +1637,31 @@ export function wireSessionsPage(root) {
|
|
|
1599
1637
|
countEl.textContent = checked === boxes.length ? t('common.all') : `${checked}/${boxes.length}`;
|
|
1600
1638
|
countEl.classList.toggle('cli-filter-active', checked !== boxes.length);
|
|
1601
1639
|
}
|
|
1640
|
+
function syncChatFilterOptions() {
|
|
1641
|
+
const prev = chatSelect.value;
|
|
1642
|
+
const showUnknownChats = !!filtersForm.querySelector('input[name="showUnknownChats"]')?.checked;
|
|
1643
|
+
const options = new Map();
|
|
1644
|
+
for (const row of store.sessions.values()) {
|
|
1645
|
+
const chatId = String(row.chatId ?? '').trim();
|
|
1646
|
+
if (!chatId)
|
|
1647
|
+
continue;
|
|
1648
|
+
if (!showUnknownChats && isUnknownChatSession(row))
|
|
1649
|
+
continue;
|
|
1650
|
+
const label = sessionLocationText(row);
|
|
1651
|
+
const existing = options.get(chatId);
|
|
1652
|
+
if (!existing || label < existing)
|
|
1653
|
+
options.set(chatId, label);
|
|
1654
|
+
}
|
|
1655
|
+
const rows = [...options.entries()].sort((a, b) => a[1].localeCompare(b[1]));
|
|
1656
|
+
const html = `<option value="">${escapeHtml(t('sessions.chatAny'))}</option>${rows.map(([chatId, label]) => `<option value="${escapeHtml(chatId)}">${escapeHtml(label)}</option>`).join('')}`;
|
|
1657
|
+
if (html !== lastChatFilterHtml) {
|
|
1658
|
+
chatSelect.innerHTML = html;
|
|
1659
|
+
lastChatFilterHtml = html;
|
|
1660
|
+
}
|
|
1661
|
+
chatSelect.value = prev && options.has(prev) ? prev : '';
|
|
1662
|
+
}
|
|
1602
1663
|
function rerender() {
|
|
1664
|
+
syncChatFilterOptions();
|
|
1603
1665
|
const rows = filtered();
|
|
1604
1666
|
for (const sid of [...selected]) {
|
|
1605
1667
|
const s = store.sessions.get(sid);
|
|
@@ -1614,7 +1676,7 @@ export function wireSessionsPage(root) {
|
|
|
1614
1676
|
if (viewMode === 'table') {
|
|
1615
1677
|
const tableHtml = rows.length
|
|
1616
1678
|
? rows.map(rowHtml).join('')
|
|
1617
|
-
: `<tr><td colspan="
|
|
1679
|
+
: `<tr><td colspan="13" class="empty">${t('sessions.empty')}</td></tr>`;
|
|
1618
1680
|
if (tableHtml !== lastTableHtml) {
|
|
1619
1681
|
lastTableHtml = tableHtml;
|
|
1620
1682
|
tbody.innerHTML = tableHtml;
|
|
@@ -1853,7 +1915,7 @@ export function wireSessionsPage(root) {
|
|
|
1853
1915
|
<p><code>${escapeHtml(s.sessionId)}</code> <button data-copy="${escapeHtml(s.sessionId)}">${t('sessions.copy')}</button></p>
|
|
1854
1916
|
</header>
|
|
1855
1917
|
<p><b>${t('sessions.bot')}:</b> ${escapeHtml(botDisplayName(s))} · <b>${t('sessions.cli')}:</b> ${escapeHtml(s.cliId ?? '?')}</p>
|
|
1856
|
-
|
|
1918
|
+
<p><b>${t('sessions.location')}:</b> ${escapeHtml(sessionLocationText(s))}</p>
|
|
1857
1919
|
<p><b>chatId:</b> <code>${escapeHtml(s.chatId ?? '')}</code> <button data-copy="${escapeHtml(s.chatId ?? '')}">${t('sessions.copy')}</button></p>
|
|
1858
1920
|
<p><b>rootMessageId:</b> <code>${escapeHtml(s.rootMessageId ?? '')}</code> <button data-copy="${escapeHtml(s.rootMessageId ?? '')}">${t('sessions.copy')}</button></p>
|
|
1859
1921
|
${s.threadId ? `<p><b>threadId:</b> <code>${escapeHtml(s.threadId)}</code></p>` : ''}
|
|
@@ -2161,6 +2223,9 @@ export function wireSessionsPage(root) {
|
|
|
2161
2223
|
rerender();
|
|
2162
2224
|
});
|
|
2163
2225
|
});
|
|
2226
|
+
monitorRoomOpenBtn.addEventListener('click', () => {
|
|
2227
|
+
window.location.href = monitorRoomUrl();
|
|
2228
|
+
});
|
|
2164
2229
|
groupByBox.querySelectorAll('[data-groupby]').forEach(btn => {
|
|
2165
2230
|
btn.addEventListener('click', () => {
|
|
2166
2231
|
const raw = btn.dataset.groupby;
|
|
@@ -2403,6 +2468,15 @@ export function wireSessionsPage(root) {
|
|
|
2403
2468
|
selected.clear();
|
|
2404
2469
|
rerender();
|
|
2405
2470
|
});
|
|
2471
|
+
bulkMonitorRoomBtn.addEventListener('click', () => {
|
|
2472
|
+
const ids = [...selected].filter(id => !!store.sessions.get(id));
|
|
2473
|
+
const result = addMonitorRoomSessionIds(ids);
|
|
2474
|
+
const original = bulkMonitorRoomBtn.textContent;
|
|
2475
|
+
bulkMonitorRoomBtn.textContent = t('sessions.monitorRoomAdded', { added: result.added, total: result.total });
|
|
2476
|
+
window.setTimeout(() => {
|
|
2477
|
+
bulkMonitorRoomBtn.textContent = original;
|
|
2478
|
+
}, 1800);
|
|
2479
|
+
});
|
|
2406
2480
|
bulkCloseBtn.addEventListener('click', async () => {
|
|
2407
2481
|
const ids = [...selected];
|
|
2408
2482
|
if (ids.length === 0)
|
|
@@ -2568,6 +2642,13 @@ export function wireSessionsPage(root) {
|
|
|
2568
2642
|
});
|
|
2569
2643
|
});
|
|
2570
2644
|
filtersForm.addEventListener('input', rerender);
|
|
2645
|
+
filtersForm.addEventListener('change', event => {
|
|
2646
|
+
const target = event.target;
|
|
2647
|
+
if (target?.name === 'showUnknownChats') {
|
|
2648
|
+
writeStoredSessionsShowUnknownChats(window.localStorage, target.checked);
|
|
2649
|
+
rerender();
|
|
2650
|
+
}
|
|
2651
|
+
});
|
|
2571
2652
|
const unsubscribeStore = store.on(rerender);
|
|
2572
2653
|
// 团队看板 30s 软刷新(拉对方部署的会话快照与共享编排);页面切走后
|
|
2573
2654
|
// kanban 脱离 DOM,定时器自清。
|