botmux 3.12.1 → 3.13.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 (123) hide show
  1. package/dist/.runtime-build-id +1 -1
  2. package/dist/bot-registry.d.ts +7 -0
  3. package/dist/bot-registry.d.ts.map +1 -1
  4. package/dist/bot-registry.js +46 -13
  5. package/dist/bot-registry.js.map +1 -1
  6. package/dist/core/config-dir.d.ts +167 -0
  7. package/dist/core/config-dir.d.ts.map +1 -0
  8. package/dist/core/config-dir.js +152 -0
  9. package/dist/core/config-dir.js.map +1 -0
  10. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  11. package/dist/core/dashboard-ipc-server.js +48 -0
  12. package/dist/core/dashboard-ipc-server.js.map +1 -1
  13. package/dist/core/per-bot-env.d.ts.map +1 -1
  14. package/dist/core/per-bot-env.js +9 -0
  15. package/dist/core/per-bot-env.js.map +1 -1
  16. package/dist/core/session-discovery.d.ts.map +1 -1
  17. package/dist/core/session-discovery.js +19 -2
  18. package/dist/core/session-discovery.js.map +1 -1
  19. package/dist/core/session-manager.d.ts.map +1 -1
  20. package/dist/core/session-manager.js +44 -3
  21. package/dist/core/session-manager.js.map +1 -1
  22. package/dist/core/trigger-session.d.ts.map +1 -1
  23. package/dist/core/trigger-session.js +499 -63
  24. package/dist/core/trigger-session.js.map +1 -1
  25. package/dist/core/types.d.ts +26 -4
  26. package/dist/core/types.d.ts.map +1 -1
  27. package/dist/core/types.js.map +1 -1
  28. package/dist/core/worker-pool.d.ts +64 -0
  29. package/dist/core/worker-pool.d.ts.map +1 -1
  30. package/dist/core/worker-pool.js +301 -10
  31. package/dist/core/worker-pool.js.map +1 -1
  32. package/dist/daemon.d.ts.map +1 -1
  33. package/dist/daemon.js +13 -6
  34. package/dist/daemon.js.map +1 -1
  35. package/dist/dashboard/auth.d.ts +8 -0
  36. package/dist/dashboard/auth.d.ts.map +1 -1
  37. package/dist/dashboard/auth.js +16 -11
  38. package/dist/dashboard/auth.js.map +1 -1
  39. package/dist/dashboard/web/bot-multi-select.d.ts +33 -0
  40. package/dist/dashboard/web/bot-multi-select.d.ts.map +1 -0
  41. package/dist/dashboard/web/bot-multi-select.js +34 -0
  42. package/dist/dashboard/web/bot-multi-select.js.map +1 -0
  43. package/dist/dashboard/web/groups-page.d.ts +13 -0
  44. package/dist/dashboard/web/groups-page.d.ts.map +1 -1
  45. package/dist/dashboard/web/groups-page.js +25 -7
  46. package/dist/dashboard/web/groups-page.js.map +1 -1
  47. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  48. package/dist/dashboard/web/i18n.js +8 -4
  49. package/dist/dashboard/web/i18n.js.map +1 -1
  50. package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
  51. package/dist/dashboard/web/sessions-page.js +15 -23
  52. package/dist/dashboard/web/sessions-page.js.map +1 -1
  53. package/dist/dashboard/web/sessions.d.ts +13 -0
  54. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  55. package/dist/dashboard/web/sessions.js +25 -0
  56. package/dist/dashboard/web/sessions.js.map +1 -1
  57. package/dist/dashboard-web/app.js +1 -1
  58. package/dist/dashboard-web/chunks/{bot-defaults-page-HL655CNR.js → bot-defaults-page-NQJFJ45Z.js} +1 -1
  59. package/dist/dashboard-web/chunks/{chunk-BFUTTYVK.js → chunk-5QJB24I2.js} +1 -1
  60. package/dist/dashboard-web/chunks/{chunk-ELL53D62.js → chunk-6JTZJRQJ.js} +2 -2
  61. package/dist/dashboard-web/chunks/{chunk-5ZL7NLR5.js → chunk-CU4SUKK3.js} +1 -1
  62. package/dist/dashboard-web/chunks/{chunk-5PAYQ3KT.js → chunk-KEEYQ3WF.js} +1 -1
  63. package/dist/dashboard-web/chunks/chunk-WLIVBPJC.js +1 -0
  64. package/dist/dashboard-web/chunks/{connectors-page-3QQACF23.js → connectors-page-HADHZXXZ.js} +1 -1
  65. package/dist/dashboard-web/chunks/groups-page-5TYF46RS.js +8 -0
  66. package/dist/dashboard-web/chunks/{insights-page-ZZ3JEJ6L.js → insights-page-EVGGJI5L.js} +1 -1
  67. package/dist/dashboard-web/chunks/{monitor-room-ROJ5GZ4N.js → monitor-room-HRGR2ENP.js} +1 -1
  68. package/dist/dashboard-web/chunks/{monitoring-page-IATV7KJF.js → monitoring-page-LBU7TTTW.js} +1 -1
  69. package/dist/dashboard-web/chunks/{office-page-TYO5OIIT.js → office-page-DF6RRBMN.js} +1 -1
  70. package/dist/dashboard-web/chunks/{overview-page-VJUULZF2.js → overview-page-ZB6QH2EX.js} +1 -1
  71. package/dist/dashboard-web/chunks/{roles-page-7RJJKZGK.js → roles-page-ZBZGHIIF.js} +1 -1
  72. package/dist/dashboard-web/chunks/{schedules-page-JTEJ5IXW.js → schedules-page-NQVQC3QY.js} +1 -1
  73. package/dist/dashboard-web/chunks/sessions-page-DXBCDWCS.js +8 -0
  74. package/dist/dashboard-web/chunks/{settings-page-7CTTFBRS.js → settings-page-E7NN4NVQ.js} +1 -1
  75. package/dist/dashboard-web/chunks/{skills-page-57NZECJ3.js → skills-page-2QAVB2SA.js} +1 -1
  76. package/dist/dashboard-web/chunks/{team-federation-page-6YYIMJG3.js → team-federation-page-VGWL53AE.js} +1 -1
  77. package/dist/dashboard-web/chunks/{v3-page-ZGKBSBK3.js → v3-page-AY35LKCX.js} +1 -1
  78. package/dist/dashboard-web/chunks/{whiteboards-page-AACJF6DB.js → whiteboards-page-BNWUU4KG.js} +1 -1
  79. package/dist/dashboard-web/style.css +61 -53
  80. package/dist/features/codex-notifier/internal-turn.d.ts +1 -2
  81. package/dist/features/codex-notifier/internal-turn.d.ts.map +1 -1
  82. package/dist/features/codex-notifier/internal-turn.js +1 -13
  83. package/dist/features/codex-notifier/internal-turn.js.map +1 -1
  84. package/dist/i18n/en.js +2 -2
  85. package/dist/i18n/en.js.map +1 -1
  86. package/dist/i18n/zh.js +2 -2
  87. package/dist/i18n/zh.js.map +1 -1
  88. package/dist/platform/secure-host-file.d.ts +63 -0
  89. package/dist/platform/secure-host-file.d.ts.map +1 -1
  90. package/dist/platform/secure-host-file.js +90 -25
  91. package/dist/platform/secure-host-file.js.map +1 -1
  92. package/dist/services/async-trigger-store.d.ts +24 -4
  93. package/dist/services/async-trigger-store.d.ts.map +1 -1
  94. package/dist/services/async-trigger-store.js +81 -19
  95. package/dist/services/async-trigger-store.js.map +1 -1
  96. package/dist/services/codex-session-meta.d.ts +4 -0
  97. package/dist/services/codex-session-meta.d.ts.map +1 -0
  98. package/dist/services/codex-session-meta.js +15 -0
  99. package/dist/services/codex-session-meta.js.map +1 -0
  100. package/dist/services/idempotency-store.d.ts +18 -3
  101. package/dist/services/idempotency-store.d.ts.map +1 -1
  102. package/dist/services/idempotency-store.js +30 -12
  103. package/dist/services/idempotency-store.js.map +1 -1
  104. package/dist/services/traex-transcript.d.ts +7 -5
  105. package/dist/services/traex-transcript.d.ts.map +1 -1
  106. package/dist/services/traex-transcript.js +139 -33
  107. package/dist/services/traex-transcript.js.map +1 -1
  108. package/dist/services/trigger-types.d.ts +14 -1
  109. package/dist/services/trigger-types.d.ts.map +1 -1
  110. package/dist/services/trigger-types.js +35 -0
  111. package/dist/services/trigger-types.js.map +1 -1
  112. package/dist/types.d.ts +2 -0
  113. package/dist/types.d.ts.map +1 -1
  114. package/dist/utils/child-env.d.ts +1 -1
  115. package/dist/utils/child-env.d.ts.map +1 -1
  116. package/dist/utils/child-env.js +18 -0
  117. package/dist/utils/child-env.js.map +1 -1
  118. package/dist/worker.js +35 -2
  119. package/dist/worker.js.map +1 -1
  120. package/package.json +1 -1
  121. package/dist/dashboard-web/chunks/chunk-6ALR252E.js +0 -1
  122. package/dist/dashboard-web/chunks/groups-page-SDZMJ7UV.js +0 -8
  123. package/dist/dashboard-web/chunks/sessions-page-KD7HDT3U.js +0 -8
@@ -61,6 +61,14 @@ export declare function persistToken(tokenPath: string, token: string): void;
61
61
  * Load the active token, creating and persisting the first one when absent.
62
62
  * The file lock makes get-or-create linearizable across dashboard processes:
63
63
  * every concurrent caller returns the same durable token.
64
+ *
65
+ * The credential directory is pinned once (Linux: via an open directory
66
+ * descriptor) and the lock, the read, and the write all resolve through that
67
+ * same anchor. This keeps the whole critical section on one directory inode —
68
+ * so a symlinked HOME whose target sits under a shared-drive / 0777 ancestor
69
+ * still succeeds, while an ancestor rename mid-section cannot redirect the lock
70
+ * or the token write into a substituted directory. `~/.botmux` itself must
71
+ * still be 0700 and owned by the current user; a leaf symlink is still refused.
64
72
  */
65
73
  export declare function loadOrCreatePersistedToken(tokenPath: string): string;
66
74
  /** Generate and durably replace the token while serialized with first creation. */
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/dashboard/auth.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CAAE;AAExE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEvF;AAED;;gFAEgF;AAChF,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAM5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA4BlC;AAED,qEAAqE;AACrE,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrE;AAED,gFAAgF;AAChF,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA+CtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CASpE;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAO1E;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAsBxB,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB;;;;uDAImD;IACnD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,YAAY,CAkDf"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/dashboard/auth.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CAAE;AAExE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEvF;AAED;;gFAEgF;AAChF,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAM5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA4BlC;AAED,qEAAqE;AACrE,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrE;AAED,gFAAgF;AAChF,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA+CtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUpE;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ9D;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAO1E;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAsBxB,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB;;;;uDAImD;IACnD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,YAAY,CAkDf"}
@@ -2,8 +2,7 @@ import { randomBytes, createHmac, timingSafeEqual } from 'node:crypto';
2
2
  import { readFileSync, existsSync, mkdirSync, chmodSync, linkSync, unlinkSync, writeFileSync, } from 'node:fs';
3
3
  import { atomicWriteFileSync } from '../utils/atomic-write.js';
4
4
  import { dirname } from 'node:path';
5
- import { readSecureHostFileSync, secureHostFilePath, writeSecureHostFileSync, } from '../platform/secure-host-file.js';
6
- import { withFileLockSync } from '../utils/file-lock.js';
5
+ import { readSecureHostFileSync, withSecureHostParentSync, writeSecureHostFileSync, } from '../platform/secure-host-file.js';
7
6
  const NONCE_TTL_MS = 60_000;
8
7
  const TS_WINDOW_S = 30;
9
8
  const seenNonces = new Map(); // nonce → expiresAt
@@ -170,26 +169,32 @@ export function persistToken(tokenPath, token) {
170
169
  * Load the active token, creating and persisting the first one when absent.
171
170
  * The file lock makes get-or-create linearizable across dashboard processes:
172
171
  * every concurrent caller returns the same durable token.
172
+ *
173
+ * The credential directory is pinned once (Linux: via an open directory
174
+ * descriptor) and the lock, the read, and the write all resolve through that
175
+ * same anchor. This keeps the whole critical section on one directory inode —
176
+ * so a symlinked HOME whose target sits under a shared-drive / 0777 ancestor
177
+ * still succeeds, while an ancestor rename mid-section cannot redirect the lock
178
+ * or the token write into a substituted directory. `~/.botmux` itself must
179
+ * still be 0700 and owned by the current user; a leaf symlink is still refused.
173
180
  */
174
181
  export function loadOrCreatePersistedToken(tokenPath) {
175
- const securePath = secureHostFilePath(tokenPath);
176
- return withFileLockSync(securePath, () => {
177
- const existing = loadPersistedToken(securePath);
182
+ return withSecureHostParentSync(tokenPath, (parent) => parent.withLeafLock(() => {
183
+ const existing = parent.readLeaf(256)?.trim() || null;
178
184
  if (existing)
179
185
  return existing;
180
186
  const token = generateToken();
181
- persistToken(securePath, token);
187
+ parent.writeLeaf(token);
182
188
  return token;
183
- });
189
+ }));
184
190
  }
185
191
  /** Generate and durably replace the token while serialized with first creation. */
186
192
  export function rotatePersistedToken(tokenPath) {
187
- const securePath = secureHostFilePath(tokenPath);
188
- return withFileLockSync(securePath, () => {
193
+ return withSecureHostParentSync(tokenPath, (parent) => parent.withLeafLock(() => {
189
194
  const token = generateToken();
190
- persistToken(securePath, token);
195
+ parent.writeLeaf(token);
191
196
  return token;
192
- });
197
+ }));
193
198
  }
194
199
  /** Extract `botmux_dashboard_token` value from a Cookie header. */
195
200
  export function parseCookie(header) {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/dashboard/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/dashboard/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type React from 'react';
2
+ /** Minimal bot shape shared by the group picker (`GroupBot`) and the
3
+ * create-session picker (`PickerBot`): both carry `larkAppId` + a display name. */
4
+ export interface BotMultiSelectOption {
5
+ larkAppId: string;
6
+ botName?: string;
7
+ }
8
+ /**
9
+ * Searchable, scrollable multi-select for bots. Fully controlled: the caller
10
+ * owns the `selected` Set and toggles via `onToggle`, and MUST read the final
11
+ * selection from that Set — never from the DOM.
12
+ *
13
+ * Why the caller state is the only source of truth: the list renders only the
14
+ * rows matching the current search query; rows filtered out are unmounted, so
15
+ * their checkboxes leave the DOM entirely. A caller that harvested the checked
16
+ * ids via `FormData.getAll(...)` at submit time would silently drop any bot
17
+ * that was selected earlier but is not matching the search box at that moment.
18
+ * `selected` survives filtering; the DOM does not.
19
+ *
20
+ * The list area has a fixed max-height and scrolls internally, so a long roster
21
+ * (dozens of bots) never grows the surrounding dialog past the viewport — the
22
+ * dialog's own action buttons stay reachable.
23
+ */
24
+ export declare function BotMultiSelect(props: {
25
+ bots: BotMultiSelectOption[];
26
+ selected: Set<string>;
27
+ onToggle(larkAppId: string, checked: boolean): void;
28
+ searchPlaceholder: string;
29
+ noMatchLabel: string;
30
+ emptyLabel: string;
31
+ selectedCountLabel(n: number): string;
32
+ }): React.JSX.Element;
33
+ //# sourceMappingURL=bot-multi-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot-multi-select.d.ts","sourceRoot":"","sources":["../../../src/dashboard/web/bot-multi-select.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;oFACoF;AACpF,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,IAAI,EAAE,oBAAoB,EAAE,CAAC;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAkDpB"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from 'react';
3
+ /**
4
+ * Searchable, scrollable multi-select for bots. Fully controlled: the caller
5
+ * owns the `selected` Set and toggles via `onToggle`, and MUST read the final
6
+ * selection from that Set — never from the DOM.
7
+ *
8
+ * Why the caller state is the only source of truth: the list renders only the
9
+ * rows matching the current search query; rows filtered out are unmounted, so
10
+ * their checkboxes leave the DOM entirely. A caller that harvested the checked
11
+ * ids via `FormData.getAll(...)` at submit time would silently drop any bot
12
+ * that was selected earlier but is not matching the search box at that moment.
13
+ * `selected` survives filtering; the DOM does not.
14
+ *
15
+ * The list area has a fixed max-height and scrolls internally, so a long roster
16
+ * (dozens of bots) never grows the surrounding dialog past the viewport — the
17
+ * dialog's own action buttons stay reachable.
18
+ */
19
+ export function BotMultiSelect(props) {
20
+ const [query, setQuery] = useState('');
21
+ const queryNorm = query.trim().toLowerCase();
22
+ const visibleBots = useMemo(() => {
23
+ if (!queryNorm)
24
+ return props.bots;
25
+ return props.bots.filter(bot => (bot.botName ?? bot.larkAppId).toLowerCase().includes(queryNorm) ||
26
+ bot.larkAppId.toLowerCase().includes(queryNorm));
27
+ }, [props.bots, queryNorm]);
28
+ const selectedCount = props.selected.size;
29
+ if (!props.bots.length) {
30
+ return _jsx("p", { className: "bot-multi-select-empty", children: props.emptyLabel });
31
+ }
32
+ return (_jsxs("div", { className: "bot-multi-select", children: [_jsx("input", { className: "bot-multi-select-search", type: "search", placeholder: props.searchPlaceholder, "aria-label": props.searchPlaceholder, value: query, onChange: event => setQuery(event.currentTarget.value) }), visibleBots.length ? (_jsx("div", { className: "bot-multi-select-list", role: "group", children: visibleBots.map(bot => (_jsxs("label", { className: "bot-multi-select-row", children: [_jsx("input", { type: "checkbox", value: bot.larkAppId, checked: props.selected.has(bot.larkAppId), onChange: event => props.onToggle(bot.larkAppId, event.currentTarget.checked) }), _jsxs("span", { className: "bot-multi-select-main", children: [_jsx("strong", { children: bot.botName ?? bot.larkAppId }), _jsxs("small", { children: ["(", bot.larkAppId, ")"] })] })] }, bot.larkAppId))) })) : (_jsx("p", { className: "bot-multi-select-empty", children: props.noMatchLabel })), selectedCount ? (_jsx("small", { className: "bot-multi-select-count", children: props.selectedCountLabel(selectedCount) })) : null] }));
33
+ }
34
+ //# sourceMappingURL=bot-multi-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot-multi-select.js","sourceRoot":"","sources":["../../../src/dashboard/web/bot-multi-select.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAS1C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,KAQ9B;IACC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,IAAI,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC;QAClC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC7B,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YAChE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACrD,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5B,MAAM,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;IAE1C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,YAAG,SAAS,EAAC,wBAAwB,YAAE,KAAK,CAAC,UAAU,GAAK,CAAC;IACtE,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,kBAAkB,aAC/B,gBACE,SAAS,EAAC,yBAAyB,EACnC,IAAI,EAAC,QAAQ,EACb,WAAW,EAAE,KAAK,CAAC,iBAAiB,gBACxB,KAAK,CAAC,iBAAiB,EACnC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,GACtD,EACD,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CACpB,cAAK,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAC,OAAO,YAChD,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CACtB,iBAA2B,SAAS,EAAC,sBAAsB,aACzD,gBACE,IAAI,EAAC,UAAU,EACf,KAAK,EAAE,GAAG,CAAC,SAAS,EACpB,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAC1C,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,GAC7E,EACF,gBAAM,SAAS,EAAC,uBAAuB,aACrC,2BAAS,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,SAAS,GAAU,EAC/C,iCAAS,GAAG,CAAC,SAAS,SAAU,IAC3B,KAVG,GAAG,CAAC,SAAS,CAWjB,CACT,CAAC,GACE,CACP,CAAC,CAAC,CAAC,CACF,YAAG,SAAS,EAAC,wBAAwB,YAAE,KAAK,CAAC,YAAY,GAAK,CAC/D,EACA,aAAa,CAAC,CAAC,CAAC,CACf,gBAAO,SAAS,EAAC,wBAAwB,YAAE,KAAK,CAAC,kBAAkB,CAAC,aAAa,CAAC,GAAS,CAC5F,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
@@ -1,3 +1,16 @@
1
1
  import { type PageDisposer } from './react-mount.js';
2
+ import { useT } from './react-hooks.js';
3
+ import { type GroupBot, type GroupChat, type GroupsSnapshot } from './groups.js';
4
+ type Translator = ReturnType<typeof useT>;
5
+ export declare function AddBotsDialog(props: {
6
+ chat: GroupChat;
7
+ bots: GroupBot[];
8
+ tr: Translator;
9
+ onClose(): void;
10
+ onReloadGroups(options?: {
11
+ force?: boolean;
12
+ }): Promise<GroupsSnapshot>;
13
+ }): import("react").JSX.Element;
2
14
  export declare function renderGroupsPage(root: HTMLElement): PageDisposer;
15
+ export {};
3
16
  //# sourceMappingURL=groups-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"groups-page.d.ts","sourceRoot":"","sources":["../../../src/dashboard/web/groups-page.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAyhDrE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAEhE"}
1
+ {"version":3,"file":"groups-page.d.ts","sourceRoot":"","sources":["../../../src/dashboard/web/groups-page.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAqBxC,OAAO,EAiBL,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,KAAK,cAAc,EAGpB,MAAM,aAAa,CAAC;AAErB,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AA6kB1C,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,EAAE,EAAE,UAAU,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,cAAc,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACxE,+BAuFA;AA21BD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAEhE"}
@@ -5,6 +5,7 @@ import { useT } from './react-hooks.js';
5
5
  import { botOrbStyle, chatAvatarUrlFor } from './ui.js';
6
6
  import { copyText } from './clipboard.js';
7
7
  import { FeedGroupPicker } from './feed-group-picker.js';
8
+ import { BotMultiSelect } from './bot-multi-select.js';
8
9
  import { CreateActionButton, DropdownMenu, LoadingState, OverviewList, OverviewListItem, OverviewListMain, OverviewListTail, RefreshIconButton, } from './dashboard-components.js';
9
10
  import { hasExplicitChatRole, summarizeGroupProfileMatches, } from './role-profile-match.js';
10
11
  import { allExpectedInChat, availableBotsForPicker, collectGroupProfileEntries, emptyGroupsSnapshot, fetchGroupsSnapshot, fetchRoleProfileSummaries, filterGroupChats, injectOptimisticChat, isValidProfileId, loadGroupRoleProfileContext, paginateGroupRows, roleKey, roleProfileBootstrapStatus, summarizeAddBotsResult, suggestRoleProfileIdFromChat, } from './groups.js';
@@ -41,7 +42,9 @@ function DialogError(props) {
41
42
  return (_jsxs("p", { className: "hint-warn", children: [_jsx("strong", { children: props.title }), _jsx("br", {}), _jsx("small", { children: String(props.reason ?? 'unknown') })] }));
42
43
  }
43
44
  function BotCheckboxes(props) {
44
- return (_jsx(_Fragment, { children: availableBotsForPicker(props.bots, props.excludeIds).map(bot => (_jsxs("label", { className: "checkbox-row", children: [_jsx("input", { type: "checkbox", name: "bot", value: bot.larkAppId }), _jsxs("span", { className: "checkbox-row-main", children: [_jsx("strong", { children: bot.botName ?? bot.larkAppId }), _jsxs("small", { children: ["(", bot.larkAppId, ")"] })] })] }, bot.larkAppId))) }));
45
+ const options = availableBotsForPicker(props.bots, props.excludeIds);
46
+ const tr = props.tr;
47
+ return (_jsx(BotMultiSelect, { bots: options, selected: props.selected, onToggle: props.onToggle, searchPlaceholder: tr('botPicker.searchPlaceholder'), noMatchLabel: tr('botPicker.noMatch'), emptyLabel: tr('botPicker.empty'), selectedCountLabel: n => tr('botPicker.selectedCount', { n: String(n) }) }));
45
48
  }
46
49
  function AddBotsResult(props) {
47
50
  const summary = props.summary;
@@ -117,6 +120,7 @@ function CreateDialog(props) {
117
120
  const [error, setError] = useState(null);
118
121
  const [success, setSuccess] = useState(null);
119
122
  const [copied, setCopied] = useState(false);
123
+ const [selectedBots, setSelectedBots] = useState(new Set());
120
124
  const [roleProfileId, setRoleProfileId] = useState('');
121
125
  const [feedGroups, setFeedGroups] = useState([]);
122
126
  const [feedGroupAppId, setFeedGroupAppId] = useState('');
@@ -210,7 +214,7 @@ function CreateDialog(props) {
210
214
  const name = String(fd.get('name') ?? '').trim();
211
215
  const bindWorkingDir = String(fd.get('bindWorkingDir') ?? '').trim();
212
216
  const roleProfileId = String(fd.get('roleProfileId') ?? '').trim();
213
- const ids = fd.getAll('bot');
217
+ const ids = [...selectedBots];
214
218
  if (ids.length === 0) {
215
219
  setError({ title: '请选择 bot', reason: '至少选择一个 bot 后再创建群聊。' });
216
220
  return;
@@ -266,7 +270,14 @@ function CreateDialog(props) {
266
270
  });
267
271
  }, children: copied ? tr('sessions.copied') : tr('sessions.copy') })] }), _jsxs("p", { children: [_jsx("b", { children: "\u521B\u5EFA\u8005:" }), " ", _jsx("code", { children: String(success.creator ?? '?') })] }), success.feedGroupId ? _jsxs("p", { className: "hint-ok", children: ["\u5DF2\u52A0\u5165\u98DE\u4E66\u6807\u7B7E", success.feedGroupName ? `「${String(success.feedGroupName)}」` : '', "\u3002"] }) : null, success.feedGroupError ? _jsxs("p", { className: "hint-warn", children: ["\u7FA4\u804A\u5DF2\u521B\u5EFA\uFF0C\u4F46\u6807\u7B7E\u8BBE\u7F6E\u5931\u8D25\uFF1A", String(success.feedGroupError)] }) : null, _jsx(CreateInviteNote, { resp: success }), binds.length > 0 ? (bindFailed.length === 0 ? (_jsxs("p", { className: "hint-ok", children: ["\u5DF2\u7ED1\u5B9A\u76EE\u5F55\uFF1A", _jsx("code", { children: String(success.bindResolvedPath ?? '') }), "\uFF08", bindOk, "/", binds.length, " bots\uFF09"] })) : (_jsxs("p", { className: "hint-warn", children: ["\u76EE\u5F55\u7ED1\u5B9A\u90E8\u5206\u5931\u8D25\uFF1A\u6210\u529F ", bindOk, "/", binds.length, "\u3002", bindFailed.map((b, index) => (_jsxs("span", { children: [_jsx("br", {}), _jsx("code", { children: String(b?.larkAppId ?? '?') }), ": ", String(b?.error ?? 'unknown')] }, `${b?.larkAppId ?? '?'}-${index}`)))] }))) : null, profileStatus ? _jsx("p", { className: profileStatus.kind === 'ok' ? 'hint-ok' : 'hint-warn', children: profileStatus.text }) : null, invalidBots.length || invalidUsers.length ? (_jsxs("ul", { children: [invalidBots.length ? _jsxs("li", { children: ["\u65E0\u6548 bot id: ", _jsx("code", { children: invalidBots.join(', ') })] }) : null, invalidUsers.length ? _jsxs("li", { children: ["\u65E0\u6548\u7528\u6237 open_id: ", _jsx("code", { children: invalidUsers.join(', ') })] }) : null] })) : null, _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", id: "g-create-close", onClick: props.onClose, children: tr('sessions.dismiss') }), _jsx("a", { className: "btn-link primary", href: appLink, target: "_blank", rel: "noopener", children: tr('groups.openGroup') })] })] }));
268
272
  }
269
- return (_jsxs("article", { className: "g-create-dialog", children: [_jsxs("header", { className: "g-create-head", children: [_jsx("h3", { children: tr('groups.createTitle') }), _jsx("p", { children: tr('groups.createHelp') })] }), _jsxs("form", { id: "g-createform", className: "g-create-form", onSubmit: ev => void submit(ev), children: [_jsxs("fieldset", { className: "g-modal-field g-create-bots", children: [_jsx("legend", { children: tr('groups.botPicker') }), _jsx("div", { className: "g-bot-picker", children: _jsx(BotCheckboxes, { bots: props.bots }) })] }), _jsxs("div", { className: "g-create-fields", children: [_jsxs("fieldset", { className: "g-modal-field", children: [_jsx("legend", { children: tr('groups.name') }), _jsx("input", { type: "text", name: "name", placeholder: tr('groups.namePlaceholder'), maxLength: 60 })] }), _jsxs("fieldset", { className: "g-modal-field", children: [_jsx("legend", { children: tr('groups.bindDir') }), _jsx("input", { type: "text", name: "bindWorkingDir", placeholder: "e.g. ~/projects/botmux" }), _jsx("small", { children: tr('groups.bindDirHelp') })] }), _jsxs("fieldset", { className: "g-modal-field g-profile-field", children: [_jsx("legend", { children: tr('groups.roleProfile') }), _jsx("input", { type: "hidden", name: "roleProfileId", value: roleProfileId }), _jsx(DropdownMenu, { className: "g-profile-menu", ariaLabel: tr('groups.roleProfile'), label: roleProfileId || tr('groups.roleProfileNone'), value: roleProfileId, options: [
273
+ return (_jsxs("article", { className: "g-create-dialog", children: [_jsxs("header", { className: "g-create-head", children: [_jsx("h3", { children: tr('groups.createTitle') }), _jsx("p", { children: tr('groups.createHelp') })] }), _jsxs("form", { id: "g-createform", className: "g-create-form", onSubmit: ev => void submit(ev), children: [_jsxs("fieldset", { className: "g-modal-field g-create-bots", children: [_jsx("legend", { children: tr('groups.botPicker') }), _jsx("div", { className: "g-bot-picker", children: _jsx(BotCheckboxes, { bots: props.bots, tr: tr, selected: selectedBots, onToggle: (id, checked) => setSelectedBots(prev => {
274
+ const next = new Set(prev);
275
+ if (checked)
276
+ next.add(id);
277
+ else
278
+ next.delete(id);
279
+ return next;
280
+ }) }) })] }), _jsxs("div", { className: "g-create-fields", children: [_jsxs("fieldset", { className: "g-modal-field", children: [_jsx("legend", { children: tr('groups.name') }), _jsx("input", { type: "text", name: "name", placeholder: tr('groups.namePlaceholder'), maxLength: 60 })] }), _jsxs("fieldset", { className: "g-modal-field", children: [_jsx("legend", { children: tr('groups.bindDir') }), _jsx("input", { type: "text", name: "bindWorkingDir", placeholder: "e.g. ~/projects/botmux" }), _jsx("small", { children: tr('groups.bindDirHelp') })] }), _jsxs("fieldset", { className: "g-modal-field g-profile-field", children: [_jsx("legend", { children: tr('groups.roleProfile') }), _jsx("input", { type: "hidden", name: "roleProfileId", value: roleProfileId }), _jsx(DropdownMenu, { className: "g-profile-menu", ariaLabel: tr('groups.roleProfile'), label: roleProfileId || tr('groups.roleProfileNone'), value: roleProfileId, options: [
270
281
  { value: '', label: tr('groups.roleProfileNone') },
271
282
  ...props.roleProfiles.map(profile => ({ value: profile.profileId, label: profile.profileId })),
272
283
  ], onChange: setRoleProfileId }), _jsx("small", { children: tr('groups.roleProfileHelp') })] }), _jsxs("fieldset", { className: "g-modal-field g-feed-group-field", children: [_jsx("legend", { children: "\u98DE\u4E66\u6807\u7B7E\uFF08\u53EF\u9009\uFF09" }), _jsx("input", { type: "hidden", name: "feedGroupId", value: feedGroupId }), _jsx(FeedGroupPicker, { groups: feedGroups, selectedId: feedGroupId, newName: newFeedGroupName, disabled: feedGroupsLoading || !!feedGroupsError, onChange: (selectedId, newName) => { setFeedGroupId(selectedId); setNewFeedGroupName(newName); } }), _jsx("small", { children: "\u5C55\u5F00\u540E\u53EF\u5728\u7B2C\u4E00\u884C\u8F93\u5165\u65B0\u6807\u7B7E\u540D\u79F0\uFF0C\u6216\u9009\u62E9\u4E0B\u65B9\u5DF2\u6709\u6807\u7B7E\u3002" }), feedGroupsLoading ? _jsx("small", { children: "\u6B63\u5728\u8BFB\u53D6\u98DE\u4E66\u6807\u7B7E\u2026" }) : null, feedGroupsError ? (_jsxs("div", { className: "hint-warn-inline", children: [_jsx("small", { children: feedGroupsError }), ' ', _jsx("button", { type: "button", disabled: feedGroupAuthSubmitting, onClick: () => void openFeedGroupLogin(), children: feedGroupAuthSubmitting ? '正在完成授权…' : '立即授权' }), _jsx("small", { children: " \u6388\u6743\u540E\u4F1A\u5F39\u7A97\u63D0\u793A\u4F60\u7C98\u8D34\u56DE\u8C03\u5730\u5740\u3002" })] })) : null, !feedGroupsLoading && !feedGroupsError && feedGroups.length === 0 ? _jsx("small", { children: "\u5F53\u524D\u6CA1\u6709\u6807\u7B7E\uFF0C\u53EF\u76F4\u63A5\u521B\u5EFA\u4E00\u4E2A\u3002" }) : null] })] }), feedGroupAuthUrl ? (_jsx("div", { className: "feed-group-auth-overlay", children: _jsxs("section", { className: "feed-group-auth-card", role: "dialog", "aria-modal": "true", "aria-labelledby": "feed-group-auth-title", children: [_jsx("h3", { id: "feed-group-auth-title", children: "\u6388\u6743\u98DE\u4E66\u6807\u7B7E" }), _jsxs("p", { children: ["\u70B9\u51FB\u4E0B\u9762\u7684\u6309\u94AE\uFF0C\u5728\u98DE\u4E66\u9875\u9762\u786E\u8BA4\u6388\u6743\u3002\u5982\u679C BotMux \u4E0E\u6D4F\u89C8\u5668\u5728\u540C\u4E00\u53F0\u7535\u8111\uFF0C\u786E\u8BA4\u540E\u4F1A\u81EA\u52A8\u5B8C\u6210\u6388\u6743\u3002\u5982\u679C BotMux \u8FD0\u884C\u5728\u8FDC\u7A0B\u865A\u62DF\u673A\u4E0A\uFF0C\u6D4F\u89C8\u5668\u4F1A\u56E0\u65E0\u6CD5\u8BBF\u95EE\u672C\u673A\u5730\u5740 ", _jsx("code", { children: "127.0.0.1:9768" }), " \u800C\u663E\u793A\u201C\u65E0\u6CD5\u8BBF\u95EE\u201D\uFF1B\u6B64\u65F6\u8BF7\u590D\u5236\u5730\u5740\u680F\u4E2D\u7684\u5B8C\u6574\u94FE\u63A5\u5E76\u7C98\u8D34\u5230\u4E0B\u65B9\u3002"] }), _jsx("button", { type: "button", className: "primary feed-group-auth-open", onClick: () => window.open(feedGroupAuthUrl, '_blank', 'noopener'), children: "\u8DF3\u8F6C\u98DE\u4E66\u6388\u6743" }), _jsxs("label", { children: [_jsx("span", { children: "\u8BF7\u628A\u70B9\u51FB\u6388\u6743\u540E\u7684\u5B8C\u6574\u94FE\u63A5\u7C98\u8D34\u5728\u8FD9\u91CC" }), _jsx("input", { type: "url", value: feedGroupCallbackUrl, placeholder: "http://127.0.0.1:9768/callback?code=\u2026&state=\u2026", onChange: event => setFeedGroupCallbackUrl(event.currentTarget.value) })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", onClick: () => { setFeedGroupAuthUrl(''); setFeedGroupCallbackUrl(''); }, children: "\u53D6\u6D88" }), _jsx("button", { type: "button", className: "primary", disabled: !feedGroupCallbackUrl.trim() || feedGroupAuthSubmitting, onClick: () => void completeFeedGroupLogin(feedGroupCallbackUrl), children: feedGroupAuthSubmitting ? '正在完成授权…' : '完成授权' })] })] }) })) : null, _jsx("div", { className: "g-create-status", "data-create-status": true, "aria-live": "polite", children: error ? _jsx(DialogError, { ...error }) : null }), _jsxs("div", { className: "actions g-create-actions", children: [_jsx("button", { type: "button", id: "g-create-cancel", onClick: props.onClose, children: tr('groups.cancel') }), _jsx("button", { type: "submit", className: "primary", disabled: submitting, children: submitting ? _jsxs(_Fragment, { children: [_jsx("i", { className: "button-spinner", "aria-hidden": "true" }), tr('groups.createSubmitting')] }) : tr('groups.createSubmit') })] })] })] }));
@@ -287,16 +298,16 @@ function CreateInviteNote(props) {
287
298
  }
288
299
  return (_jsxs("p", { className: "hint-warn", children: ["\u6CA1\u5728 dashboard \u7F13\u5B58\u91CC\u627E\u5230 ownerOpenId\uFF0C", _jsx("strong", { children: "\u6CA1\u6709\u81EA\u52A8\u9080\u8BF7\u4F60" }), "\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"] }));
289
300
  }
290
- function AddBotsDialog(props) {
301
+ export function AddBotsDialog(props) {
291
302
  const { chat, tr } = props;
292
303
  const [submitting, setSubmitting] = useState(false);
293
304
  const [error, setError] = useState(null);
294
305
  const [summary, setSummary] = useState(null);
306
+ const [selectedBots, setSelectedBots] = useState(new Set());
295
307
  const inChatSet = useMemo(() => new Set((chat.memberBots ?? []).filter(member => member.inChat).map(member => member.larkAppId)), [chat]);
296
308
  async function submit(ev) {
297
309
  ev.preventDefault();
298
- const fd = new FormData(ev.currentTarget);
299
- const ids = fd.getAll('bot');
310
+ const ids = [...selectedBots];
300
311
  if (ids.length === 0) {
301
312
  setError({ title: '请选择 bot', reason: '至少选择一个 bot 后再添加。' });
302
313
  setSummary(null);
@@ -339,7 +350,14 @@ function AddBotsDialog(props) {
339
350
  setSubmitting(false);
340
351
  }
341
352
  }
342
- return (_jsxs("article", { className: "g-add-bots-dialog", children: [_jsx("header", { children: _jsxs("h3", { children: [tr('groups.addBots'), " \u00B7 ", chat.name ?? chat.chatId] }) }), _jsx("p", { children: tr('groups.createHelp') }), _jsxs("form", { id: "g-addform", onSubmit: ev => void submit(ev), children: [_jsx(BotCheckboxes, { bots: props.bots, excludeIds: inChatSet }), _jsxs("div", { "data-add-status": true, "aria-live": "polite", children: [error ? _jsx(DialogError, { ...error }) : null, summary ? (_jsxs(_Fragment, { children: [_jsx(AddBotsResult, { summary: summary.result }), summary.refreshError ? _jsx(DialogError, { title: "\u5237\u65B0\u5931\u8D25", reason: summary.refreshError }) : null] })) : null] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", id: "g-cancel", onClick: props.onClose, children: tr('groups.cancel') }), _jsx("button", { type: "submit", className: "primary", disabled: submitting, children: submitting ? 'Adding...' : tr('groups.addBots') })] })] })] }));
353
+ return (_jsxs("article", { className: "g-add-bots-dialog", children: [_jsx("header", { children: _jsxs("h3", { children: [tr('groups.addBots'), " \u00B7 ", chat.name ?? chat.chatId] }) }), _jsx("p", { children: tr('groups.createHelp') }), _jsxs("form", { id: "g-addform", onSubmit: ev => void submit(ev), children: [_jsx(BotCheckboxes, { bots: props.bots, excludeIds: inChatSet, tr: tr, selected: selectedBots, onToggle: (id, checked) => setSelectedBots(prev => {
354
+ const next = new Set(prev);
355
+ if (checked)
356
+ next.add(id);
357
+ else
358
+ next.delete(id);
359
+ return next;
360
+ }) }), _jsxs("div", { "data-add-status": true, "aria-live": "polite", children: [error ? _jsx(DialogError, { ...error }) : null, summary ? (_jsxs(_Fragment, { children: [_jsx(AddBotsResult, { summary: summary.result }), summary.refreshError ? _jsx(DialogError, { title: "\u5237\u65B0\u5931\u8D25", reason: summary.refreshError }) : null] })) : null] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", id: "g-cancel", onClick: props.onClose, children: tr('groups.cancel') }), _jsx("button", { type: "submit", className: "primary", disabled: submitting, children: submitting ? 'Adding...' : tr('groups.addBots') })] })] })] }));
343
361
  }
344
362
  function SaveProfileDialog(props) {
345
363
  const { tr } = props;