dsh-bots 0.2.17 → 0.2.19

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 (2) hide show
  1. package/lib/client.js +54 -7
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -284,6 +284,13 @@
284
284
  .dbs-navBody{display:flex;flex-direction:column;min-height:0;flex:1}
285
285
  .dbs-botsBody{overflow-y:auto;scrollbar-gutter:stable;padding-right:var(--dsh-sidebar-inline-padding,8px)}
286
286
  .dbs-navBodyErr{padding:6px 12px;font-size:12px;line-height:20px;color:var(--dsw-alias-label-tertiary)}
287
+ .dbs-secHead{position:relative;cursor:pointer;border-radius:8px}
288
+ .dbs-secHead:hover{background:var(--dsw-alias-interactive-bg-hover)}
289
+ .dbs-secHead .dbs-rowActions{display:none}
290
+ .dbs-secHead:hover .dbs-rowActions,.dbs-secHead:focus-within .dbs-rowActions{display:inline-flex}
291
+ .dbs-secMenu{position:absolute;top:100%;right:0;z-index:40;min-width:148px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:4px;box-shadow:0 12px 40px rgba(0,0,0,.22);animation:dbs-modal-in .14s ease-out}
292
+ .dbs-secMenuItem{display:flex;align-items:center;gap:8px;width:100%;padding:6px 10px;border-radius:8px;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);cursor:pointer;background:none;border:none;text-align:left}
293
+ .dbs-secMenuItem:hover{background:var(--dsw-alias-interactive-bg-hover)}
287
294
  .dbs-prow,.dbs-srow{cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;gap:6px;padding:0 8px;display:flex;box-sizing:border-box}
288
295
  /* Native mirror (dsh-client-ui-sidebar/workspace): header-class rows outdent
289
296
  their label 4px (pl:4 → x=16 from the window edge) while list rows keep
@@ -489,6 +496,8 @@
489
496
  'list.loading': '加载中…',
490
497
  'list.empty': '还没有 Bot,点 + 新建。',
491
498
  'section.groups': '群聊',
499
+ 'list.more': '更多操作',
500
+ 'list.refresh': '刷新列表',
492
501
  'section.singles': '单聊',
493
502
  'chat.group': '群聊 · {n} 名成员',
494
503
  'chat.single': '单聊',
@@ -602,6 +611,8 @@
602
611
  'list.loading': 'Loading…',
603
612
  'list.empty': 'No bots yet — use + to create one.',
604
613
  'section.groups': 'Groups',
614
+ 'list.more': 'More actions',
615
+ 'list.refresh': 'Refresh list',
605
616
  'section.singles': 'Direct',
606
617
  'chat.group': 'Group · {n} members',
607
618
  'chat.single': 'Direct',
@@ -791,6 +802,8 @@
791
802
  /** Manage-members dialog: group agentId | null (system modal). */
792
803
  manageMembers: null,
793
804
  settingsAgentId: null,
805
+ sectionMenu: null,
806
+ sectionsOpen: null,
794
807
  /** Bumped on a language switch so module-scope `t` output re-renders. */
795
808
  localeRev: 0,
796
809
  };
@@ -1129,19 +1142,47 @@
1129
1142
  * are: creating the first bot or group never requires a trip to the
1130
1143
  * footer. `addAction` opens the same system-style modal as before.
1131
1144
  */
1132
- function sectionRows(label, list, addAction) {
1145
+ function sectionRows(label, list, addAction, menuKind, menuItems) {
1146
+ const menuOpen = s.sectionMenu === menuKind;
1147
+ // Group-header collapse contract, mirrored from 「工作区|Bots」:
1148
+ // chevron + whole-row click toggle, body suppressed when closed.
1149
+ const isOpen = s.sectionsOpen?.[menuKind] !== false;
1150
+ const toggle = () => {
1151
+ patch({ sectionMenu: null, sectionsOpen: { ...(s.sectionsOpen ?? {}), [menuKind]: !isOpen } });
1152
+ };
1133
1153
  return e('div', { key: label }, e('div', {
1134
- className: 'dbs-navBodyErr',
1154
+ className: 'dbs-navBodyErr dbs-secHead', role: 'button', tabIndex: 0, 'aria-expanded': isOpen,
1135
1155
  // Native sectionHeader outdent: label at x=16 (12 sidebar
1136
1156
  // padding + 4), aligned with the group headers. The previous
1137
1157
  // 12px here pushed section labels 8px right of the native
1138
1158
  // baseline, making both sections read horizontally off.
1139
- style: { padding: '4px 8px 2px 4px', display: 'flex', alignItems: 'center' },
1140
- }, e('span', { style: { flex: 1 } }, label), e(Button, {
1159
+ style: { padding: '4px 8px 2px 4px', display: 'flex', alignItems: 'center', gap: 2 },
1160
+ onClick: toggle,
1161
+ onKeyDown: (ev) => { if (ev.key === 'Enter' || ev.key === ' ') {
1162
+ ev.preventDefault();
1163
+ toggle();
1164
+ } },
1165
+ }, e(Chevron, { open: isOpen }), e('span', { style: { flex: 1 } }, label),
1166
+ // Native workspace pattern: header actions appear on hover
1167
+ // (.dbs-rowActions is hover-gated in .dbs-secHead CSS); their
1168
+ // clicks must not fold the section with them.
1169
+ e('div', {
1170
+ className: 'dbs-rowActions', style: { alignItems: 'center', gap: 2 },
1171
+ onClick: (ev) => { ev.stopPropagation(); },
1172
+ }, e(Button, {
1141
1173
  variant: 'ghost', size: 'sm', title: addAction.title, 'aria-label': addAction.title,
1142
1174
  icon: Ico('IconPlusOutline16', { size: 14 }),
1143
1175
  onClick: addAction.onClick,
1144
- })), list.map(row));
1176
+ }), e(Button, {
1177
+ variant: 'ghost', size: 'sm', title: t('list.more'), 'aria-label': t('list.more'),
1178
+ icon: Ico('IconEllipsisOutline16', { size: 14 }),
1179
+ onClick: () => patch({ sectionMenu: menuOpen ? null : menuKind }),
1180
+ })), menuOpen
1181
+ ? e(React.Fragment, null, e('div', { style: { position: 'fixed', inset: 0, zIndex: 39 }, onClick: () => patch({ sectionMenu: null }) }), e('div', { className: 'dbs-secMenu', onClick: (ev) => { ev.stopPropagation(); } }, menuItems.map((item) => e('button', {
1182
+ key: item.label, className: 'dbs-secMenuItem', type: 'button',
1183
+ onClick: () => { patch({ sectionMenu: null }); item.onClick(); },
1184
+ }, item.label))))
1185
+ : null), isOpen ? list.map(row) : null);
1145
1186
  }
1146
1187
  // No footer: the gateway status moved to the Bots group-header dot's
1147
1188
  // hover tooltip (0.2.8) — see SidebarNav's StateDot `title`.
@@ -1155,12 +1196,18 @@
1155
1196
  ? sectionRows(t('section.groups'), groups, {
1156
1197
  title: t('group.new'),
1157
1198
  onClick: () => patch({ create: 'group', createName: '', createMembers: {}, createWorking: false, error: null }),
1158
- })
1199
+ }, 'groups', [
1200
+ { label: t('group.new'), onClick: () => patch({ create: 'group', createName: '', createMembers: {}, createWorking: false, error: null }) },
1201
+ { label: t('list.refresh'), onClick: () => { void refreshAgents(); } },
1202
+ ])
1159
1203
  : null, s.agentsLoaded
1160
1204
  ? sectionRows(t('section.singles'), singles, {
1161
1205
  title: t('bot.new'),
1162
1206
  onClick: () => patch({ create: 'bot', createName: '', createDesc: '', createWorking: false, error: null }),
1163
- })
1207
+ }, 'singles', [
1208
+ { label: t('bot.new'), onClick: () => patch({ create: 'bot', createName: '', createDesc: '', createWorking: false, error: null }) },
1209
+ { label: t('list.refresh'), onClick: () => { void refreshAgents(); } },
1210
+ ])
1164
1211
  : null);
1165
1212
  }
1166
1213
  // =========================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-bots",
3
- "version": "0.2.17",
3
+ "version": "0.2.19",
4
4
  "description": "Multi-bot workbench for DeepSeek Harness: bridges the sdk-bots orchestration gateway (group chats, single bots) into the dsh web shell with official-styled UI.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",